ページ 1 / 1
明日までの宿題です・・・
Posted: 2012年4月26日(木) 00:09
by れお
いそいでいます C言語でつまずいています
入力ファイルにあるN 個の整数のデータを配列に入力し、その配列内のデータを
小さい順に並べ替え、結果を出力ファイルに書き込む。(N ≦ 10で小さいものから順に並べる)
このプログラムをかいてみたのですが、エラーはおこりませんがうまくいきません。最後に変な数字がでてきたり、整数の個数が10個のとき10個以上のときなどがうまくいきません。。。
詳しく説明できるかた、どうか訂正お願いします。
コード:
#include <stdio.h>
#define MAX 10
int sort(int n[],int m){
int N=0,i=0,j=0;
for(i=0; i<m; i++){
for(j=i+1; j<m; j++){
if(n[i] > n[j]){
N = n[i];
n[i] = n[j];
n[j] = N;
}
}
}
return(n[m]);
}
int main(int argc, char *argv[])
{
FILE *fpi, *fpo;
int m=0, i=0;
int n[MAX];
if(argc != 3){
fprintf(stderr, "Illegal number of argument.\n");
return(-1);
}
if((fpi=fopen(argv[1],"r"))==NULL) {
fprintf(stderr, "Can't open input file <%s>.\n", argv[1]);
return(-1);
}
else {
while(! feof(fpi)){
fscanf(fpi,"%d",&n[m]);
m++;
}
if(m>=MAX){ //10こ以上の入力の判断
printf("NUMBER IS OVER");
return(-1);
}
fclose(fpi);
}
if((fpo=fopen(argv[2],"w"))==NULL) {
fprintf(stderr, "Can't open output file <%s>.\n", argv[2]);
return(-1);
}
else{
sort(n,m-1);//並べ替える関数にnの配列とm-1をわたす
//EOFまで数えてるから数字は1つ前まで
for(i=0;i<m;i++){
fprintf(fpo,"%d ",n[i]);
}
fclose(fpo);
}
return 0;
}
Re: 明日までの宿題です・・・
Posted: 2012年4月26日(木) 00:26
by box
インデント(字下げ)の適切な付け方について教えてもらってないんでしょうか。
コードが見づらくてしょうがないです。
今みたいに自己流だと、将来困ることになりそうな気がします。
今のうちに直しておく方がいいと思います。
Re: 明日までの宿題です・・・
Posted: 2012年4月26日(木) 00:36
by れお
すみません。これでどうでしょうか?まだ初心者なので・・・
コード:
#include <stdio.h>
#define MAX 10
int sort(int n[],int m){
int N=0,i=0,j=0;
for(i=0; i<m; i++){
for(j=i+1; j<m; j++){
if(n[i] > n[j]){
N = n[i];
n[i] = n[j];
n[j] = N;
}
}
}
return(n[m]);
}
int main(int argc, char *argv[])
{
FILE *fpi, *fpo;
int m=0, i=0;
int n[MAX];
if(argc != 3){
fprintf(stderr, "Illegal number of argument.\n");
return(-1);
}
if((fpi=fopen(argv[1],"r"))==NULL) {
fprintf(stderr, "Can't open input file <%s>.\n", argv[1]);
return(-1);
}
else {
while(! feof(fpi)){
fscanf(fpi,"%d",&n[m]);
m++;
}
if(m>=MAX){ //10こ以上の入力の判断
printf("NUMBER IS OVER");
return(-1);
}
fclose(fpi);
}
if((fpo=fopen(argv[2],"w"))==NULL) {
fprintf(stderr, "Can't open output file <%s>.\n", argv[2]);
return(-1);
}
else{
sort(n,m-1);//並べ替える関数にnの配列とm-1をわたす
//EOFまで数えてるから数字は1つ前まで
for(i=0;i<m;i++){
fprintf(fpo,"%d ",n[i]);
}
fclose(fpo);
}
return 0;
}
Re: 明日までの宿題です・・・
Posted: 2012年4月26日(木) 01:21
by sq
ファイルの読み取りですが、10個より多い場合でもループが止まりません。
そのため、m >= 10 のときでも、fscanf(fpi, "%d", &n[m]);が実行されてしまいます。
読み込んだ数mが一つ多くなる現象は、データファイルの末尾に改行があるからだと思います。
その場合、!feof();に引っかからずに一つ多く読みに行ってしまうからです。
改行がない場合はmは正確な数になるのでsort(n, m-1);は正確にソートされません。
入力データの書式に依存せずに、正確に読み込んだ数を数えるようにすればsort(n, m);でいいはずです。
Re: 明日までの宿題です・・・
Posted: 2012年4月26日(木) 01:35
by kurain
入力ファイルは何処(いずこ)…
ざっくり見てみました。
コード:
while(! feof(fpi))
{
fscanf(fpi,"%d",&n[m]);
m++;
}
ここで10個読みこんだとします。
ならmは10ですね。
mは10なのですから送られるmは9となりますね。
コード:
for(i=0; i<m; i++)
{
for(j=i+1; j<m; j++)
{
中身省略
}
}
i(j) < m
これはいいかえると0から8の間の添え字の配列を入れ替えますよって事になりますね。
が、添え字が9の場合のパターンがありません。
n[9]が放置されてしまいます。
もう一つのケース。
コード:
while(! feof(fpi))
{
fscanf(fpi,"%d",&n[m]);
m++;
}
ここで10個読みこんだとします。
EOF(?)も読みこんでいると言うのならmは11ですね。
…はいいのですが…
コード:
for(i=0;i<m;i++)
{
fprintf(fpo,"%d ",n[i]);
}
ここでまずいことに。
n[10]を見に行ってしまいます。(n[10]は存在しない)
…が、エラーは出ないとおっしゃっているので前者かな?
>最後に変な数字がでてきたり、整数の個数が10個のとき10個以上のときなどがうまくいきません。
読みこむファイルの中身かファイルそのもの、出力結果などを提示するともっとスムーズに話が進みます。
インデントが奇妙です。
「{」がきたら4字下げる
「}」がきたら4字上げる
と言った具合に統一しましょう。
Re: 明日までの宿題です・・・
Posted: 2012年4月26日(木) 01:39
by reo
kurain さんが書きました:入力ファイルは何処(いずこ)…
ざっくり見てみました。
コード:
while(! feof(fpi))
{
fscanf(fpi,"%d",&n[m]);
m++;
}
ここで10個読みこんだとします。
ならmは10ですね。
mは10なのですから送られるmは9となりますね。
コード:
for(i=0; i<m; i++)
{
for(j=i+1; j<m; j++)
{
中身省略
}
}
i(j) < m
これはいいかえると0から8の間の添え字の配列を入れ替えますよって事になりますね。
が、添え字が9の場合のパターンがありません。
n[9]が放置されてしまいます。
もう一つのケース。
コード:
while(! feof(fpi))
{
fscanf(fpi,"%d",&n[m]);
m++;
}
ここで10個読みこんだとします。
EOF(?)も読みこんでいると言うのならmは11ですね。
…はいいのですが…
コード:
for(i=0;i<m;i++)
{
fprintf(fpo,"%d ",n[i]);
}
ここでまずいことに。
n[10]を見に行ってしまいます。(n[10]は存在しない)
…が、エラーは出ないとおっしゃっているので前者かな?
>最後に変な数字がでてきたり、整数の個数が10個のとき10個以上のときなどがうまくいきません。
読みこむファイルの中身かファイルそのもの、出力結果などを提示するともっとスムーズに話が進みます。
インデントが奇妙です。
「{」がきたら4字下げる
「}」がきたら4字上げる
と言った具合に統一しましょう。
Re: 明日までの宿題です・・・
Posted: 2012年4月26日(木) 01:51
by れお
sort(n, m)
にすれば変な数字がでてくることはなくなりました。
しかしファイルに10個入力されているときでもNUMBER IS OVERが表示されてしまいます・・・
Re: 明日までの宿題です・・・
Posted: 2012年4月26日(木) 01:55
by nullptr
N≦10なら
if(m>=MAX){ //10こ以上の入力の判断
じゃなくて
if(m>MAX){ //10こ以上の入力の判断
なんじゃ‥‥いやさらっと見ただけなんで見当違いなら申し訳ないです
*完全にミスりました忘れてくださいorz
Re: 明日までの宿題です・・・
Posted: 2012年4月26日(木) 01:58
by れお
新月獅子 さんが書きました:N≦10なら
if(m>=MAX){ //10こ以上の入力の判断
じゃなくて
if(m>MAX){ //10こ以上の入力の判断
なんじゃ‥‥いやさらっと見ただけなんで見当違いなら申し訳ないです
*完全にミスりました忘れてくださいorz
いや、それで解決しました。。ww多分
そこ直しただけではだめですか??;
Re: 明日までの宿題です・・・
Posted: 2012年4月26日(木) 02:00
by kurain
コード:
while(! feof(fpi))
{
fscanf(fpi,"%d",&n[m]);
m++;
}
ここで10個読みこんだとします。
ならmは10ですね。
コード:
if(m>=MAX){ //10こ以上の入力の判断
printf("NUMBER IS OVER");
return(-1);
}
さて、この条件式はどうなるでしょうか。
(10>=10)真になってしまいますね。
どうすれば成立しなくなるでしょうか。
…余談ですが、10個を超すデータ(極端な例で1万個)の時n[10000]とかになりますが大丈夫なのでしょうか…
データ過剰に対するエラー処理はいっそのことwhile文の読みこみ処理の中に組み込んだ方がいい気がします。
Re: 明日までの宿題です・・・
Posted: 2012年4月26日(木) 02:02
by nullptr
れお さんが書きました:新月獅子 さんが書きました:N≦10なら
if(m>=MAX){ //10こ以上の入力の判断
じゃなくて
if(m>MAX){ //10こ以上の入力の判断
なんじゃ‥‥いやさらっと見ただけなんで見当違いなら申し訳ないです
*完全にミスりました忘れてくださいorz
いや、それで解決しました。。ww多分
そこ直しただけではだめですか??;
あら?解決したんですか?;流れがわからないのでアレですが、宿題ならとりあえず動くならそれで出しちゃえばいいと思いますが‥‥さらっと見てて「ん‥?」と思うとことかあるので綺麗なコードが書けるまで修正することはオススメします
Re: 明日までの宿題です・・・
Posted: 2012年4月26日(木) 02:09
by れお
kurain さんが書きました:コード:
while(! feof(fpi))
{
fscanf(fpi,"%d",&n[m]);
m++;
}
ここで10個読みこんだとします。
ならmは10ですね。
コード:
if(m>=MAX){ //10こ以上の入力の判断
printf("NUMBER IS OVER");
return(-1);
}
さて、この条件式はどうなるでしょうか。
(10>=10)真になってしまいますね。
どうすれば成立しなくなるでしょうか。
…余談ですが、10個を超すデータ(極端な例で1万個)の時n[10000]とかになりますが大丈夫なのでしょうか…
データ過剰に対するエラー処理はいっそのことwhile文の読みこみ処理の中に組み込んだ方がいい気がします。
m>MAXでOKですよね?
よくわかりませんが、コマンドラインでさらにn[10]しか用意していないから配列には11個目はいってきませんよね?
あまり理解できていないので意味不明なこと言ってたらすみません。
実はいまのを11個以上入力すると並び替えたうえでNUMBER IS OVERと表示されます。自分的にはそういうものは並べ替えずなにもファイルには出力しないうえでNUMBER IS OVERと表示すればいいと思っています。。。
やり方がわかりあせんが・・・・
Re: 明日までの宿題です・・・
Posted: 2012年4月26日(木) 02:14
by れお
[/quote]
あら?解決したんですか?;流れがわからないのでアレですが、宿題ならとりあえず動くならそれで出しちゃえばいいと思いますが‥‥さらっと見てて「ん‥?」と思うとことかあるので綺麗なコードが書けるまで修正することはオススメします[/quote]
あした(もはや今日)の14時までなので朝10時くらいまでなら修正は可能です。w
学校が遠いのでそれ以降はもう無理です・・・ww
さらっとみてそう思うということはそうとう汚いコードなんですね;
きれいなコードがどういうものかわからないので修正もできません;;
いまいちまだ下げ字?{ }のやつもどうすればいい(見やすくなる)のかわかってないですし・・・><
Re: 明日までの宿題です・・・
Posted: 2012年4月26日(木) 02:19
by kurain
奇妙な部分を発見しました。
コード:
int sort(int n[],int m){
略
return(n[m]);
}
sortは値を返しているにもかかわらず
sort(n,m-1);
受け取っていません。
逆に何故値を返すのかが疑問なのですが…何か意図があるのでしょうか。
当面放置しても良い部分ではありますが。
>よくわかりませんが、コマンドラインでさらにn[10]しか用意していないから配列には11個目はいってきませんよね?
入ってきちゃうんです。(多分)
>並び替えたうえでNUMBER IS OVER
うーん、ごめんなさいさっぱりです…
Re: 明日までの宿題です・・・
Posted: 2012年4月26日(木) 02:25
by nullptr
れお さんが書きました:すみません。これでどうでしょうか?まだ初心者なので・・・
コード:
#include <stdio.h>
#define MAX 10
int sort(int n[],int m){
int N=0,i=0,j=0;
for(i=0; i<m; i++){
for(j=i+1; j<m; j++){
if(n[i] > n[j]){
N = n[i];
n[i] = n[j];
n[j] = N;
}
}
}
return(n[m]);
}
int main(int argc, char *argv[])
{
FILE *fpi, *fpo;
int m=0, i=0;
int n[MAX];
if(argc != 3){
fprintf(stderr, "Illegal number of argument.\n");
return(-1);
}
if((fpi=fopen(argv[1],"r"))==NULL) {
fprintf(stderr, "Can't open input file <%s>.\n", argv[1]);
return(-1);
}
else {
while(! feof(fpi)){
fscanf(fpi,"%d",&n[m]);
m++;
}
if(m>=MAX){ //10こ以上の入力の判断
printf("NUMBER IS OVER");
return(-1);
}
fclose(fpi);
}
if((fpo=fopen(argv[2],"w"))==NULL) {
fprintf(stderr, "Can't open output file <%s>.\n", argv[2]);
return(-1);
}
else{
sort(n,m-1);//並べ替える関数にnの配列とm-1をわたす
//EOFまで数えてるから数字は1つ前まで
for(i=0;i<m;i++){
fprintf(fpo,"%d ",n[i]);
}
fclose(fpo);
}
return 0;
}
№3のこれをインデントするとこうですかね。
コード:
#include <stdio.h>
#define MAX 10
int sort(int n[],int m){
int N=0,i=0,j=0;
for(i=0; i<m; i++){
for(j=i+1; j<m; j++){
if(n[i] > n[j]){
N = n[i];
n[i] = n[j];
n[j] = N;
}
}
}
return(n[m]);
}
int main(int argc, char *argv[])
{
FILE *fpi, *fpo;
int m=0, i=0;
int n[MAX];
if(argc != 3){
fprintf(stderr, "Illegal number of argument.\n");
return(-1);
}
if((fpi=fopen(argv[1],"r"))==NULL) {
fprintf(stderr, "Can't open input file <%s>.\n", argv[1]);
return(-1);
}
else {
while(! feof(fpi)){
fscanf(fpi,"%d",&n[m]);
m++;
}
if(m>=MAX){ //10こ以上の入力の判断
printf("NUMBER IS OVER");
return(-1);
}
fclose(fpi);
}
if((fpo=fopen(argv[2],"w"))==NULL) {
fprintf(stderr, "Can't open output file <%s>.\n", argv[2]);
return(-1);
}
else{
sort(n,m-1);//並べ替える関数にnの配列とm-1をわたす EOFまで数えてるから数字は1つ前まで
for(i=0;i<m;i++){
fprintf(fpo,"%d ",n[i]);
}
fclose(fpo);
}
return 0;
}
まぁ内容は一切変えてないのでアレですが・・・インデントをととのえるだけでも少しは違うと思いますよ
Re: 明日までの宿題です・・・
Posted: 2012年4月26日(木) 02:26
by kurain
コード:
#include <stdio.h>
#define MAX 10
int sort(int n[],int m){
int N=0,i=0,j=0;
for(i=0; i<m; i++)
{
for(j=i+1; j<m; j++)
{
if(n[i] > n[j])
{
N = n[i];
n[i] = n[j];
n[j] = N;
}
}
}
return(n[m]);
}
int main(int argc, char *argv[])
{
FILE *fpi, *fpo;
int m=0, i=0;
int n[MAX];
if(argc != 3){
fprintf(stderr, "Illegal number of argument.\n");
return(-1);
}
if((fpi=fopen(argv[1],"r"))==NULL) {
fprintf(stderr, "Can't open input file <%s>.\n", argv[1]);
return(-1);
}
else {
while(! feof(fpi)){
fscanf(fpi,"%d",&n[m]);
m++;
}
if(m>=MAX){ //10こ以上の入力の判断
printf("NUMBER IS OVER");
return(-1);
}
fclose(fpi);
}
if((fpo=fopen(argv[2],"w"))==NULL) {
fprintf(stderr, "Can't open output file <%s>.\n", argv[2]);
return(-1);
}
else{
sort(n,m-1);//並べ替える関数にnの配列とm-1をわたす
//EOFまで数えてるから数字は1つ前まで
for(i=0;i<m;i++){
fprintf(fpo,"%d ",n[i]);
}
fclose(fpo);
}
return 0;
}
無駄な空行と先頭のスペース排除しました。
は
と分岐文と{を分離しました。
全部の行の先頭にスペース入れてみてください。
「{」がきたら「「{」の次の行以降」のスペースの数を4つ追加。
「}」がきたら「「}」の行から以降全部」スペースを4つ減らす。
インデントしっかりしろ!
と言う目的の一つはifやforに対する対応を見やすくするためです。
対応が一目でわかると非常に見やすくなります。
Re: 明日までの宿題です・・・
Posted: 2012年4月26日(木) 02:40
by れお
新月獅子さん
kurarinさん
ありがとうございます。
確かに自分のよりは断然にみやすいです^^
ただ自分のレベルではまだ一目ではわかりませんがww
これから頑張っていきたいと思います。(プログラミングかなり苦手ですが><)
初めてこのサイト使ったんですがみなさんやさしく、回答もはやいのでほんと助かりました。
これから多々w利用するとおもいますが宜しくお願いします。
はやくみなさんくらいになりたいです・・・><
ーーーーー
kurarinさん
intをvoidにしてreturnとっぱらいました。
1万個とかなったときのやつはよくわかりませんが、
12個とか入力ファイルにあったとすると、
それを並べ替えて10個までが出力ファイルに表示されちゃってます。
べつにいいんでしょうかね?ww、まぁ提出さえすれば単位をおとすことはないので細かいとこは宿題にはさほどかんけいないのですが・・・
Re: 明日までの宿題です・・・
Posted: 2012年4月26日(木) 02:49
by kurain
>>並び替えたうえでNUMBER IS OVER
>うーん、ごめんなさいさっぱりです…
うーん、やっぱりわからない。
コード:
if(m>=MAX){ //10こ以上の入力の判断
printf("NUMBER IS OVER");
return(-1);
}
この時点で止まるから下にあるソートは行われないはずなんだけど…
ソートしてから出力されるのも変だし…
思いっきりソースコード改変したりしていませんか?
>intをvoidにしてreturnとっぱらいました。
returnは取っちゃだめwww
void型の時は「return ;」です。
>1万個とかなったときのやつはよくわかりませんが、
実際にやったことが無いので実際は分かりませんがこれをやると
約4万バイトほどのメモリを破壊する気がします。
コード:
while(! feof(fpi)){
fscanf(fpi,"%d",&n[m]);
m++;
}
if(m>=MAX){ //10こ以上の入力の判断
printf("NUMBER IS OVER");
return(-1);
}
while全部が終わったらifの中身
ではなく、
whileの中身が終わるたびにif全部の方が良いでしょう。
コード:
while(! feof(fpi)){
fscanf(fpi,"%d",&n[m]);
m++;
if(m>=MAX){ //10こ以上の入力の判断
printf("NUMBER IS OVER");
return(-1);
}
}
Re: 明日までの宿題です・・・
Posted: 2012年4月26日(木) 02:57
by れお
みにくくてすみません
コード:
#include <stdio.h>
#define MAX 10
void sort(int n[],int m){
int N=0,i=0,j=0;
for(i=0; i<m; i++){
for(j=i+1; j<m; j++){
if(n[i] > n[j]){
N = n[i];
n[i] = n[j];
n[j] = N;
}
}
}
return 0;
}
int main(int argc, char *argv[])
{
FILE *fpi, *fpo;
int m=0, i=0;
int n[MAX];
if(argc != 3){
fprintf(stderr, "Illegal number of argument.\n");
return(-1);
}
if((fpi=fopen(argv[1],"r"))==NULL) {
fprintf(stderr, "Can't open input file <%s>.\n", argv[1]);
return(-1);
}
else {
while(! feof(fpi)){
fscanf(fpi,"%d",&n[m]);
m++;
}
if(m>MAX){ //10こ以上の入力の判断
printf("NUMBER IS OVER");
return(-1);
}
fclose(fpi);
}
if((fpo=fopen(argv[2],"w"))==NULL) {
fprintf(stderr, "Can't open output file <%s>.\n", argv[2]);
return(-1);
}
else{
sort(n,m);//並べ替える関数にnの配列をわたす
//改行してるとおそらく数字+1までよんでいるからm-1
for(i=0;i<m;i++){
fprintf(fpo,"%d ",n[i]);
}
fclose(fpo);
}
return 0;
}
が今のコードです。returnけすとか馬鹿すぎてすみません。全然きづかなかったです・・・でもエラーはなかったw
コード:
while(! feof(fpi)){
fscanf(fpi,"%d",&n[m]);
m++;
}
if(m>=MAX){ //10こ以上の入力の判断
printf("NUMBER IS OVER");
return(-1);
}
while全部が終わったらifの中身
ではなく、
whileの中身が終わるたびにif全部の方が良いでしょう。
コード:
while(! feof(fpi)){
fscanf(fpi,"%d",&n[m]);
m++;
if(m>=MAX){ //10こ以上の入力の判断
printf("NUMBER IS OVER");
return(-1);
}
}
[/quote]
なるほど。たしかにそうですね!!すごい納得できます。
Re: 明日までの宿題です・・・
Posted: 2012年4月26日(木) 03:03
by れお
11以上のデータがあっても並べ変わるというのは僕のミスでした。
忘れてください。
Re: 明日までの宿題です・・・
Posted: 2012年4月26日(木) 03:16
by nullptr
どうでもいいしいやたぶんどうでもよくはないけど好みだからアレなんだけど関数の命名はPascal記法がいいと思います。全部小文字とかってのは標準ライブラリとかとかぶるので・・・sort()とか
別にオーバーライド(ちゃうちゃうオーバーロードです。申しわけない)できるとはいえ呼び出し側はわかりにくくなると思います(標準ライブラリとの判別が)。わたしは、ですが。
Re: 明日までの宿題です・・・
Posted: 2012年4月26日(木) 03:20
by kurain
return 0;
ではなくて
return ;
です。
void型が値を返してはいけません。
コード:
#include <stdio.h>
#define MAX 10
void sort(int n[],int m){
int N=0,i=0,j=0;
for(i=0; i<m; i++){
for(j=i+1; j<m; j++){
if(n[i] > n[j]){
N = n[i];
n[i] = n[j];
n[j] = N;
}
}
}
return ;
}
int main(int argc, char *argv[])
{
FILE *fpi, *fpo;
int m=0, i=0;
int n[MAX];
if(argc != 3){
fprintf(stderr, "Illegal number of argument.\n");
return(-1);
}
if((fpi=fopen(argv[1],"r"))==NULL) {
fprintf(stderr, "Can't open input file <%s>.\n", argv[1]);
return(-1);
}
else {
while(! feof(fpi)){
fscanf(fpi,"%d",&n[m]);
m++;
}
if(m>MAX){ //10こ以上の入力の判断
printf("NUMBER IS OVER");
return(-1);
}
fclose(fpi);
}
if((fpo=fopen(argv[2],"w"))==NULL) {
fprintf(stderr, "Can't open output file <%s>.\n", argv[2]);
return(-1);
}
else{
sort(n,m);//並べ替える関数にnの配列をわたす
for(i=0;i<m;i++){
fprintf(fpo,"%d ",n[i]);
}
fclose(fpo);
}
return 0;
}
どうしてもインデントがおかしくなるようです。
インデントを直してみました。
オートインデント付きのエディタなどを使ってみるのも手かもしれません。
>11以上のデータがあっても並べ変わるというの
了解です。
他におかしなところは見つからないので…他の方の突っ込みが無ければ大丈夫かな?
データが1つだけの時や5個6個。ソートする必要が無いデータ。10個の時や11個の時。
試してみて大丈夫なら…問題ないと思います。
Cに
オーバーライド(あばばばば)オーバーロードって有りましたっけ…?
Re: 明日までの宿題です・・・
Posted: 2012年4月26日(木) 03:24
by nullptr
全部忘れろ~(^ν^)
Re: 明日までの宿題です・・・
Posted: 2012年4月26日(木) 03:27
by nullptr
ゴハッミスってたオーバーロードや
寝たほうがいいんかねこれ
Re: 明日までの宿題です・・・
Posted: 2012年4月26日(木) 03:32
by れお
コード:
#include <stdio.h>
#define MAX 10
void Sort(int n[],int m)
{
int N=0,i=0,j=0;
for(i=0; i<m; i++)
{
for(j=i+1; j<m; j++)
{
if(n[i] > n[j])
{
N = n[i];
n[i] = n[j];
n[j] = N;
}
}
}
return ;
}
int main(int argc, char *argv[])
{
FILE *fpi, *fpo;
int m=0, i=0;
int n[MAX];
if(argc != 3)
{
fprintf(stderr, "Illegal number of argument.\n");
return(-1);
}
if((fpi=fopen(argv[1],"r"))==NULL)
{
fprintf(stderr, "Can't open input file <%s>.\n", argv[1]);
return(-1);
}
else
{
while(! feof(fpi))
{
fscanf(fpi,"%d",&n[m]);
m++;
if(m>MAX)
{ //10こ以上の入力の判断
printf("NUMBER IS OVER");
return(-1);
}
}
fclose(fpi);
}
if((fpo=fopen(argv[2],"w"))==NULL)
{
fprintf(stderr, "Can't open output file <%s>.\n", argv[2]);
return(-1);
}
else
{
Sort(n,m);//並べ替える関数にnの配列をわたす
//改行してるとおそらく数字+1までよんでいるからm-1
for(i=0;i<m;i++)
{
fprintf(fpo,"%d ",n[i]);
}
fclose(fpo);
}
return 0;
}
自分でもインデントとやらをやってみました。みなさんのようにうまくはいってませんが・・・ましにはなったかと。
実はさっきから5回以上かきこんでるのに反映されてませんw
なので簡単にすませますが、みなさんほんと遅くまでありがとうございました。
テストとか簡単にやってみて、最低限のことができてればもう提出します。
おそらくまたこのサイト利用するのでそのときはまたお願いします。
ほんと感謝してます。ありがとうございました
Re: 明日までの宿題です・・・
Posted: 2012年4月26日(木) 09:06
by bitter_fox
関数の戻り値の型がvoidの場合はreturn文は任意なので関数末尾の場合は書かなくてもよいと思いますよ。
コード:
void f(int n)
{
if (n < 0)
{
return;
}
printf("%d\n", n);
}
れお さんが書きました:
自分でもインデントとやらをやってみました。みなさんのようにうまくはいってませんが・・・ましにはなったかと。
エディタは何を使われていますか?
オート(スマート)インデント機能のあるエディタを使って自動でインデントされるようにすれば楽ですよ。
そのエディタのするインデントに合わせていけば自然と良いインデントがどのようなものかもわかると思いますし・・・
Re: 明日までの宿題です・・・
Posted: 2012年4月26日(木) 19:29
by れお
eclipseですね。
一応やってくれますがなんか自分ではみにくいような・・・^^;
Re: 明日までの宿題です・・・
Posted: 2012年4月26日(木) 21:01
by bitter_fox
れお さんが書きました:eclipseですね。
一応やってくれますがなんか自分ではみにくいような・・・^^;
見にくいですか?僕はインデントされていないコードのほうが見にくい(醜い)と思いますね。
たとえば次のようなコード
コード:
void f(int n)
{
int count;
int i, j;
if (n >= 0)
{
for (i = 0; i < n; i++)
{
for (count = j = 0; j < i * n; j++)
{
if (j % 3 == 0 || j % 5 == 0)
{
count++;
}
}
}
printf("case %d:%d\n", i, count);
}
else
{
f(-n);
}
}
実はこのコードにはバグとなる個所があります。
それは、スコープに関する問題なんですが、次のようにインデントされたコードでは一目瞭然かと思います。
コード:
void f(int n)
{
int count;
int i, j;
if (n >= 0)
{
for (i = 0; i < n; i++)
{
for (count = j = 0; j < i * n; j++)
{
if (j % 3 == 0 || j % 5 == 0)
{
count++;
}
}
}
printf("case %d:%d\n", i, count);
}
else
{
f(-n);
}
}
Re: 明日までの宿題です・・・
Posted: 2012年4月26日(木) 21:57
by れお
すみません。。。スコープがわかりません。;
たしかにこれはかなり見やすいですね^^
Re: 明日までの宿題です・・・
Posted: 2012年4月26日(木) 23:56
by nullptr
じゃあスコープについて少し。例えばグローバル変数は実はグローバル領域と呼ばれる空間に所属しています。グローバル変数はそのまま使えますが、その場合たとえばint a;というグローバル変数を使うときはa = 0;とかというように使いますが、明示的に使うならスコープ演算子を使い::a = 0;とします。(厳密なC言語では出来ませんが多分C++のコンパイラを使っているでしょうからできると思います。)
若干語弊はありますが簡潔に言えば所属してる空間の名前(名前空間)などが総じてスコープと呼ばれます。
おそらく名前空間てなんぞ?と思うでしょうが難しくないです、例えばhoge関数の中は全てhoge名前空間に所属しています。
forにもスコープがあります。for(int i=0; i< 10; ++i )とした場合(forのなかで宣言されている場合)、forから抜けるとiは寿命を迎え解放されるのもforスコープの存在のためです。
御参考までに。
Re: 明日までの宿題です・・・
Posted: 2012年4月27日(金) 02:12
by かずま
feof の使い方を間違っているため、正しくデータが読みこめていませんね。
feof は、それより前の入力処理(fscanfや fgetsや fgetc) がエラーになったことを示すものです。
feof でチェックしても、次の入力データがあるとは限りません。
例えば、次のプログラムでは、入力データが 10個の場合、11個の数値が出力されてしまいます。
コード:
while (!feof(fp)) {
fscanf(fp, "%d", &i);
printf("%d\n", i);
}
fscanf, fgets, fgetc などの入力関数はすべて、正しく入力できたかどうかの
情報を返すのでそれをチェックするべきです。
データを最大10個読み込むときに、11個のデータがあったらエラーにしたいのなら、
11個目を実際に読み込まないと、判断できません。
入力データを格納する配列の大きさが 10 なら、一旦、別の変数に読み込んでから
その配列に格納しなければならないでしょう。
ということを踏まえて、全体を書き換えてみました。いかがでしょうか?
コード:
#include <stdio.h>
#define MAX 10
void sort(int n[], int m)
{
int N, i, j;
for (i = 0; i < m; i++) {
for (j = i + 1; j < m; j++) {
if (n[i] > n[j]) {
N = n[i];
n[i] = n[j];
n[j] = N;
}
}
}
}
int main(int argc, char *argv[])
{
FILE *fpi, *fpo;
int m, i;
int n[MAX];
if (argc != 3) {
fprintf(stderr, "Illegal number of argument.\n");
return 1;
}
fpi = fopen(argv[1], "r");
if (fpi == NULL) {
fprintf(stderr, "Can't open input file <%s>.\n", argv[1]);
return 1;
}
for (m = 0; fscanf(fpi, "%d", &i) == 1; m++) {
if (m >= MAX) {
fprintf(stderr, "NUMBER IS OVER\n");
return 1;
}
n[m] = i;
}
fclose(fpi);
fpo = fopen(argv[2], "w");
if (fpo == NULL) {
fprintf(stderr, "Can't open output file <%s>.\n", argv[2]);
return 1;
}
sort(n, m);
for (i = 0; i < m; i++) {
fprintf(fpo, "%d ", n[i]);
}
fclose(fpo);
return 0;
}
Re: 明日までの宿題です・・・
Posted: 2012年4月27日(金) 03:26
by ISLe
名前空間とスコープは別モノです。
名前空間はスコープを作るものです。
リンケージとスコープも別モノです。
グローバル変数でも宣言しないと変数名を使えません。
ライフサイクル(生存期間)とスコープも別モノです。
関数から関数を呼び出したとき、呼び出された関数から呼び出し元の関数の一時変数は見えませんがその時点で解放されてはいません。
スコープ(有効範囲・可視範囲)とは識別子を参照できる範囲のことです。
例えば変数名は宣言以降で且つその宣言を含むブロック({}で囲まれた範囲)内で有効です。
Re: 明日までの宿題です・・・
Posted: 2012年4月27日(金) 23:32
by れお
なるほど^^
なんとなくイメージできました。
ありがとうございます^^