【问题标题】:In C, how do I read a file, and store only the doubles - ignoring text before?在 C 中,我如何读取文件,并且只存储双打 - 之前忽略文本?
【发布时间】:2014-05-21 15:18:11
【问题描述】:

我需要读入一个包含文本的文件,然后读取该文本的双精度。只是为了得到这组数字的均值和标准差,所以前面的文字是无关紧要的。例如,我的输入文件看起来有点像:

preface 7.0000
chapter_1 9.0000
chapter_2 12.0000
chapter_3 10.0000

等等。

在这种情况下,它正在寻找一本书各章的均值和标准差。我有下面的代码部分,但我不太确定如何“忽略”文本,只抓取双打。目前这段代码打印出零,并且只有在超出数组限制时才退出循环,我在程序开始时将其设置为常量 20。

FILE *ifp;
char *mode = "r";
ifp = fopen("table.txt", mode); 

double values[array_limit];
int i;
double sample;

if (ifp==NULL)
{
  printf("cannot read file \n");
}

else
{
i = 0;

do
{
   fscanf(ifp, "%lf", &sample);  

   if (!feof(ifp))
   {
      values[i] = sample;
      printf("%.4lf \n", values[i]);
      i++;
      if (i>=array_limit)   //prevents program from trying read past array size limit//
        {
           printf("No more space\n");
           break;
        }
   }

   else
   {
              printf("read complete\n");
              printf("lines = %d\n", i);
   }

  }while (!feof(ifp));
  fclose(ifp);
}

【问题讨论】:

    标签: c file-io scanf


    【解决方案1】:

    我认为您可以使用fscanf(ifp, "%*[^ ] %lf", &sample) 来读取您的文件。 * 表示忽略该特定匹配,[] 指定要匹配的字符列表,^ 表示匹配除[] 中的字符之外的所有字符。

    或者可能(更简单一点)fscanf(ifp, "%*s %lf", &sample)

    【讨论】:

    • 非常感谢,我知道有一种方法可以忽略所有字符,但我没有意识到你可以只使用 [^]
    【解决方案2】:

    你有两个主要问题——你使用的是pretty much always wrong的feof,你没有检查fscanf的返回值,它告诉你是否有一个值(或者是否你到了eof)。

    所以你想要的是类似的东西

    while ((found = fscanf(ifp, "%lf", &values[i])) != EOF) {  /* loop until eof */
        if (found) {
            /* got a value, so count it */
            if (++i >= ARRAY_LIMIT) {
                printf("no more space\n");
                break;
            }
        } else {
            /* something other than a value on input, so skip over it */
            fscanf(ifp, "%*c%*[^-+.0-9]");
        }
    }
    

    【讨论】:

      【解决方案3】:

      从文件读入时,通常最好使用fgets一次读取一行,然后使用sscanf提取您感兴趣的部分:

      #include <stdlib.h>
      #include <stdio.h>
      
      #define ARRAY_LIMIT 10
      #define LINE_LENGTH 128
      
      int main()
      {
          double values[ARRAY_LIMIT];
          int i, count = 0;
          double sample;
      
          FILE *ifp = fopen("table.txt", "r");
          if (ifp==NULL)
          {
              printf("cannot read file \n");
              return 1;
          }
      
          char buff[LINE_LENGTH];
          while (fgets(buff, LINE_LENGTH, ifp) != NULL) 
          {
              if (sscanf(buff, "%*s %lf", &sample) != 1) break;
              values[count++] = sample;
              if (count == ARRAY_LIMIT) {
                  printf("No more space\n");
                  break;
              }
          }    
          fclose(ifp);
      
          for (i = 0; i < count; ++i) {
              printf("%d: %f\n", i, values[i]);
          }
      
          return 0;
      }
      

      fgets 如果遇到文件末尾或发生读取错误,则返回NULL。否则,它将文件的一行读入字符缓冲区buff

      sscanf 中的星号%*s 表示该行的第一部分被丢弃。第二部分写入变量sample。我正在查看sscanf的返回值,表示已经成功读取了多少个值。

      到达文件末尾或计数达到数组大小时循环中断。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-04-07
        • 1970-01-01
        • 2015-12-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-28
        • 1970-01-01
        相关资源
        最近更新 更多