使用fscanf_s时出现访问冲突错误

4

我想以特定格式读取文件,因此我使用fscanf_s和while循环。但是一旦处理fscanf_s,程序就会崩溃并出现访问冲突(0xC0000005)。

以下是代码:

FILE *fp;
errno_t err = fopen_s(&fp, "C:\\data.txt", "r");

if (err != 0)
    return 0;

int minSpeed = 0;
int maxSpeed = 0;
char axis = '@';

while(!feof(fp)) 
{
    int result = fscanf_s(fp, "%c;%d-%d\n", &axis, &minSpeed, &maxSpeed);

    if (result != 3)
        continue;
}

fclose(fp);

文件的内容是基于行的,例如:
-;10000-20000
X;500-1000
S;2000-2400

有人能帮我吗?


1
什么?没有feof_s()或者fclose_s()?真的吗?*_s函数比普通命名的函数更糟糕:它们需要相同的检查,让你感觉安全,但实际上并不是这样。我建议你不要使用它们,因为会产生虚假的安全感,并且在许多实现中都不可用,使得你的程序只能在可能机器的有限子集上运行。 - pmg
@pmg 我没有使用feof_s和fclose_s,因为它们没有被定义。但是从fscanf_s中删除那个_s就解决了问题。现在它可以工作了! :-) 谢谢! - Hubert Korn
是的,当我尝试了一个小测试程序时,我遇到了同样的问题。这些函数真是奇怪! - Robinson
3
feof_s()fclose_s()只是一个玩笑(哈哈);显然,正确的fscanf_s()调用应该是 fscanf_s(fp, "%c;%d-%d\n", &axis, 1, &minSpeed, &maxSpeed);,额外的1是为了axis数组的大小。不要使用*_s函数! - pmg
@pmg:你应该把那个作为答案 :) - user7116
2个回答

9

显然,fscanf_s()在变量地址后需要一个大小参数

fscanf_s(fp, "%c;%d-%d\n", &axis, 1, &minSpeed, &maxSpeed);
/* extra 1 for the size of the   ^^^ axis array */

但我建议您不要使用*_s函数:它们比明确命名的函数更差 - 它们需要相同的检查并使您感到安全,而实际上并非如此。由于虚假的安全感以及许多实现中不可用,我建议您不要使用它们,这会使您的程序仅适用于可能机器的有限子集。

请使用普通的fscanf()函数。

fscanf(fp, "%c;%d-%d\n", &axis, &minSpeed, &maxSpeed);
/* fscanf(fp, "%1c;%d-%d\n", &axis, &minSpeed, &maxSpeed); */
/* default 1   ^^^    same as for fscanf_s                 */

你使用 feof() 是错误的。
当出现错误(包括文件结束、匹配失败或读取错误等)时,fscanf() 将返回 EOF。

你可以使用 feof() 来确定为什么 fscanf() 失败,而不是检查下一次调用它是否会失败。

/* pseudo-code */
while (1) {
    chk = fscanf();
    if (chk == EOF) break;
    if (chk < NUMBER_OF_EXPECTED_CONVERSIONS) {
        /* ... conversion failures */
    } else {
        /* ... all ok */
    }
}
if (feof()) /* failed because end-of-file reached */;
if (ferror()) /* failed because of stream error */;

0

如果您认为文件(data.txt)存在,则您的应用程序可能没有在设置文件所在的当前目录下运行。这将导致fopen_s()失败。


没错,但是fopen_s成功了,我在Visual Studio调试器中检查过了。 - Hubert Korn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接