传递 va_list 导致无效数据
passing va_list around results in invalid data
我发现了几个关于此的问题,但其中 none 帮助我完成了这项工作。
我有以下内容。
struct general_calibration_t {
double pressure_span;
double pressure_offset;
double steam_temperature_offset;
};
struct general_t {
struct general_calibration_t calibration;
};
int generateGenericJSON(string* str, const char* json, ...) {
char* tmp = (char*)malloc(2048);
if (tmp == NULL)
goto fail;
va_list ap;
va_start(ap, json);
const int amount = snprintf(tmp, 2048, json, ap);
va_end(ap);
if (amount >= 2048 || amount < 0)
goto release;
string_new_value(str, tmp, amount);
free(tmp);
return 0;
release:
free(tmp);
fail:
return 1;
}
调用如下:
struct general_t data;
data.calibration.pressure_offset = 1.0;
data.calibration.pressure_span = 34.8;
data.calibration.steam_temperature_offset = 20.0;
string calibrationStr;
generateGenericJSON(&calibrationStr,
"\"Calibration\":{\"PressureSpan\":%.3f,\"PressureOffset\":%.3f,\"SteamTemperatureOffset\":%.3f}",
data.calibration.pressure_span,
data.calibration.pressure_offset,
data.calibration.steam_temperature_offset);
我的输出如下:
"Calibration":{"PressureSpan":0.000,"PressureOffset":0.000,"SteamTemperatureOffset":-92559631349317830736831783200707727132248687965119994463780864.000}
将 va_list
传递给 snprintf
时出现错误。如果我使用 va_arg
遍历函数 generateGenericJSON
中的列表,则数据是正确的。我尝试将 va_list
作为指针传递,但我得到了相同的无效数据。
将此 va_list
传递给 snprintf
我做错了什么?
What am I doing wrong in passing this va_list to snprintf?
您想使用 vsnprintf()
而不是 snprintf()
。
跟进 dash-o 的 :尽量避免(出现)意大利面条代码。
处理 success/failure 不同情况的可能方法是:
int generateGenericJSON(string* str, const char* json, ...) {
int result = 0; /* Be optimistic. */
do { /* One time "loop" */
char* tmp = malloc(2048); /* No need to cast malloc() and friends in C. */
if (tmp == NULL) {
result = -1; /* By convention -1 indicates failure. */
break;
}
va_list ap;
va_start(ap, json);
const int amount = vsnprintf(tmp, 2048, json, ap);
va_end(ap);
if (amount >= 2048 || amount < 0) {
result = -1;
break;
}
string_new_value(str, tmp, amount);
} while (0);
free(tmp); /* Passing NULL to free is fine. */
return result;
}
我发现了几个关于此的问题,但其中 none 帮助我完成了这项工作。 我有以下内容。
struct general_calibration_t {
double pressure_span;
double pressure_offset;
double steam_temperature_offset;
};
struct general_t {
struct general_calibration_t calibration;
};
int generateGenericJSON(string* str, const char* json, ...) {
char* tmp = (char*)malloc(2048);
if (tmp == NULL)
goto fail;
va_list ap;
va_start(ap, json);
const int amount = snprintf(tmp, 2048, json, ap);
va_end(ap);
if (amount >= 2048 || amount < 0)
goto release;
string_new_value(str, tmp, amount);
free(tmp);
return 0;
release:
free(tmp);
fail:
return 1;
}
调用如下:
struct general_t data;
data.calibration.pressure_offset = 1.0;
data.calibration.pressure_span = 34.8;
data.calibration.steam_temperature_offset = 20.0;
string calibrationStr;
generateGenericJSON(&calibrationStr,
"\"Calibration\":{\"PressureSpan\":%.3f,\"PressureOffset\":%.3f,\"SteamTemperatureOffset\":%.3f}",
data.calibration.pressure_span,
data.calibration.pressure_offset,
data.calibration.steam_temperature_offset);
我的输出如下:
"Calibration":{"PressureSpan":0.000,"PressureOffset":0.000,"SteamTemperatureOffset":-92559631349317830736831783200707727132248687965119994463780864.000}
将 va_list
传递给 snprintf
时出现错误。如果我使用 va_arg
遍历函数 generateGenericJSON
中的列表,则数据是正确的。我尝试将 va_list
作为指针传递,但我得到了相同的无效数据。
将此 va_list
传递给 snprintf
我做错了什么?
What am I doing wrong in passing this va_list to snprintf?
您想使用 vsnprintf()
而不是 snprintf()
。
跟进 dash-o 的
处理 success/failure 不同情况的可能方法是:
int generateGenericJSON(string* str, const char* json, ...) {
int result = 0; /* Be optimistic. */
do { /* One time "loop" */
char* tmp = malloc(2048); /* No need to cast malloc() and friends in C. */
if (tmp == NULL) {
result = -1; /* By convention -1 indicates failure. */
break;
}
va_list ap;
va_start(ap, json);
const int amount = vsnprintf(tmp, 2048, json, ap);
va_end(ap);
if (amount >= 2048 || amount < 0) {
result = -1;
break;
}
string_new_value(str, tmp, amount);
} while (0);
free(tmp); /* Passing NULL to free is fine. */
return result;
}