这两天在工作中遇见一个问题,如标题所示,具体场景是我需要将用户的短信内容存储若干字节用来证明业务历史之用,内容是否能正常显示则无要求,所以我使用函数fprintf()将短信内容写入文件,测试后工作良好。模块在开始的1个月之内没什么问题,但从第二个月开始不定时的出现模块退出情况,打开core文件,第一次没发现有什么异常,只是显示fprintf()函数错误,当出现多次退出情况并查看core文件之后发现,每次退出时,向日志文件写入的内容都包含字符串“%n”。
关于“%n”
在c语言中%n的作用是将%n之前字符串的长度存放至后边地址之中,例如:
int len;
fprintf(fd,"Hello%dworld",&len);
将字符串Hello的长度5存放于len之中,并将字符串输出到文件,但是当我们不提供输出地址的时候,由于没有合法的地址,就会出现段错误。反观之前我储存短信内容的时候则是使用函数:
fprintf(fd,MsgContent);
因此就出现了用户发送一个GBK编码含%n的短信,就让模块退出的荒诞事情,!!
总结:
1、对%n格式基础知识上还有盲区。
2、如果需要将%n以字符串输出,而不是使用它的格式化功能,则因该:
fprintf(fd,"%s",Str);//不管Str中含有什么字符,都将安全输出
fprintf(fd,Str);//存在安全隐患,除非你能确保Str的内容在你的掌握之内
3、类printf函数都会有这种隐患,如:printf, fprintf, sprintf, snprintf, vprintf,
vfprintf,vsprintf, vsnprintf