我寫了一個很簡單的測驗代碼來測驗vsnprintf,但是在xcode和visual studio環境下,結果卻大不相同。測驗代碼如下:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string.h>
#include <cstdarg>
void p(const char* fmt, ...)
{
static const int DefaultLength = 256;
char defaultBuf[DefaultLength] = { 0 };
va_list args;
va_start(args, fmt);
vsprintf(defaultBuf, fmt, args);
printf("%s\n", defaultBuf);
memset(defaultBuf, 0, sizeof(defaultBuf));
vsnprintf(defaultBuf, DefaultLength, fmt, args);
printf("%s\n", defaultBuf);
va_end(args);
}
int main(int argc, const char* argv[])
{
// if you uncomment this line(std::cout ...), it will crash at vsnprintf in xcode
std::cout << "Tests...!\n";
p("Create:%s(%d)", "I'm A String", 0x16);
return 0;
}
這是視覺作業室的輸出:
Tests...!
Create:I'm A String(22)
Create:I'm A String(22)
這是正常的,似乎不是問題。但是同樣的代碼,我創建了一個macos命令列專案,把這段代碼粘貼進去,奇怪的事情發生了,當代碼執行到vsnprintf時,會直接啟動EXC_BAD_ACCESS。
更離譜的是,如果我在main函式中注釋掉std::cout,它不會崩潰,但是輸出是錯誤的。那么問題來了,造成這種差異的原因是什么,這些函式不應該都是C標準庫的函式,它們的行為應該受到標準庫的約束嗎?還是我的用法不對?當我洗掉 std::cout 時的輸出:
Create:I'm A String(22)
Create:\310\366\357\277\367(3112398)
Program ended with exit code: 0

如果只有一個是對的,是xcode對還是visual studio對,最后我用的是最新的xcode 14,visual studio 2022。
uj5u.com熱心網友回復:
您必須重新初始化對 的va_list呼叫之間vsprintf。不這樣做是未定義的行為。
請參閱https://en.cppreference.com/w/c/variadic/va_list:
如果一個
va_list實體被創建,傳遞給另一個函式,并在該函式中通過 va_arg 使用,那么在呼叫函式中的任何后續使用都應該在呼叫va_end.
void p(const char* fmt, ...)
{
static const int DefaultLength = 256;
char defaultBuf[DefaultLength] = { 0 };
va_list args;
va_start(args, fmt);
vsprintf(defaultBuf, fmt, args);
va_end(args);
printf("%s\n", defaultBuf);
memset(defaultBuf, 0, sizeof(defaultBuf));
va_start(args, fmt);
vsnprintf(defaultBuf, DefaultLength, fmt, args);
va_end(args);
printf("%s\n", defaultBuf);
}
uj5u.com熱心網友回復:
void p(const char* fmt, ...)
{
static const int DefaultLength = 256;
char defaultBuf[DefaultLength] = { 0 };
va_list args;
va_start(args, fmt);
va_list args_r;
va_copy(args_r, args);
vsprintf(defaultBuf, fmt, args);
printf("%s\n", defaultBuf);
memset(defaultBuf, 0, sizeof(defaultBuf));
vsnprintf(defaultBuf, DefaultLength, fmt, args_r);
printf("%s\n", defaultBuf);
va_end(args_r);
va_end(args);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/515095.html
標籤:C C代码视觉工作室打印
上一篇:在SSIS中將字串轉換為日期
