fgets 的循环退出条件不起作用

Loop exit condition on fgets doesn't work

我有一个这样的文本文件

"input"
height : 227
width : 227
depth : 3

"conv"
num_output : 96
pad : 0
kernel_size : 11
stride : 4
group : 1

"relu"

"pool"
kernel_size : 3
stride : 2

我正在循环阅读(这是部分代码)

char line[100];

while ((fgets(line, sizeof(line), filePtr))) {
    if (line[0] != "\n") {
        sscanf(line, "%15s : %15s", tmpstr1, tmpstr2);
        printf("%s\n",  tmpstr2);
        printf("line = %s", line);
    } else
        break;
}

但我观察到if条件总是成立,输出如下

"input"
227
line = height : 227
227
line = width : 227
3
line = depth : 3
3
line = 
3
line = "conv"
96
line = num_output : 96
0
line = pad : 0
11
line = kernel_size : 11
4
line = stride : 4
1
line = group : 1
1
line = 
1
line = "relu"
1
line = 
1
line = "pool"
3
line = kernel_size : 3
2
line = stride : 2

我也尝试过与 [=14=] 进行比较,但结果没有改变。请指出我哪里出错了。

P.S。 : 我正在使用 Ubuntu 16.04 64 位机器和 gcc 5.2.1。

换行符是字符,不是字符串,所以改成:

line[0] != "\n"

对此:

line[0] != '\n'

启用编译器警告(GCC 中的 -Wall 标志),您应该会看到如下内容:

warning: comparison between pointer and integer
warning: comparison with string literal results in unspecified behavior [-Waddress]

您正在尝试将字符串文字与 char 进行比较。

有:

if(line[0] != '\n')

效果很好。

如果您正在读取以文本模式(包括 stdin)打开的文件,那么底层系统用于标记行尾的任何表示都将被转换为单个 '\ n' 个字符。

您应该打开编译器警告。 gcc-pedantic -Werror.

this site 上我们可以看到 fgets 没有改变 str 的值(在你的例子中是行)。因为该值没有改变,所以您的 if 测试一直被评估为 true。

如果要检查 fgets 是否找到文件末尾,则必须检查 fgets 是否返回 NULL。

您正在将字符与字符串进行比较:line[0] != "\n" 应该会产生警告。要检测空行,请改用它:

line[0] != '\n'

请注意,您还应验证 sscanf() 的 return 值:

char line[100];

while (fgets(line, sizeof(line), filePtr) && *line != '\n') {
    if (sscanf(line, "%15s : %15s", tmpstr1, tmpstr2) == 2) {
        printf("%s\n",  tmpstr2);
        printf("line = %s", line);
    } else {
        printf("invalid format: %s", line);
    }
}