【问题标题】:read semicolon separated strings from a file [duplicate]从文件中读取分号分隔的字符串[重复]
【发布时间】:2013-04-19 08:46:32
【问题描述】:

如何读“;”从c中的文件中分离字符串? 我正在使用以下方法:

char c;
c=fgetc(fp);
while(c!=EOF)
{
    int k=0;
    if(c=='\n')
    c=fgetc(fp);
    while(c!=';')
    {
        str1[k]=c;
        k++;
        c=fgetc(fp);
    }
    str1[k]='\0';
    c=fgetc(fp);
    k=0;
    while(c!=EOF && c!='\n')
    {
        str2[k]=c;
        k++;
        c=fgetc(fp);
    }
    str2[k]='\0';
    Seq(str1,str2);
    printf("\n");
    if(c==EOF)
    {
        break;
    }
    else
    c=fgetc(fp);
}

输入文件:

     Hello;world

     Male;Female

     where;who

我必须读取不同的字符串值,然后将它们传递给一个函数作为 Seq(hello,world)..等等

有更好的方法吗?

【问题讨论】:

  • 定义“更好”?更少的代码行?更高效?更具可读性?如果您的解决方案有效,为什么要修复它?
  • @ams 更易于维护? “为什么要修?” -- OP想把事情做好……为什么要气馁?
  • 我还要指出,这是有史以来编写的一些最糟糕的代码(包括未定义的行为),因此强烈建议 OP 重写它以调用库函数。

标签: c string file


【解决方案1】:

更好的方法是从文件中读取行,然后使用strchrstrpbrkstrcspnstrtoksscanf 或其他库函数来查找“;”。

【讨论】:

  • 我也在想同样的事情。一次读入内容然后使用strtok等函数进行解析似乎要容易得多。
【解决方案2】:
while (fscanf(fp, " %[^;];%s", str1, str2) == 2)
  Seq(str1, str2);

只要确保str1str2 足够大!

格式说明:

  • (空格):跳过任何空格,包括换行符。
  • %[^;] :读取一个不能包含分号的字符串。这不会跳过前导空格,因此我们必须明确地这样做(感谢@MOHAMED)。
  • ; :读取并丢弃分号。如果不存在,则匹配失败。
  • %s :读取一个字符串直到空白,所以基本上直到行尾。

fscanf 返回匹配字段的数量。我们正在寻找两个,所以如果结果是任何其他数字,则输入失败。如果您的文件格式正确,那么 feof(fd) 应该返回 true,否则匹配会提前失败。

为了正确地偏执,您还应该包括str1str2 的字段宽度,以确保不会出现缓冲区溢出。因此,如果您分配了 100 个字节,您将使用 %99[^;](留下一个字节作为零终止符)。

【讨论】:

  • 在说明符格式的开头添加空格以避免换行问题" %[^;];%s"
  • 如果第二个字符串包含空格,那么 %s 将无法捕获整个字符串,那么您必须将格式说明符更改为 " %[^;] ; %[^\n]"
  • 是的,尽管; 之前的空格是多余的。还要注意 CRLF 行尾,所以也许你想要这个:" %[^;]; %[^\r\n]"
  • 是的,这也可以
【解决方案3】:

您可以使用 " %[^;] ; %[^\n]" 作为 fscanf() 的格式说明符来执行此操作。它将读取文件直到遇到分号,那么格式说明符字符串中的分号将“吃掉”文件中该单词后面的分号。

【讨论】:

  • 我相信s 是一个错误。
  • 是的,这里的 s 是一个错误
  • @MOHAMED 那么更正是什么?请在我删除或编辑之前告诉我。
  • 使用以下格式" %[^;] ; %[^\n]"
  • @ams 请更正它。我知道它的意思是“读到你遇到一个;”。如果不是在 s 中,那么读取的内容存储在哪里?
猜你喜欢
  • 2019-05-08
  • 2017-06-06
  • 2023-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-14
  • 2015-08-11
相关资源
最近更新 更多