掲示板システム
ホーム
アクセス解析
カテゴリ
ログアウト
年齢 (ID:52989)
名前
ホームページ(ブログ、Twitterなど)のURL (省略可)
本文
> 誤差無しで正確に年齢を得られるソースを再掲しときます。 処理系依存する上に長く,使い勝手が悪いです。 さらに,突っ込み所が結構ある……。 > // birthday YYYY/MM/DD → age > int getAge(char *birth) int getAge (const char * birth) 変更しないのであればconstを付けること。 特に,文字列を受け入れる場合はconstを付けるか否かは重要です。 CにしろC++にしろ,文字列リテラルを変更すると未定義動作となります。 #C++では元々const charの配列だが。 故に,char *に文字列リテラルを渡すことは未定義動作を引き渡す原因となり得るため, Cがわかっているプログラマであれば,char *に文字列リテラルを渡すことは躊躇うでしょう。 例えば, char * p; int age; p = malloc(strlen("1954/01/14") + 1); if (!p) abort(); strcpy(p, "1954/01/14"); age = getAge(p); free(p); のように使う可能性があります。 > strcpy(wbuf,(const char *)birth); char *からconst char *へのキャストは不要です。 #constがわかっていない? このキャストは最悪,型の不一致というコンパイラの警告/エラーを握りつぶすという問題を持っています。 > i = fix = 0; > tkn = strtok(wbuf,"/"); > while (tkn != NULL){ > ymd[i++] = atoi(tkn); > tkn = strtok(NULL,"/"); > } sscanfを使えばよい問題ですし,このコードでは2003/1/5/4のような場合にバッファオーバーランを引き起こします。 > diffTime = (time_t)difftime(nowTime,bthTime); > tmRsltTime = gmtime(&diffTime); > ret = tmRsltTime->tm_year - 70 + fix; 現状のVC++では実行できますが,将来実行できるとは限りませんよ。 time_tが1970年1月1日起点というのはあくまで現在のVC++での話です。 将来にわたってその日が起点であるとは限りませんし, 他の処理系においても同じ起点である保証はありません。 time_tの内部表現などという処理系依存項目に頼らず, 自分で日付を演算するのが,正しくかつ確実に年齢を計算する唯一の方法です。 エラー処理をほとんど端折っていますが, int age (const char * str) { int d0, d1, m0, m1, y0, y1; struct tm * today; time_t t; if (sscanf(str, "%u/%u/%u", &y1, &m1, &d1) != 3) return -1; time(&t); today = localtime(&t); y0 = today->tm_year + 1900; m0 = today->tm_mon + 1; d0 = today->tm_mday; if (d0 < d1) m0--; if (m0 < m1) y0--; return y0 - y1; } で実行当日の年齢を得ることができます。
←解決時は質問者本人がここをチェックしてください。
戻る
掲示板システム
Copyright 2020 Takeshi Okamoto All Rights Reserved.