明日までの宿題です・・・

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
れお

明日までの宿題です・・・

#1

投稿記事 by れお » 12年前

いそいでいます 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;
 } 


box
記事: 2002
登録日時: 13年前

Re: 明日までの宿題です・・・

#2

投稿記事 by box » 12年前

インデント(字下げ)の適切な付け方について教えてもらってないんでしょうか。
コードが見づらくてしょうがないです。
今みたいに自己流だと、将来困ることになりそうな気がします。
今のうちに直しておく方がいいと思います。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

れお

Re: 明日までの宿題です・・・

#3

投稿記事 by れお » 12年前

すみません。これでどうでしょうか?まだ初心者なので・・・

コード:

 
#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;
    }


sq

Re: 明日までの宿題です・・・

#4

投稿記事 by sq » 12年前

ファイルの読み取りですが、10個より多い場合でもループが止まりません。
そのため、m >= 10 のときでも、fscanf(fpi, "%d", &n[m]);が実行されてしまいます。

読み込んだ数mが一つ多くなる現象は、データファイルの末尾に改行があるからだと思います。
その場合、!feof();に引っかからずに一つ多く読みに行ってしまうからです。
改行がない場合はmは正確な数になるのでsort(n, m-1);は正確にソートされません。
入力データの書式に依存せずに、正確に読み込んだ数を数えるようにすればsort(n, m);でいいはずです。

kurain
記事: 12
登録日時: 12年前

Re: 明日までの宿題です・・・

#5

投稿記事 by kurain » 12年前

入力ファイルは何処(いずこ)…

ざっくり見てみました。

コード:

while(! feof(fpi))
{
    fscanf(fpi,"%d",&n[m]);
    m++;
}
ここで10個読みこんだとします。
ならmは10ですね。

コード:

sort(n,m-1);
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ですね。

コード:

sort(n,m-1);
…はいいのですが…

コード:

for(i=0;i<m;i++)
{
    fprintf(fpo,"%d ",n[i]);
}
ここでまずいことに。
n[10]を見に行ってしまいます。(n[10]は存在しない)
…が、エラーは出ないとおっしゃっているので前者かな?

>最後に変な数字がでてきたり、整数の個数が10個のとき10個以上のときなどがうまくいきません。

読みこむファイルの中身かファイルそのもの、出力結果などを提示するともっとスムーズに話が進みます。

インデントが奇妙です。
「{」がきたら4字下げる
「}」がきたら4字上げる
と言った具合に統一しましょう。

reo

Re: 明日までの宿題です・・・

#6

投稿記事 by reo » 12年前

kurain さんが書きました:入力ファイルは何処(いずこ)…

ざっくり見てみました。

コード:

while(! feof(fpi))
{
    fscanf(fpi,"%d",&n[m]);
    m++;
}
ここで10個読みこんだとします。
ならmは10ですね。

コード:

sort(n,m-1);
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ですね。

コード:

sort(n,m-1);
…はいいのですが…

コード:

for(i=0;i<m;i++)
{
    fprintf(fpo,"%d ",n[i]);
}
ここでまずいことに。
n[10]を見に行ってしまいます。(n[10]は存在しない)
…が、エラーは出ないとおっしゃっているので前者かな?

>最後に変な数字がでてきたり、整数の個数が10個のとき10個以上のときなどがうまくいきません。

読みこむファイルの中身かファイルそのもの、出力結果などを提示するともっとスムーズに話が進みます。

インデントが奇妙です。
「{」がきたら4字下げる
「}」がきたら4字上げる
と言った具合に統一しましょう。

れお

Re: 明日までの宿題です・・・

#7

投稿記事 by れお » 12年前

sort(n, m)
にすれば変な数字がでてくることはなくなりました。

しかしファイルに10個入力されているときでもNUMBER IS OVERが表示されてしまいます・・・

アバター
nullptr
記事: 239
登録日時: 12年前

Re: 明日までの宿題です・・・

#8

投稿記事 by nullptr » 12年前

