8

我对以下行为差异感到困惑:

// 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 上编译。任何人都可以复制吗?谁能解释一下?

谢谢!

4

3 回答 3

9

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

安全函数(带有 _s 后缀)和旧函数之间的主要区别在于,安全函数需要每个 c、C、s、S 和 [ 类型字段的大小作为紧跟变量的参数传递。有关详细信息,请参阅 scanf_s、_scanf_s_l、wscanf_s、_wscanf_s_l 和 scanf 宽度规范。

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

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

字符 [10];

scanf("%9s", s, 10);

所以你应该这样称呼它:

fscanf_s(fp,"%80s",cmd, sizeof(cmd));
于 2010-06-24T18:46:37.237 回答
6

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

fscanf_s(fp, "%80s", cmd, 81);
于 2010-06-24T18:38:38.300 回答
2

您的问题被标记为 C++ 并且您正在使用 VC++ 进行编译,但使用 fscanf?获取一个 std::ifstream。

std::string buffer;
std::ifstream fp("my filepath");
fp >> buffer;
于 2010-06-24T19:00:49.300 回答