我有一个包含以下内容的文本文件:
"abc","def","ghi"
以下内容适用于正确读取文件内容:
int main()
{
char name[1024] = {0};
FILE *file = fopen("file.txt", "r");
while(1)
{
if (fscanf(file, " %[\",]s ", name) == EOF)
break;
if (fscanf(file, " %[a-zA-Z]s ", name) == EOF)
break;
printf("%s\n", name);
}
return 0;
}
然而,以下失败:
int main()
{
char name[1024] = {0}, garbage[5];
FILE *file = fopen("file.txt", "r");
while(1)
{
if (fscanf(file, " %[\",]s%[a-zA-Z]s ", garbage, name) == EOF)
break;
printf("%s\n", name);
}
return 0;
}
我正在使用MSVC ++ 08.我错过了什么?我正在寻找fscanf()
循环中单while
的解决方案。
答案 0 :(得分:7)
它的工作原理???纯粹的坏运气: - )
您的转换规范意味着
" %[\",]s "
^= optionally skip whitespace
^== read a literal 's'
^^^^^^=== read an unlimited string of quotes and commas
^========= optionally skip whitespace
和
" %[a-zA-Z]s "
^= optionally skip whitespace
^== read a literal 's'
^^^^^^^^^=== read an unlimited string of letters
^============ optionally skip whitespace
和
" %[\",]s%[a-zA-Z]s "
^= optionally skip whitespace
^== read a literal 's'
^^^^^^^^^=== read an unlimited string of letters
^============ read a literal 's'
^^^^^^============= read an unlimited string of quotes and commas
^=================== optionally skip whitespace
我想你想要
" %4[\",]%1023[a-zA-Z] "
^= optionally skip whitespace
^^^^^^^^^^^^^== read a string of at most 1023 letters
^^^^^^^=============== read a string of at most 4 quotes and commas
^====================== optionally skip whitespace
除此之外,scanf
会在出错时返回成功转化次数或EOF。您应该将结果值与EOF进行比较,以便与1(或2或其他)进行比较:与您期望的转化次数进行比较。
if (scanf() == 3) /* expected 3 conversions */
{ /* ok */ }
else { /* oops, something went wrong */ }
答案 1 :(得分:4)
%[a-zA-Z]s
表示“匹配任意数量的字母字符并分配给name
,然后匹配文字s
。删除s
个字符。%*[\",]
。EOF
。这意味着当文件指针位于i
之后时,您将获得错误的循环。考虑测试分配的指定符的数量,或者在末尾测试另一个"%*[\"]"
以覆盖尾随的引号。这也是第一个版本有效的原因。文字s
无法匹配,但第一次转换成功,因此您获得name
但不是EOF
。
if (fscanf(file, " %*[\",]%[a-zA-Z] ", name) < 1)
break;
或
fscanf(file, " %*[\",]%[a-zA-Z]%*[\"] ", name)
答案 2 :(得分:2)
删除“s”转换标志,如:
if (fscanf(file, " %[\",]%[a-zA-Z] ", garbage, name) < 2)
请注意,我必须比较2而不是EOF,因为最后一个引号会在下一次迭代时被读入。
编辑:我很惊讶您的第一个代码示例也有效,但在Mac OS X上使用gcc时运行得很好,所以这不是Microsoft特有的问题。
答案 3 :(得分:0)
以下内容应该有效:
if (fscanf(file, " %[\",]%[a-zA-Z] ", garbage, name) == EOF)
break;