Strtok - 在行尾读取空字符串

时间:2013-02-07 15:59:13

标签: c strtok

在下面的代码中,我使用strtok从一个看起来像这样的文件中解析一行代码:

1023.89,863.19  1001.05,861.94  996.44,945.67   1019.28,946.92  1023.89,863.19

由于文件可以有不同长度的行,我不使用fscanf。除了一个小故障外,下面的代码适用。它循环一次太多并且在循环之前读入一个长空字符串“”,再次识别空标记“”并退出while循环。我不知道为什么会这样。

非常感谢任何帮助。

fgets(line, sizeof(line), some_file);    
while ((line != OPC_NIL) {
    token = strtok(line, "\t"); //Pull the string apart into tokens using the commas
    input = op_prg_list_create();
    while (token != NULL) {
        test_token = strdup(token);
        if (op_prg_list_size(input) == 0)       
            op_prg_list_insert(input,test_token,OPC_LISTPOS_HEAD);  
        else
            op_prg_list_insert(input,test_token,OPC_LISTPOS_TAIL);
        token = strtok (NULL, "\t");
    }
    fgets(line, sizeof(line), some_file);                
}

2 个答案:

答案 0 :(得分:2)

您必须使用正确的分隔符列表。你的代码与评论相矛盾:

token = strtok(line, "\t"); //Pull the string apart into tokens using the commas

如果您想用逗号分隔代币,请使用","代替"\t"。此外,您当然不希望令牌包含换行符\n(出现在fgets从文件读取的每一行的末尾)。因此,将换行符添加到分隔符列表中:

token = strtok(line, ",\n"); //Pull the string apart into tokens using the commas
...
token = strtok (NULL, ",\n");

您可能还想将空格字符添加到分隔符列表中(863.19 1001.05是一个令牌还是两个令牌?是否要删除行尾的空格?)。

答案 1 :(得分:0)

您对sizeof(line)的使用告诉我line是一个固定大小的数组,存在于堆栈中。在这种情况下,(line != OPC_NIL)永远不会是false。但是,当到达文件末尾或发生其他错误时,fgets()将返回NULL。你的外部while循环应该重写为:

while(fgets(line, sizeof(line), some_file)) {
...
}

您的输入文件可能还会在最后一个输入行的末尾添加换行符,从而在结尾处生成一个空行。这就是:

之间的区别
1023.89,863.19 1001.05,861.94 996.44,945.67 1019.28,946.92 1023.89,863.19↵
<blank line>

和此:

1023.89,863.19 1001.05,861.94 996.44,945.67 1019.28,946.92 1023.89,863.19

你应该在while循环中做的第一件事是检查字符串是否实际上是你期望的格式。如果不是那么休息:

while(fgets(line, sizeof(line), some_file)) {
    if(strlen(line) == 0) // or other checks such as "contains tab characters"
        break;
    ...
}