关于C#:使用fscanf_s时访问冲突

Access violation while using fscanf_s

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

这是代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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\
"
, &axis, &minSpeed, &maxSpeed);

    if (result != 3)
        continue;
}

fclose(fp);

该文件的内容是基于行的,例如:

1
2
3
-;10000-20000
X;500-1000
S;2000-2400

有人可以帮我吗?


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

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

但我建议您不要使用*_s函数:它们比简单命名的函数更糟糕---它们需要进行相同的检查,并在不使用它们时使您感到安全。 我建议您不要使用它们,因为存在错误的安全感,并且它们在许多实现中都不可用,这使您的程序只能在可能的有限机器中运行。

使用普通的fscanf()

1
2
3
4
5
fscanf(fp,"%c;%d-%d\
"
, &axis, &minSpeed, &maxSpeed);
/* fscanf(fp,"%1c;%d-%d\
", &axis, &minSpeed, &maxSpeed); */

/* default 1   ^^^    same as for fscanf_s                 */

您对feof()的使用是错误的。
当出现错误(文件结尾或匹配失败或读取错误...)时,fscanf()返回EOF。

您可以使用feof()来确定fscanf()失败的原因,而不必检查它在下次调用时是否会失败。

1
2
3
4
5
6
7
8
9
10
11
12
/* 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 */;

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