C言語における時刻取得の正しい実装方法とは?

このQ&Aのポイント
  • C言語において時刻取得を正しく実装する方法を説明します。
  • プログラムを複数回実行しても前回の時刻が正しく表示されるようにするにはどうすれば良いか解説します。
  • ファイルを書き込む際に使うプログラムのコードも紹介します。
回答を見る
  • ベストアンサー

時刻取得について

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

質問者が選んだベストアンサー

  • ベストアンサー
  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.1

出力ファイルにあるデータは 増えても構わないのであれば get関数の fscanfを ループして最後まで読み込んでしまえばいいでしょう do { fsacnf(fp, "%d %d %d", &h, &m, &s); } while ( !feof(fp) ); 最後の行を読み込んで もう一度読み込もうした場合fscanfは失敗し 次の whileでループを終了します 出力ファイルに 常にデータが2行なら 出力する前に最後行(2行目)のデータを読み出して 2行とも出力しなおすといった具合になるでしょう

その他の回答 (2)

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.3

同じような話が参考URLで持ち上がっています。 参考になるかもしれません。

参考URL:
http://www2.realint.com/cgi-bin/tarticles.cgi?pointc+30405
  • qqtester
  • ベストアンサー率66% (10/15)
回答No.2

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行目=最終行となっているためです。

