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

时间:2017-08-15 19:42:05

标签: c string loops fgets

我有一个像这样的文本文件

"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

我也试过与\0进行比较,但结果并没有改变。请指出我出错的地方。

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

4 个答案:

答案 0 :(得分:5)

换行符是一个字符,而不是字符串,所以请更改:

line[0] != "\n"

到此:

line[0] != '\n'

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

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

答案 1 :(得分:4)

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

使用:

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

效果很好。

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

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

答案 2 :(得分:0)

this site上我们可以看到fgets不会改变str的值(在你的情况下为line)。由于该值不会更改,因此if测试将继续评估为true。

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

答案 3 :(得分:0)

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

line[0] != '\n'

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

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);
    }
}