在C中,我如何读取文件,并且只存储双打 - 忽略之前的文本?

时间:2014-05-21 15:18:12

标签: c file-io scanf

我需要读取包含文本的文件,然后读取该文本的double。它只是获得数字集的均值和标准差,因此之前的文本是无关紧要的。例如,我的输入文件看起来有点像:

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);
}

3 个答案:

答案 0 :(得分:3)

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

或者可能(稍微简单一些)fscanf(ifp, "%*s %lf", &sample)

答案 1 :(得分:1)

你有两个主要问题 - 你使用的是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]");
    }
}

答案 2 :(得分:0)

从文件中读取时,通常最好使用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

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

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