关于sprintf和snprintf格式化字符串输出到字符串缓冲区


    都知道,sprintf,snprintf是printf函数族的一员,只是它的输出对象是一个字符串缓冲区,而不是stdout或者文件。所以sprintf,snprintf很适合用来生成自己的格式化参数,易于解析。但是要注意的是关于字符串结束的问题,假设有这样的程序
#include<....>
int main(int argc,char *argv[]){
    int len;
    int i=1;
    char buffer[128];
    while(i<argc){
        len=strlen(argv[i]);
        if(len>=128)
            exit(1);
        snprintf(buffer,len,"%s",argv[i]);
        i++;
    }
    printf("%s",buffer);
    fflush(stdout);
    return 0;
}
上面这个程序正确吗?能使用printf函数输出buffer字符串吗?
显然,程序是正确的,但是运行的结果是:不能输出字符串buffer!
使用gdb调试,假设,传递一个参数“hello",在gdb中查看len的值为5,正确,查看snprintf执行后,buffer的内容为"hell/000/000..."。证么回事?少了一个o,而且有正确的字符串结束符'/0'。-----这是问题1
    修改上面的snprintf语句为:
snprintf(buffer,len+1,"%s",argv[i]);

    然后使用gdb调试,可以看到buffer的内容为"hello/000/000..."

关于sprintf和snprintf格式化字符串输出到字符串缓冲区_第1张图片

内容正确了,但是为什么printf("%s/n",buffer)依然不能输出?----问题2
    然后将snprintf修改为:
snprintf(buffer,len+1,"%s/n",argv[i]);
    使用gdb调试,可以看到buffer的内容为"hello/000/000...",和上面的一样,但是同样不能打印出字符串buffer!----------问题3
    然后将snprintf修改为:
snprintf(buffer,len+2,"%s/n",argv[i]);
    运行程序,发现可以打印出字符串buffer了,使用gdb调试

关于sprintf和snprintf格式化字符串输出到字符串缓冲区_第2张图片

发现buffer的内容为"hello/n/000/000...",---------问题4
    现在来分析一下上面的几个问题:首先为什么snprintf将格式化字符串输出到buffer时,会少掉最后一个字符(问题1,2,3),查看snprintf的manpage可以看到

size的大小其实是包含了最后一个字符结束符的大小,所以输出时会输出字符串的前size-1个字符,然后加上一个字符串结束符'/0'。那么问题4是:为什么字符串没有'/n'符号就不能打印出来呢?这个没道理啊。其实是终端显示的问题,如果最后一行不换行的话,将会和PS1(命令提示符)混合,根本就看不到输出的效果,你可以使用如下最简单的语句来测试:
printf("hello");

你可能感兴趣的:(测试,buffer,终端)