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