繁体   English   中英

在fscanf()中使用[]

[英]Use of [] in fscanf()

我有一个包含以下内容的文本文件:

"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.我错过了什么? 我正在寻找一个在while循环中使用单个fscanf()的解决方案。

有用??? 纯粹运气不好:-)

您的转换规格意味着

" %[\",]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。 当您应该与1(或2或其他)进行比较时,您将结果值与EOF进行比较:与您期望的转化次数进行比较。

if (scanf() == 3) /* expected 3 conversions */
{ /* ok */ }
else { /* oops, something went wrong */ }
  1. 括号是他们自己的转换说明符,而不是修饰符。 %[a-zA-Z]s表示“匹配任意数量的字母字符并分配给name ,然后匹配文字s 。删除s字符。
  2. 如果你想匹配一些但丢弃它,使用星号而不是垃圾缓冲区: %*[\\",]
  3. 如果在文件结束之前至少有一个匹配器匹配,则scanf不会返回EOF 这意味着当文件指针位于i之后时,您将获得错误的循环。 考虑测试分配的指定符的数量,或者在末尾测试另一个"%*[\\"]"以覆盖尾随的引号。

这也是第一个版本有效的原因。 文字s无法匹配,但第一次转换成功,所以你得到了name而不是EOF


if (fscanf(file, " %*[\",]%[a-zA-Z] ", name) < 1)
    break;

要么

fscanf(file, " %*[\",]%[a-zA-Z]%*[\"] ", name)

删除“s”转换标志,如下所示:

if (fscanf(file, " %[\",]%[a-zA-Z] ", garbage, name) < 2)

请注意,我必须比较2而不是EOF,因为最后一个引号将在下一次迭代时被读入。

编辑 :我很惊讶您的第一个代码示例也有效,但它在Mac OS X上使用gcc运行得很好,因此这不是Microsoft特定的问题。

以下应该有效:

      if (fscanf(file, " %[\",]%[a-zA-Z] ", garbage, name) == EOF) 
        break; 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM