[英]How to use snprintf when using a pointer to char
Right now I'm using sprintf
but want to change to snprintf
.现在我正在使用
sprintf
但想更改为snprintf
。
My question is, what is the best way to secure that I'm not doing a buffer overflow, when I'm doing something like the code below using pointer:我的问题是,当我使用指针执行类似以下代码的操作时,确保我不执行缓冲区溢出的最佳方法是什么:
This is a quick example of the code, in my code the string_pos += get_line_to_buffer(&string[string_pos]);
这是代码的一个快速示例,在我的代码中
string_pos += get_line_to_buffer(&string[string_pos]);
is called multiple times.被多次调用。 So I'm gonna add alot of data to the buffer and therefore I want to make sure I'm not writing too much.
所以我要向缓冲区添加大量数据,因此我想确保我不会写太多。
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;
}
Read carefully documentation of snprintf
(and/or the Linux one, snprintf(3) ).仔细阅读
snprintf
文档(和/或 Linux文档, snprintf(3) )。 Notice that it could fail by returning a negative value.请注意,它可能会因返回负值而失败。 And you could be interested by its
%n
.你可能会对它的
%n
感兴趣。
You need to know the size of the buffer.您需要知道缓冲区的大小。 A good way is to pass it as a second argument to your
get_line_to_buffer
function:一个好方法是将它作为第二个参数传递给
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;
}
Actually, you could consider using asprintf(3) if your system has it.实际上,如果您的系统有asprintf(3) ,您可以考虑使用它。
And you might instead open a in-memory stream with fmemopen(3) or open_memstream(3) and use fprintf
on it.您可以改为使用fmemopen(3)或open_memstream(3)打开内存流并在其上使用
fprintf
。
BTW, you might simply do a single snprintf
but split its format control string in several physical lines:顺便说一句,您可能只执行一个
snprintf
但将其格式控制字符串拆分为几行:
int n = snprintf(p, siz,
"%d, %s, %s, %lu"
",%d,%d,%f",
version, fileName, Id, timestamp,
noOfObs, frequency, sum);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.