N≦10なら
if(m>=MAX){ //10こ以上の入力の判断
じゃなくて
if(m>MAX){ //10こ以上の入力の判断
なんじゃ‥‥いやさらっと見ただけなんで見当違いなら申し訳ないです

*完全にミスりました忘れてくださいorz
 
 
✜ で C ご ✜
: す + 注 :
¦ か + 文 ¦
?
Is the は :
order C++? ✜
     糸冬   
  ――――――――
  制作・著作 NHK
 
 

れお

Re: 明日までの宿題です・・・

#9

投稿記事 by れお » 12年前

新月獅子 さんが書きました:N≦10なら
if(m>=MAX){ //10こ以上の入力の判断
じゃなくて
if(m>MAX){ //10こ以上の入力の判断
なんじゃ‥‥いやさらっと見ただけなんで見当違いなら申し訳ないです

*完全にミスりました忘れてくださいorz


いや、それで解決しました。。ww多分

そこ直しただけではだめですか??;

kurain
記事: 12
登録日時: 12年前

Re: 明日までの宿題です・・・

#10

投稿記事 by kurain » 12年前

コード:

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文の読みこみ処理の中に組み込んだ方がいい気がします。

アバター
nullptr
記事: 239
登録日時: 12年前

Re: 明日までの宿題です・・・

#11

投稿記事 by nullptr » 12年前

れお さんが書きました:
新月獅子 さんが書きました:N≦10なら
if(m>=MAX){ //10こ以上の入力の判断
じゃなくて
if(m>MAX){ //10こ以上の入力の判断
なんじゃ‥‥いやさらっと見ただけなんで見当違いなら申し訳ないです

*完全にミスりました忘れてくださいorz


いや、それで解決しました。。ww多分

そこ直しただけではだめですか??;
あら?解決したんですか?;流れがわからないのでアレですが、宿題ならとりあえず動くならそれで出しちゃえばいいと思いますが‥‥さらっと見てて「ん‥?」と思うとことかあるので綺麗なコードが書けるまで修正することはオススメします
 
 
✜ で C ご ✜
: す + 注 :
¦ か + 文 ¦
?
Is the は :
order C++? ✜
     糸冬   
  ――――――――
  制作・著作 NHK
 
 

れお

Re: 明日までの宿題です・・・

#12

投稿記事 by れお » 12年前

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: 明日までの宿題です・・・

#13

投稿記事 by れお » 12年前

[/quote]
あら?解決したんですか?;流れがわからないのでアレですが、宿題ならとりあえず動くならそれで出しちゃえばいいと思いますが‥‥さらっと見てて「ん‥?」と思うとことかあるので綺麗なコードが書けるまで修正することはオススメします[/quote]


あした(もはや今日)の14時までなので朝10時くらいまでなら修正は可能です。w
学校が遠いのでそれ以降はもう無理です・・・ww

さらっとみてそう思うということはそうとう汚いコードなんですね;
きれいなコードがどういうものかわからないので修正もできません;;

いまいちまだ下げ字?{ }のやつもどうすればいい(見やすくなる)のかわかってないですし・・・><

kurain
記事: 12
登録日時: 12年前

Re: 明日までの宿題です・・・

#14

投稿記事 by kurain » 12年前

奇妙な部分を発見しました。

コード:

int sort(int n[],int m){
    略
    return(n[m]);
}
sortは値を返しているにもかかわらず
sort(n,m-1);
受け取っていません。
逆に何故値を返すのかが疑問なのですが…何か意図があるのでしょうか。
当面放置しても良い部分ではありますが。

>よくわかりませんが、コマンドラインでさらにn[10]しか用意していないから配列には11個目はいってきませんよね?
入ってきちゃうんです。(多分)

>並び替えたうえでNUMBER IS OVER
うーん、ごめんなさいさっぱりです…

アバター
nullptr
記事: 239
登録日時: 12年前

Re: 明日までの宿題です・・・

#15

投稿記事 by nullptr » 12年前

れお さんが書きました:すみません。これでどうでしょうか?まだ初心者なので・・・

コード:

 
#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;
}
まぁ内容は一切変えてないのでアレですが・・・インデントをととのえるだけでも少しは違うと思いますよ
最後に編集したユーザー nullptr on 2012年4月26日(木) 02:31 [ 編集 2 回目 ]
 
 
✜ で C ご ✜
: す + 注 :
¦ か + 文 ¦
?
Is the は :
order C++? ✜
     糸冬   
  ――――――――
  制作・著作 NHK
 
 

kurain
記事: 12
登録日時: 12年前

Re: 明日までの宿題です・・・

#16

投稿記事 by kurain » 12年前

コード:

#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;
}
無駄な空行と先頭のスペース排除しました。

コード:

if(   ){
    hogehoge
}

コード:

if(   )
{
    hogehoge
}
と分岐文と{を分離しました。

全部の行の先頭にスペース入れてみてください。
「{」がきたら「「{」の次の行以降」のスペースの数を4つ追加。
「}」がきたら「「}」の行から以降全部」スペースを4つ減らす。
インデントしっかりしろ!
と言う目的の一つはifやforに対する対応を見やすくするためです。
対応が一目でわかると非常に見やすくなります。

れお

Re: 明日までの宿題です・・・

#17

投稿記事 by れお » 12年前

新月獅子さん
kurarinさん
ありがとうございます。
確かに自分のよりは断然にみやすいです^^

ただ自分のレベルではまだ一目ではわかりませんがww
これから頑張っていきたいと思います。(プログラミングかなり苦手ですが><)
初めてこのサイト使ったんですがみなさんやさしく、回答もはやいのでほんと助かりました。
これから多々w利用するとおもいますが宜しくお願いします。
はやくみなさんくらいになりたいです・・・><


ーーーーー
kurarinさん
intをvoidにしてreturnとっぱらいました。

1万個とかなったときのやつはよくわかりませんが、
12個とか入力ファイルにあったとすると、
それを並べ替えて10個までが出力ファイルに表示されちゃってます。
べつにいいんでしょうかね?ww、まぁ提出さえすれば単位をおとすことはないので細かいとこは宿題にはさほどかんけいないのですが・・・

kurain
記事: 12
登録日時: 12年前

Re: 明日までの宿題です・・・

#18

投稿記事 by kurain » 12年前

>>並び替えたうえで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);
            }
        }

れお
記事: 113
登録日時: 12年前

Re: 明日までの宿題です・・・

#19

投稿記事 by れお » 12年前

みにくくてすみません

コード:

#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]

なるほど。たしかにそうですね!!すごい納得できます。

れお
記事: 113
登録日時: 12年前

Re: 明日までの宿題です・・・

#20

投稿記事 by れお » 12年前

11以上のデータがあっても並べ変わるというのは僕のミスでした。
忘れてください。

アバター
nullptr
記事: 239
登録日時: 12年前

Re: 明日までの宿題です・・・

#21

投稿記事 by nullptr » 12年前

どうでもいいしいやたぶんどうでもよくはないけど好みだからアレなんだけど関数の命名はPascal記法がいいと思います。全部小文字とかってのは標準ライブラリとかとかぶるので・・・sort()とか
別にオーバーライド(ちゃうちゃうオーバーロードです。申しわけない)できるとはいえ呼び出し側はわかりにくくなると思います(標準ライブラリとの判別が)。わたしは、ですが。
最後に編集したユーザー nullptr on 2012年4月26日(木) 03:32 [ 編集 1 回目 ]
 
 
✜ で C ご ✜
: す + 注 :
¦ か + 文 ¦
?
Is the は :
order C++? ✜
     糸冬   
  ――――――――
  制作・著作 NHK
 
 

kurain
記事: 12
登録日時: 12年前

Re: 明日までの宿題です・・・

#22

投稿記事 by kurain » 12年前

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にオーバーライド(あばばばば)オーバーロードって有りましたっけ…?
最後に編集したユーザー kurain on 2012年4月26日(木) 17:35 [ 編集 1 回目 ]

アバター
nullptr
記事: 239
登録日時: 12年前

Re: 明日までの宿題です・・・

#23

投稿記事 by nullptr » 12年前

全部忘れろ~(^ν^)
最後に編集したユーザー nullptr on 2012年4月26日(木) 03:28 [ 編集 1 回目 ]
 
 
✜ で C ご ✜
: す + 注 :
¦ か + 文 ¦
?
Is the は :
order C++? ✜
     糸冬   
  ――――――――
  制作・著作 NHK
 
 

アバター
nullptr
記事: 239
登録日時: 12年前

Re: 明日までの宿題です・・・

#24

投稿記事 by nullptr » 12年前

ゴハッミスってたオーバーロードや

寝たほうがいいんかねこれ
 
 
✜ で C ご ✜
: す + 注 :
¦ か + 文 ¦
?
Is the は :
order C++? ✜
     糸冬   
  ――――――――
  制作・著作 NHK
 
 

れお
記事: 113
登録日時: 12年前

Re: 明日までの宿題です・・・

#25

投稿記事 by れお » 12年前

コード:

 
#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
なので簡単にすませますが、みなさんほんと遅くまでありがとうございました。
テストとか簡単にやってみて、最低限のことができてればもう提出します。

おそらくまたこのサイト利用するのでそのときはまたお願いします。

ほんと感謝してます。ありがとうございました

アバター
bitter_fox
記事: 607
登録日時: 13年前
住所: 大阪府

Re: 明日までの宿題です・・・

#26

投稿記事 by bitter_fox » 12年前

関数の戻り値の型がvoidの場合はreturn文は任意なので関数末尾の場合は書かなくてもよいと思いますよ。

コード:

void f(int n)
{
	if (n < 0)
	{
		return;
	}

	printf("%d\n", n);
}
れお さんが書きました: 自分でもインデントとやらをやってみました。みなさんのようにうまくはいってませんが・・・ましにはなったかと。
エディタは何を使われていますか?
オート(スマート)インデント機能のあるエディタを使って自動でインデントされるようにすれば楽ですよ。
そのエディタのするインデントに合わせていけば自然と良いインデントがどのようなものかもわかると思いますし・・・

れお
記事: 113
登録日時: 12年前

Re: 明日までの宿題です・・・

#27

投稿記事 by れお » 12年前

eclipseですね。
一応やってくれますがなんか自分ではみにくいような・・・^^;

アバター
bitter_fox
記事: 607
登録日時: 13年前
住所: 大阪府

Re: 明日までの宿題です・・・

#28

投稿記事 by bitter_fox » 12年前

れお さんが書きました: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);
	}
}

