【问题标题】:fscanf parse settings in filefscanf 解析文件中的设置
【发布时间】:2013-08-19 15:14:25
【问题描述】:

大家好 我有一个简单的问题..

如何让 fscanf 读取整个文件?

假设我有文件 settings.txt

setting1 = 1
setting2 = 2
setting3 = 3

如何将它们解析为 C 编程变量?

int setting1, setting2,setting3;

我尝试这样做很简单:

fscanf(fp, "setting2 = %d\n", &setting2);

但它无法从文件中获取 thw 值,但这是可行的:

fscanf(fp, "setting1 = %d\n", &setting1);

是否有读取整个文件的正确方法?

【问题讨论】:

    标签: c file-handling scanf


    【解决方案1】:

    如何使用fgets() 读取每一行并使用sscanf() 解析其内容,如下例所示: https://stackoverflow.com/a/861822/1150918 ? :)

    另外,对于这种配置,我个人更喜欢 Lua 或类似的小而简单的东西。内置语法检查、C API 和小型解释器。

    【讨论】:

    • 谢谢,但是 fgets 的问题是你必须指定包含它的变量的大小,我不知道它会有多大.. 设置可能真的很长数字。
    【解决方案2】:

    首先fscanf() 没有任何问题。您应该知道的第一件事是 fscanf 将换行符视为空格。因此,即使您将文件视为单独的行,fscanf 也会将其视为:

      setting1 = 1  setting2 = 2  setting3 = 3
    

    这不是问题,但它确实会影响您编写 fscanf 代码来读取此文本字符串的方式。下一个简单的方法太简单了?!

      fscanf(fp, " setting1 = %d", &setting1);
      fscanf(fp, " setting2 = %d", &setting2);
      fscanf(fp, " setting3 = %d", &setting3);
    

    注意。 fscanf 的格式有一个前导空格。这样扫描仪就不能找到任何、一个或多个空白字符。如果文本文件的行有前导空格,则不会找到匹配项,除非该前导空格符合格式。这很有意义,因为一行的开头可能有几个空格。

    当 fscanf 编码正确时,使用 read 和 append 打开文件也可以。

    让这个工作。现在,该文件是否有比三个设置更多的内容?如果是这样,那么您的 fscanf 代码可能必须更复杂,但也许不是。记住这个想法是读取数据,如果你的代码读取了数据,那么你就完成了。

    只是为了好玩,我尝试了以下 fscanfs:

    fscanf(fp, " setting1 = %i ", &setting1);
    fscanf(fp, "setting2 = %i ", &setting2);
    fscanf(fp, "setting3 = %i", &setting3); 
    

    请注意,“格式定义中奇怪放置的空格允许每个关键字之间有一个或多个空格。

    还有最后一条评论。您的代码应该考虑到用户可能拼错了关键字,在这种情况下 fscanf 会失败。因此,始终存储或测试 fscanf 的返回值:

       int x;
    
       x = fscanf(fp, " setting1 = %d", &setting1);
    
       if (x == 0) { // keyword setting1 was misspelled...
    

    对于当天的琐事:

      x = fscanf(fp, " s e t t i n g 1 = %d", &setting1);  // also works
    

    【讨论】:

    • 我认为这会解决它,但它仍然只读取第一行.. 我什至尝试了 siplier 测试,用 "Jake%d" 扫描 "Jake123" 并能够得到 "123" .然后,我在“Jake”所在的前一行添加了“asd”。(这使得“Jake”在第二行中)。当我跑的时候,它再也找不到它了。 :\
    • 我用一个字符串做了另一个测试。我在 settings.txt 中有“JakeSold”(第一行,只有一行),然后用“Jake%s”扫描它可以得到“Sold”但是当我在“Jake”和“Sold”之间添加空格时,这使得它“杰克出售”。它不再显示“已售出”。如何使它包含空格?因为 fscanf 停在空格上,我不明白为什么..
    • 我目前正在打开带有“a+”fopen 标志的文件。在读取和附加模式下.. 这有关系吗?
    • @user2128576,基本上,我认为它会。追加模式将文件 ptr 放在文件末尾。试试看,然后告诉我。
    【解决方案3】:

    你想要这样的东西:

    int setting[3], i;
    for(i = 0; i < 3; ++i)
        fscanf(fp, "setting%*d = %d\n", &setting[i]);
    

    【讨论】:

      【解决方案4】:
      char line[1024];
      int setting[N],i = 0;
      while(fgets(fp,line,1024) != NULL)
      {
           fscanf(line,"setting%*d = %d",&setting[i++]);
      } 
      

      【讨论】:

        【解决方案5】:

        最佳方法是将文件 I/O 与解析分开,并处理它们各自的潜在错误。 IOW:避免fscanf()

        void Parse(FILE *fp, int NN) {
          char buf[100];
          int setting[NN];
          int i;
          for (i = 0; i < NN; i++) {
            if (fgets(buf, sizeof(buf), fp) == NULL ) {
              ;  // Handle unexpected I/O error
            }
            int n, count;
            unsigned u;
            count = sscanf(buf, "setting%u = %d", &u, &n);
            // Qualify the parse
            if ((count != 2) && (u <= 0) && (u > NN)) {
              ;  // Handle parse I/O error
            }
            setting[u - 1] = n;
          }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-09-02
          • 2023-04-01
          • 1970-01-01
          • 1970-01-01
          • 2021-06-21
          相关资源
          最近更新 更多