ページ 11

C言語 ファイル入出力について

Posted: 2014年9月30日(火) 20:27
by suzuki
名前、生年月日を入力されて年齢を出力し、再起動時に同一氏名入力時は生年月日と年齢を出力する

上記の問題で、下記のプログラミングを訂正致しました。
最初の年齢が出るところまでしかいきません。
他に何か間違いなどあれば、現在手元に実行できるものがないので直して教えて頂けると幸いです。
宜しくお願い致します。


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main (void)
{
FILE *fp;
char name[256];
char cBuf[256];
int year,month,day;
int year2,month2,day2;
int y;

year = 0;
month = 0;
day = 0;
year2 = 0;
month2 = 0;
day2 = 0;
y = 0;

/*名前入力*/
printf("あなたの氏名は ? ");
scanf("%s",name);

/*ファイルオープン*/
fp = fopen ("a.txt","r");
memset(cBuf,0x00,sizeof(cBuf));
fgets(cBuf,sizeof(cBuf)-1,fp);

/*ファイルがNULLの時*/
if ( fp == NULL ){
printf("ファイルオープンできません\n");
return -1;
}
//ファイルがNULLじゃない時*/
else if ( fp != NULL){


/*名前一致*/
if( cBuf == name ){

fprintf(fp,"あなたは%d年%d月%d日生れの%d歳ですね\n",year,month,day,y);
}
/*名前が不一致*/
else if ( cBuf != name ){
while ( fgets (name,256,fp) != NULL ){
printf("%s",name);
}

/*生年月日入力計算*/
printf("生年月日 ? ");
scanf("%d%d%d",&year,&month,&day);
year2 =2014;
month2 =9;
day2 =30;
y =year2-year;
if(month2 < month){
y--;}
else if(month2==month && day2 < day){
y--;}
printf("あなたは%d歳ですね\n",y);

/*ファイル出力*/
fp = fopen ("a.txt","w");
if ( fp == NULL ){
printf("ファイルをオープンできません\n");
return 1;
}
else if ( fp != NULL ){
fprintf(fp,"%s,%d,%d,%d,%d\n",name,year,month,day,y);

fclose(fp);

}

}
}
}

Re: C言語 ファイル入出力について

Posted: 2014年9月30日(火) 21:00
by amehirune
コードを投稿する際は、

コード:

タグで囲っていただければ見やすくなります。ご活用ください。

if( cBuf == name )だと、
nameもcBufも、文字を入れる配列であるため、上記のように書くと、
「ポインタによる、アドレスの一致判定」がなされている…と、思います。( 私自身もあいまいです。間違ってたらごめんなさい><)
このままだと、二つのアドレスが一致することはあり得ませんので、必ず偽のelseが実行されてしまいます。

文字列の一致を判定するのであれば、手っ取り早い方法として「strcmp関数」があげられるのではないでしょうか。

Re: C言語 ファイル入出力について

Posted: 2014年9月30日(火) 21:11
by みけCAT
コードを提示するときはBBcodeを有効にした状態でcodeタグで囲み、
かつ適切なインデントをしていただけると、見やすくて助かります。
suzuki さんが書きました: fgets(cBuf,sizeof(cBuf)-1,fp);
suzuki さんが書きました: fprintf(fp,"%s,%d,%d,%d,%d\n",name,year,month,day,y);
このコードだと、scanfの%sで改行は入力できないので、
名前一致の判定を直し、名前と生年月日をコンマでつなげたデータを入力しても、
同一氏名が入力されたと判定されることは無さそうですね。
対策としては、
・nameに含まれるコンマをエスケープしてから出力する、もしくはnameを行の最後に出力する
・読み込むときは、fgetsでデータを読み込んだ後にパースを行って各データを復元する、もしくはgetcで読み込みながらパースする
というプログラムにするといいと思います。

Re: C言語 ファイル入出力について

Posted: 2014年9月30日(火) 22:57
by suzuki
amehirune さんが書きました:コードを投稿する際は、

コード:

タグで囲っていただければ見やすくなります。ご活用ください。

if( cBuf == name )だと、
nameもcBufも、文字を入れる配列であるため、上記のように書くと、
「ポインタによる、アドレスの一致判定」がなされている…と、思います。( 私自身もあいまいです。間違ってたらごめんなさい><)
このままだと、二つのアドレスが一致することはあり得ませんので、必ず偽のelseが実行されてしまいます。

文字列の一致を判定するのであれば、手っ取り早い方法として「strcmp関数」があげられるのではないでしょうか。[/quote]


コード投稿についてのご説明ありがとうございます。

早速やってみました。
[code]
/*名前一致*/
if ( strcmp ( cBuf,name) == 0 {
        printf ( fp,あなたは%d年%d月%d日生れの%d歳ですね\n",year,month,day,y);
}

/*名前が不一致*/
else {
        while ( fgets (name,256,fp) != NULL ){
        printf("%s",name);
}

Re: C言語 ファイル入出力について

Posted: 2014年10月01日(水) 00:16
by みけCAT
表示がおかしくなったため、トピックを移動したようです。
下記にある「言語ファイル入出力について」のsuzukiです
オフトピック
リンクをたどれなくなったため、他のページを参考にURLを入力することで返信画面を開きました。