0

別のロギング関数の時間を返す必要がある関数があり、次のようになります。

//put time in to buf, format 00:00:00\0
void gettimestr(char buf[9]) {
  if(strlen(buf) != 9) { //experimental error checking
    fprintf(stderr, "Buf appears to be %d bytes and not 9!\n", strlen( buf ));
  }
  time_t cur_time;
  time(&cur_time);
  struct tm *ts = localtime(&cur_time);
  sprintf(buf, "%02d:%02d:%02d",
        ts->tm_hour,
        ts->tm_min,
        ts->tm_sec );
  strncat(buf, "\0", 1);
}

ここでの主な問題は、バッファが十分に長いかどうかを確認することだと思います。sizeof()はポインタサイズを返し、strlenは2つの異なる呼び出しでランダムに0または12などを返すようです。

私の最初の質問は、バッファのサイズを安全に検出するにはどうすればよいですか、それは可能ですか?

私の他の質問は、buf [9]を受け入れるのが好ましいメソッドですか、それともバッファーへのポインターを受け入れ、sprintf()の代わりにstrcat()を使用して時間を追加する必要がありますか?sprintfを使用すると、時間値にゼロを簡単に埋めることができますが、ポインタは受け入れず、文字配列のみを受け入れるようです。

4

2 に答える 2

4

この関数は、渡されるバッファーに9文字のnullで終了する文字列がすでに含まれていることを前提としています。それは意味がありません。

適切な方法は、引数としてサイズを要求することです。

void gettimestr(char *buf, int bufferSize) {

snprintfを使用します。

snprintf(buf, bufferSize, "%02dx....", ....);<sub>*</sub>

制限を超えた場合、snprintfはそれを実行しないため、文字列を終了します。

buf[bufferSize-1] = 0;

次のように関数を呼び出すことができます。

char buffer[16];
gettimestr(buffer, sizeof(buffer));

サイズを決定する他の方法はありません。これは、配列がそのサイズを知っているJavaではありません。aを渡すchar *と、それ以上の情報なしで関数へのポインタが送信されるだけなので、バッファのサイズを取得する唯一の方法は、呼び出し元にそれを指定するように要求することです。

(編集:コメントで指摘されているように、snprintfは常に文字列を適切に終了する必要があります。)

于 2011-03-22T01:30:18.550 に答える
0

@EboMikeは正しいです。彼の答えを補足するために、次のようにバッファをチェックできます。

void gettimestr(char *buf, int bufferSize) {
    if (!buf) {
        fprintf(stderr, "Null buffer\n");
        return;
    }

 // rest of the code

 }
于 2011-03-22T01:35:24.523 に答える