れお
記事: 113
登録日時: 12年前

Re: 明日までの宿題です・・・

#29

投稿記事 by れお » 12年前

すみません。。。スコープがわかりません。;
たしかにこれはかなり見やすいですね^^

アバター
nullptr
記事: 239
登録日時: 12年前

Re: 明日までの宿題です・・・

#30

投稿記事 by nullptr » 12年前

じゃあスコープについて少し。例えばグローバル変数は実はグローバル領域と呼ばれる空間に所属しています。グローバル変数はそのまま使えますが、その場合たとえばint a;というグローバル変数を使うときはa = 0;とかというように使いますが、明示的に使うならスコープ演算子を使い::a = 0;とします。(厳密なC言語では出来ませんが多分C++のコンパイラを使っているでしょうからできると思います。)

若干語弊はありますが簡潔に言えば所属してる空間の名前(名前空間)などが総じてスコープと呼ばれます。

おそらく名前空間てなんぞ?と思うでしょうが難しくないです、例えばhoge関数の中は全てhoge名前空間に所属しています。
forにもスコープがあります。for(int i=0; i< 10; ++i )とした場合(forのなかで宣言されている場合)、forから抜けるとiは寿命を迎え解放されるのもforスコープの存在のためです。


御参考までに。
 
 
✜ で C ご ✜
: す + 注 :
¦ か + 文 ¦
?
Is the は :
order C++? ✜
     糸冬   
  ――――――――
  制作・著作 NHK
 
 

かずま

Re: 明日までの宿題です・・・

#31

投稿記事 by かずま » 12年前

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;
}

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: 明日までの宿題です・・・

#32

投稿記事 by ISLe » 12年前

名前空間とスコープは別モノです。
名前空間はスコープを作るものです。

リンケージとスコープも別モノです。
グローバル変数でも宣言しないと変数名を使えません。

ライフサイクル(生存期間)とスコープも別モノです。
関数から関数を呼び出したとき、呼び出された関数から呼び出し元の関数の一時変数は見えませんがその時点で解放されてはいません。


スコープ(有効範囲・可視範囲)とは識別子を参照できる範囲のことです。
例えば変数名は宣言以降で且つその宣言を含むブロック({}で囲まれた範囲)内で有効です。

れお
記事: 113
登録日時: 12年前

Re: 明日までの宿題です・・・

#33

投稿記事 by れお » 12年前

なるほど^^
なんとなくイメージできました。
ありがとうございます^^

閉鎖

“C言語何でも質問掲示板” へ戻る