プロが教えるわが家の防犯対策術!

C言語において時刻取得を以下のようにプログラムしたら、プログラムを3回目以上実行すると前回時間内容が常に1回目が表示されてしまいます。どこを直せばちゃんと前回の時刻が正しく表示されるようになるのでしょうか。put()のfopenの"a"の部分は"w"に変えるだけで正しく実行されるのですが、これを"a"にした場合について正しく表示されるようにするということです。

#include <time.h>
#include <stdio.h>

void get(void);
void put(void);
char data_file[] = "time.dat";
int main(void)
{
get();
put();
return(0);
}
/* 前回の日付・時刻を読込む   */
void get(void)
{
FILE *fp;
time_t t;
struct tm *local;

time(&t);
local = localtime(&t);

if ((fp = fopen(data_file, "r")) == NULL){
printf("\a本プログラムを実行するのは初めて\n");
}else {
int year, month, day, h, m, s;
fscanf(fp, "%d %d %d", &h, &m, &s);
printf("前回は%d時%d分%d秒\n", h, m, s);
fclose(fp);
}
}

/* 今回の日付・時刻を書き込む   */
void put(void)
{
FILE *fp;
time_t t;
struct tm *local;

time(&t);
local = localtime(&t);

if ((fp = fopen(data_file, "a")) == NULL)
printf("\aファイルをオープンできません。\n");
else {
printf("現在の日付・時刻を書き出しました。\n");
fprintf(fp, "%d %d %d\n",
local->tm_hour, local->tm_min, local->tm_sec );
fclose(fp);
}
}

A 回答 (3件)

出力ファイルにあるデータは 増えても構わないのであれば



get関数の fscanfを ループして最後まで読み込んでしまえばいいでしょう

do {
fsacnf(fp, "%d %d %d", &h, &m, &s);
} while ( !feof(fp) );

最後の行を読み込んで もう一度読み込もうした場合fscanfは失敗し
次の whileでループを終了します

出力ファイルに 常にデータが2行なら 出力する前に最後行(2行目)のデータを読み出して
2行とも出力しなおすといった具合になるでしょう
    • good
    • 0

同じような話が参考URLで持ち上がっています。


参考になるかもしれません。

参考URL:http://www2.realint.com/cgi-bin/tarticles.cgi?po …
    • good
    • 0

fopen(data_file,"a")


"a"ではファイルdata_fileの最終行の後に追加書き込みをしているので、
void get(void)で1行目だけを読み込んでいるのを < ここが問題
最終行から読み込むように変更する必要があります。

なのでvoid get(void)の

fscanf(fp, "%d %d %d", &h, &m, &s);
を細かい処理は省略し大まかにはこんな感じに変更します。
char buffer[100];
while(fgets(buffer,100,fp) != NULL){} /* 最終行をさがす */
sscanf(buffer, "%d %d %d", &h, &m, &s);


fopen(data_file,"w")で成功しているのは、既存のファイルに常に同じ名前のファイルを上書きしているので、1行目=最終行となっているためです。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!