[ad_1]
C言語関数 printf は非常に異なるパラメータを持っています。 …、以下のようなもの:
int printf(const char *format, ...);
これは、var_args を扱う var_list に関するものです。 ログ情報を記録するための同様の機能があります。
void LOG(const char* format,...) { va_list list; time_t t=time(NULL); tm* tp=localtime(&t); char log_spin[256]=""; char log_buffer[1024*4]=""; if(format==NULL||!LOGFILE) return; sprintf(log_spin,"[%04d-%02d-%02d %02d:%02d:%02d]", tp->tm_year+1900,tp->tm_mon+1,tp->tm_mday, tp->tm_hour,tp->tm_min,tp->tm_sec); strcpy(log_buffer,log_spin); size_t occuppied=strlen(log_buffer); size_t remain=sizeof(log_buffer)-occuppied; int count=0; va_start(list,format); count=vsnprintf(&log_buffer[strlen(log_buffer)],remain,format,list); va_end(list); if(count>=remain) sprintf(&log_buffer[sizeof(log_buffer)-5],"...\n\0"); else log_buffer[strlen(log_buffer)]='\n'; fprintf(LOGFILE,log_buffer); fflush(LOGFILE); }
このコードは、simiar 関数を使用します vsnprintf フォーマットと記録パラメータを扱います。 %2d% のような 16 進値と一緒に % を使用することで、いくつかの変換が行われます。 4f…
しかし、この LOG 関数に URL を渡すと、sh*t が発生しました。 デバッグしようとすると、例外が発生しました(MSVC)。 OK、LOG コードに問題があると思います。 Cの標準関数「printf」は対応していましたか? 同じ URL をコンソールに出力しようとしましたが、すべて OK です。 つまり、私が知らない % 文字を処理する適切な方法があるということです。 それに対する標準的な答えがあるはずです。
だから、これは私の問題です、va_list の文字 % をどう扱うか?
私が試したこと:
コードを簡素化するために、コードとテスト入力をここに貼り付けます。
int vsnprintf_test(char* format,...) { char buffer[256]={0}; va_list list; int count=0; va_start(list,format); count=vsnprintf(buffer,sizeof(buffer),format,list); va_end(list); printf(buffer); return count; }
呼び出し側:
char msg[256] = { 0 };//""; msg[0] = '%'; //the character which caused the exception msg[1] = 'A'; printf("%s\n",msg); //all ok vsnprintf_test(msg); // crashed.
このコードを修正する方法がわかりません。 関数printfは文字%をどのように処理しましたか?
解決策 1
ドキュメントを見てください: https://cplusplus.com/reference/cstdio/vsnprintf/[^] フォーマットが vnsprintf の最初のパラメータではなく、3 番目のパラメータであることがわかります。
したがって、小さな例で printf に渡す文字列は、印刷するデータですが、 vnsprintf 呼び出しでそれを印刷する形式は、認識されない印刷形式である “%A” です。 代わりに「%s」を渡すと、機能します。
LOG 関数に戻り、何を渡す必要があるか、何を行う必要があるかを検討します。「これをログに記録する」関数にフォーマットを渡すことはほとんどないため、代わりに、データを渡して実際にログに記録します…
[ad_2]
コメント