fscanf / fscanf_s的行为差异

时间:2010-06-24 18:31:14

标签: c++ visual-c++ visual-studio-2005 crt

我对以下行为上的不同感到困惑:

// suppose myfile.txt contains a single line with the single character 's'
    errno_t res;
    FILE* fp;
    char cmd[81];

    res = fopen_s(&fp, "D:\\myfile.txt", "rb" );
    fscanf(fp,"%80s",cmd); // cmd now contains 's/0'
    fclose(fp);

    res = fopen_s(&fp, "D:\\myfile.txt", "rb" );
    fscanf_s(fp,"%80s",cmd); // cmd now contains '/0' !
    fclose(fp);

结果不依赖于调用顺序(即,首先调用fscanf_s,首先获取空字符串)。编译VC ++ - VS2005。有人可以复制吗?谁能解释一下?

谢谢!

3 个答案:

答案 0 :(得分:8)

来自fscanf_s()http://msdn.microsoft.com/en-us/library/6ybhk9kc.aspx上的文档:

  

安全函数(带_s后缀)和旧函数之间的主要区别在于安全函数需要每个c,C,s,S的大小和[type字段作为参数紧接在变量。有关更多信息,请参阅scanf_s,_scanf_s_l,wscanf_s,_wscanf_s_l和scanf Width Specification。

http://msdn.microsoft.com/en-us/library/w40768et.aspx

  

与scanf和wscanf不同,scanf_s和wscanf_s要求为所有类型为c,C,s,S或[的输入参数指定缓冲区大小。缓冲区大小在指向缓冲区或变量的指针后立即作为附加参数传递。例如,如果读取字符串,则该字符串的缓冲区大小将按如下方式传递:

     

char s [10];

     

scanf(“%9s”,s,10);

所以你应该这样称呼它:

fscanf_s(fp,"%80s",cmd, sizeof(cmd));

答案 1 :(得分:6)

fscanf_s(以及整个scanf_s系列)要求您传递任何%c%C%s%S的大小,或缓冲区本身后的%[;你忽略了这个论点:

fscanf_s(fp, "%80s", cmd, 81);

答案 2 :(得分:2)

你的问题是用C ++标记的,你是用VC ++编译的,但是使用fscanf?获取std :: ifstream。

std::string buffer;
std::ifstream fp("my filepath");
fp >> buffer;