1

在下面的代码中,我使用 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);                
}
4

2 回答 2

2

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

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

如果您想用逗号分隔标记,请使用","而不是"\t". 此外,您当然不希望标记包含换行符\n(出现在从 file by 读取的每一行的末尾fgets)。因此,将换行符添加到分隔符列表中:

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

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

于 2013-02-07T16:25:06.877 回答
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;
    ...
}
于 2013-02-07T16:47:09.050 回答