関連するQ&A

  • エラーがわかりません、、

    以下のプログラムを入力したときに以下のえらーがでます。 List13-4.c: In function ‘get_data’: List13-4.c:18: error: expected expression before ‘)’ token 18行目を探すのですが、自力では見つけられません。もしかしたら 別のところが間違っていて18行目がエラーと出ているのかなと思っています。ならいたてですぐにわかるようなミスかもしれないですが、よろしくお願いします。 #include <stdio.h> #include <time.h> char data_file[] = "datetime.data"; void get_data(void) { FILE *fp; if((fp = fopen(data_file,"r")) == NULL){ printf("本プログラムを実行するのは初めてですね\n"); } else{ int year,month,day,h,m,s; fscanf(fp,"%d %d %d %d %d %d",&year,&month,&day,&h,&m,&s); printf("前回は%d年%d月%d日%d時%d分%d秒でした\n",year,month,day,h,m,s,); fclose(fp); } } void put_data(void) { FILE *fp; time_t t; struct tm *local; time(&t); local = localtime(&t); if((fp = fopen(data_file,"w")) == NULL) printf("\aファイルをオープンできません\n"); else{ fprintf(fp,"%d %d %d %d %d %d\n", local->tm_year + 1900,local->tm_mon + 1 ,local->tm_mday, local->tm_hour, local->tm_min, local->tm_sec); fclose(fp); } } int main(void) { get_data(); put_data(); return(0); }

  • C言語 初心者です。

    いつもお世話になっています。 以下のソースはファイルに今日の日付を書き込み、それをコマンドプロンプトに表示させたいと思い作成しましたが、できません。 どうか教えてください。 #include <time.h> #include <stdio.h> void put_data(void) { FILE *fp; time_t t; struct tm *local; time(&t); local = localtime(&t); fp = fopen("time.txt", "w"); int year, month, day; fprintf(fp, "%d%d%d%d\t",local->tm_year + 1900, local->tm_mon + 1, local->tm_day); printf("%d%d%d%d\n", year, month, day); fclose(fp); } int main(void) { put_data(); return 0; }

  • 現在時刻をミリ秒まで取得

    お疲れ様です 現在時刻をミリ秒まで取得がしたいです。 今はtime_tを使って秒までは取得したのですがミリ秒は構造体にないらしく同じようにとってはこれないのでしょうか? また別のやり方だとどんなのがあるか教えてください。 現在は下記のように取得してyyyymmddhhmmssの形を作ってます。 これをyyyymmddhhmmsssssのようにミリ秒を増やしたたいのです。 長くなってしまいましたがよろしくお願いします time_t timer; time(&timer);/* 現在の時刻を取得 */ struct tm *local; local =localtime(&timer);/* 地方時の構造体に変換 */ CString time; //CString用の時間 time.Format("%4d%02d%02d%02d%02d%02d" ,local->tm_year + 1900,/* 年 */ local->tm_mon+1,/*月は0から始まるので1を+*/ local->tm_mday,/* 日 */ local->tm_hour,/* 時 */ local->tm_min,/* 分 */ local->tm_sec);/* 秒 */

  • C言語のqsortについて

    現在、qsortのコードに取り組んでいます。 if (strcmp(ad, "ASC") == 0) { qsort(sin, sizeof(cnt), sizeof(sin[0]), cmp_u); } else { qsort(sin, sizeof(cnt), sizeof(sin[0]), cmp_d); } 恐らくこちらのqsortでの第二引数が書き方を間違えていると思うのですが、修正の方法が分からず、どなたか教えて頂けないでしょうか? #include <stdio.h> #include <time.h> #include <string.h> #include <stdlib.h> static char ad[10]; int cmp_u(const void* a, const void* d) { return strcmp((char*)a, (char*)d); } int cmp_d(const void* a, const void* d) { return strcmp((char*)d, (char*)a); } int main() { int num1, num2; char op; float answer; int r,i; FILE* fp; char c[11]; char sin[1000][1000]; char ad[8]; fp = fopen("log.txt", "a+"); if (fp == NULL) { printf("ファイルオープン失敗\n"); return -1; } while (1) { r = scanf("%d%c%d", &num1, &op, &num2); if (r != 3) { puts("input error"); return 1; } if (op == '+') { answer = num1 + num2; } else if (op == '-') { answer = num1 - num2; } else if (op == '*') { answer = num1 * num2; } else if (op == '/') { answer = (float)num1 / num2; } time_t t = time(NULL); struct tm* tm = localtime(&t); printf("%d/%02d/%02d ", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday); printf("%02d:%02d:%02d ", tm->tm_hour, tm->tm_min, tm->tm_sec); printf("%d%c%d,%f\n", num1, op, num2, answer); fprintf(fp, "%d/%02d/%02d ", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday); fprintf(fp, "%02d:%02d:%02d ", tm->tm_hour, tm->tm_min, tm->tm_sec); fprintf(fp, "%d%c%d,%f\n", num1, op, num2, answer); printf("計算を続けますか?"); scanf("%s\n", &c); if (strcmp(c, "no") == 0) { break ; } } fclose(fp); fp = fopen("log.txt", "r"); int cnt = 0; for (i = 0;i < 1000;i = i + 1) { if (fgets(sin[i], sizeof(sin[0]), fp)) ++cnt; else break; } fclose(fp); printf("ASC or DESC: "); scanf("%s", ad); if (strcmp(ad, "ASC") == 0) { qsort(sin, sizeof(cnt), sizeof(sin[0]), cmp_u); } else { qsort(sin, sizeof(cnt), sizeof(sin[0]), cmp_d); } for (i = 0;i < cnt;i = i + 1) { printf("%s", sin[i]); } return 0; }

  • C言語の、戻り値/値渡し/アドレス渡しのついて

    【実装したコードに、戻り値/値渡し/アドレス渡しを用いたサブの関数を作成せよ。】 上記の課題に取り組んでいるのですが、何となく概念は分かったのですが、ソースコードに反映させようとすると詰まってしまって… どなたか教えて頂けないでしょうか? 『ソースコード』 #include <stdio.h> #include <time.h> #include <string.h> #include <stdlib.h> #define CALC (3) #define FROM_YEAR (1900) #define MAX_LINE (1000) int cmp_u(const void* a, const void* d) { return strcmp((char*)a, (char*)d); } int cmp_d(const void* a, const void* d) { return strcmp((char*)d, (char*)a); } int main() { int num1, num2; char op; float answer; int r,i; FILE* fp; char e[11]; char sin[1000][1000]; char ad[8]; fp = fopen("log.txt", "a+"); if (fp == NULL) { printf("ファイルオープン失敗\n"); return -1; } while (1) { r = scanf("%d%c%d", &num1,&op, &num2); if (r != CALC) { puts("input error"); return 1; } if (op == '+') { answer = num1 + num2; } else if (op == '-') { answer = num1 - num2; } else if (op == '*') { answer = num1 * num2; } else if (op == '/') { answer = (float)num1 / num2; } time_t t = time(NULL); struct tm* tm = localtime(&t); printf("%d/%02d/%02d ", tm->tm_year + FROM_YEAR, tm->tm_mon + 1, tm->tm_mday); printf("%02d:%02d:%02d ", tm->tm_hour, tm->tm_min, tm->tm_sec); printf("%d%c%d,%f\n", num1, op, num2, answer); fprintf(fp, "%d/%02d/%02d ", tm->tm_year + FROM_YEAR, tm->tm_mon + 1, tm->tm_mday); fprintf(fp, "%02d:%02d:%02d ", tm->tm_hour, tm->tm_min, tm->tm_sec); fprintf(fp, "%d%c%d,%f\n", num1, op, num2, answer); printf("計算を続けますか?"); scanf("%s", e); if (strcmp(e, "no") == 0) { break ; } } fclose(fp); fp = fopen("log.txt", "r"); int cnt = 0; for (i = 0;i < MAX_LINE;i = i + 1) { if (fgets(sin[i], sizeof(sin[0]), fp)) ++cnt; else break; } fclose(fp); printf("ASC or DESC: "); scanf("%s", ad); if (strcmp(ad, "ASC") == 0) { qsort(sin, cnt, sizeof(sin[0]), cmp_u); } else { qsort(sin, cnt, sizeof(sin[0]), cmp_d); } for (i = 0;i < cnt;i = i + 1) { printf("%s", sin[i]); } return 0; }

  • C言語のtime_tに関して

    こんにちは。 今現在、C言語にてプログラミングを行っております。time_tを用いましたが、4月などの2桁目が0のは巧く取得できたのですが、日にちの2桁目が0にならず、空白となってしまいます。 一応、ソースを載せておきますが見辛いのが申し訳ないです。 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> time_t timer; struct tm *local; struct tm *utc; extern char today[20]; extern char today2[20]; extern char today_year[10]; extern char today_month[2]; extern char today_day[2]; void day(){ char *ptr; /* 現在時刻を取得 */ timer = time(NULL); local = localtime(&timer); /* 地方時に変換 */ /* 地方時 変換後表示 */ printf("地方時: "); printf("%4d/", local->tm_year + 1900); printf("%2d/", local->tm_mon + 1); printf("%2d ", local->tm_mday); if(local->tm_mday<10) //system("pause"); // printf("%2d:", local->tm_hour); // printf("%2d:", local->tm_min); // printf("%2d", local->tm_sec); // printf(" %d\n", local->tm_isdst); /*****************************/ sprintf(today_year,"%4d", local->tm_year + 1900); sprintf(today_month,"%2d", local->tm_mon + 1); sprintf(today_day,"%2d", local->tm_mday); if((local->tm_mon+1)<=9) today_month[0]='0'; if((local->tm_mday+1)<=9) today_day[0]='0'; sprintf(today, "%s-%s-%s", today_year, today_month, today_day); sprintf(today2, "%s/%s/%s", today_year, today_month, today_day); //printf("%s",today); /*****************************/ // utc = gmtime(&timer); /* 協定世界時(UTC)に変換 */ /* 協定世界時 変換後表示 */ // printf("\n\n\n\n協定世界時: "); // printf("%4d/", utc->tm_year + 1900); // printf("%2d/", utc->tm_mon + 1); // printf("%2d ", utc->tm_mday); // printf("%2d:", utc->tm_hour); // printf("%2d:", utc->tm_min); // printf("%2d", utc->tm_sec); // printf(" %d\n", utc->tm_isdst); return; } どなたかご教示下さい。

  • いつもお世話になっております。以下のようなプログラムで現在時刻の表示を

    いつもお世話になっております。以下のようなプログラムで現在時刻の表示をしているわけですが、 #include <stdio.h> #include <time.h> int main(void) { //日付 time_t tmp; struct tm date; time(&tmp); date = *(localtime(&tmp)); printf("現在の時刻:%d-%d-%d %d:%d\n", date.tm_year + 1900 , date.tm_mon + 1 , date.tm_mday , date.tm_hour , date.tm_min); return 0; } このプログラムで動いているので問題は無いのですが、 例えば月・日・時・分が1桁の場合に出力画面が「2010-5-20 14:7」となってしまいます。 個人的には「2010-05-20 14:07」とYYYY-MM-DD HH:MM←(この書き方であってるか不安…) 方式にしたいのですがどのようにすれば良いでしょうか?

  • write関数でファイルディスクリプタfile(fp1)に出力されません

    宜しくお願い致します。Windows2000でCygwinを使用しています。 $ cat test6.c #include<stdio.h> int main(void){ FILE *fp1,*fp2; fp1=fopen("file.txt","w"); fp2=fopen("file.txt","a"); printf("fp1->fd=%d\n",fileno(fp1)); printf("fp2->fd=%d\n",fileno(fp2)); write("first",fileno(fp1),2); write("second",fileno(fp2),2); return 0; } $ gcc -o test6 test6.c $ test6 fp1->fd=3 fp2->fd=4 $ cat ./file.txt となり、 file.txtに"first"と"second"が出力されるとかと思いましたが空ファイルです。 これは何が原因なのでしょうか?

  • C言語のエラー処理について

    下記のコードを作成したのですが、入力エラーの際に出力される表示が意図した input error の出力と違う形で表示されてしまい、修正方法が分からず、どなたか教えて頂けないでしょうか? ・『あ』等の整数以外の文字が入力された時 input errorinput errorinput error ・/0が入力された時 input error input error input error 「ソースコード」 #include <stdio.h> #include <time.h> #include <string.h> #include <stdlib.h> #define CALC (3) #define FROM_YEAR (1900) #define MAX_LINE (1000) #define MAX_ROW (1000) float calc_proc(int* n1, char op, int n2, float* ans) { switch (op) { case '+': *ans = (float)*n1 + n2; break; case '-': *ans = (float)*n1 - n2; break; case '*': *ans = (float)*n1 * n2; break; case '/': if (n2 == 0) { puts("input error"); return 1; } *ans = (float)(float)*n1 / n2; break; default: printf("input error"); return 1; break; } return 0; } int cmp_u(const void* a, const void* d) { return strcmp((char*)a, (char*)d); } int cmp_d(const void* a, const void* d) { return strcmp((char*)d, (char*)a); } int main() { int num1, num2; char op; float answer; int i; FILE* fp; char e[11]; char sin[MAX_LINE][MAX_ROW]; char ad[8]; fp = fopen("log.txt", "a+"); if (fp == NULL) { printf("ファイルオープン失敗\n"); return -1; } while (1) { scanf("%d%c%d", &num1, &op, &num2); calc_proc(&num1, op, num2, &answer); if (calc_proc(&num1, op, num2, &answer) != 0) { puts("input error"); return 1; } time_t t = time(NULL); struct tm* tm = localtime(&t); printf("%d/%02d/%02d ", tm->tm_year + FROM_YEAR, tm->tm_mon + 1, tm->tm_mday); printf("%02d:%02d:%02d ", tm->tm_hour, tm->tm_min, tm->tm_sec); printf("%d%c%d,%f\n", num1, op, num2, answer); fprintf(fp, "%d/%02d/%02d ", tm->tm_year + FROM_YEAR, tm->tm_mon + 1, tm->tm_mday); fprintf(fp, "%02d:%02d:%02d ", tm->tm_hour, tm->tm_min, tm->tm_sec); fprintf(fp, "%d%c%d,%f\n", num1, op, num2, answer); printf("計算を続けますか?"); scanf("%s", e); if (strcmp(e, "no") == 0) { break ; } } fclose(fp); fp = fopen("log.txt", "r"); if (fp == NULL) { printf("ファイルオープン失敗\n"); return -1; } int cnt = 0; for (i = 0;i < MAX_LINE;i = i + 1) { if (fgets(sin[i], sizeof(sin[0]), fp)) ++cnt; else break; } fclose(fp); printf("ASC or DESC: "); scanf("%s", ad); if (strcmp(ad, "ASC") == 0) { qsort(sin, cnt, sizeof(sin[0]), cmp_u); } else { qsort(sin, cnt, sizeof(sin[0]), cmp_d); } for (i = 0;i < cnt;i = i + 1) { printf("%s", sin[i]); } return 0; }

  • time関数

    time関数で取得した値をファイル名として、任意のディレクトリにファイルを作成したいのですが、実装方法がわかりません お分かりの方、教えていただけませんでしょうか #include<stdio.h> #include <stdlib.h> #include <time.h> #include<sys/types.h> #include<unistd.h> time_t time(time_t *tloc); int main(void){ char keys[16] = "\x00"; time_t t; t = time(&t); printf("%ld\n", t); FILE *fp; fp = fopen(・・・・・ "w");    :     :     : fclose(fp);

専門家に質問してみよう