现在我正在使用 sprintf
,但想更改为 snprintf
。
我的问题是,当我使用指针执行以下代码之类的操作时,确保不发生缓冲区溢出的最佳方法是什么:
这是代码的快速示例,在我的代码中,string_pos += get_line_to_buffer(&string[string_pos]);
被多次调用。所以我要向缓冲区添加大量数据,因此我想确保我不会写入太多数据。
int main(void){
char string[50];
size_t string_pos = 0;
string_pos += get_line_to_buffer(&string[string_pos]);
}
static size_t get_line_to_buffer(char *buffer){
char* p = buffer;
p += sprintf(p, "%d,%s,%s,%lu", version, fileName, Id, timestamp);
p += sprintf(p, ",%d,%d,%f", noOfObs, frequency, sum);
p += sprintf(p, ",%f,%f", latitude, longitude);
p += sprintf(p, ",%f,%d", speed, errorCode);
p += sprintf(p, "\r\n");
return p - buffer;
}
最佳答案
仔细阅读documentation of snprintf
(和/或 Linux 的 snprintf(3) )。请注意,它可能会因返回负值而失败。您可能会对它的 %n
感兴趣。
您需要知道缓冲区的大小。一个好方法是将其作为第二个参数传递给 get_line_to_buffer
函数:
ssize_t get_line_to_buffer(char *buffer, size_t siz) {
char* p = buffer;
char* start = buffer;
char* end = buffer + siz;
int n = 0;
if (p < end)
n = snprintf(p, siz, "%d, %s, %s, %lu", version, fileName, Id, timestamp);
else
n = snprintf(NULL, 0, "%d, %s, %s, %lu", version, fileName, Id, timestamp);
if (n<0) return -1;
p += n, siz -= n;
if (siz<0) return -1;
if (p < end)
n = snprintf(p, siz, ",%d,%d,%f", noOfObs, frequency, sum);
else
n = snprintf(NULL, 0, ",%d,%d,%f", noOfObs, frequency, sum);
if (n<0) return -1;
p += n; siz -= n;
return p - start;
}
其实,你可以考虑使用 asprintf(3)如果您的系统有的话。
您也可以使用 fmemopen(3) 打开内存中的流。或open_memstream(3)并对其使用fprintf
。
顺便说一句,您可以简单地执行一个 snprintf
但将其格式控制字符串拆分为多个物理行:
int n = snprintf(p, siz,
"%d, %s, %s, %lu"
",%d,%d,%f",
version, fileName, Id, timestamp,
noOfObs, frequency, sum);
关于c - 使用指向 char 的指针时如何使用 snprintf,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52039290/