使用fscanf从给定行读取

时间:2013-05-15 04:30:28

标签: c input scanf

我想读取一个最多有10行的txt文件。该文件的格式如下所示:

1 1 8
2 2 3
3 1 15
4 2 7

我正在尝试编写一个只从传递给它的int提供的行读取的函数。我想过使用for循环遍历行而不扫描任何东西,但我无法弄清楚如何实现它。

到目前为止我的功能看起来像这样,for循环还没有正确实现。

void process(int lineNum, char *fullName)
  {
    int ii, num1, num2, num3;

    FILE* f; 
    f = fopen(fullName, "r");

    if(f==NULL) 
      {
      printf("Error: could not open %S", fullName);
      }

    else
    {
    for (ii=0 (ii = 0; ii < (lineNum-1); ii++)
      {
      /*move through lines without scanning*/
      fscanf(f, "%d %d %d", &num1, &num2, &num3);
      }

    printf("Numbers are: %d %d %d \n",num1, num2, num3);
    }
  }

3 个答案:

答案 0 :(得分:1)

您必须阅读所有直到您想要的行。

我可能会使用fgets()来读取行,sscanf()来解析所需的行。但是,您可以添加一个循环来读取不需要的行(仍为fgets()),然后使用fscanf()读取所需的行。检查您是否有三个值:您必须检查fscanf()的返回值。还记得关闭你打开的文件。

void process(int lineNum, char *fullName)
{
    FILE *f = fopen(fullName, "r");

    if (f == NULL) 
    {
        fprintf(stderr, "Error: could not open %S", fullName);
        return;
    }

    int num1, num2, num3;
    for (int i = 0; i < lineNum; i++)
    {
        if (fscanf(f, "%d %d %d", &num1, &num2, &num3) != 3)
        {
            fprintf(stderr, "Format error on line %d\n", i+1);
            fclose(f);
            return;
        }
    }

    printf("Numbers are: %d %d %d \n",num1, num2, num3);
    fclose(f);
}

请注意,此代码实际上并不强制分隔数字集合的行(scanf()函数系列的基于文件的成员的缺点之一。为此,您需要fgets()sscanf()

void process(int lineNum, char *fullName)
{
    FILE *f = fopen(fullName, "r");

    if (f == NULL) 
    {
        fprintf(stderr, "Error: could not open %S", fullName);
        return;
    }

    char line[4096];
    for (i = 0; i < lineNum; i++)
    {
        if (fgets(line, sizeof(line), f) == 0)
        {
            fprintf(stderr, "Premature EOF at line %d\n", i+1);
            fclose(f);
            return;
        }
        // Optionally check format here...
    }

    int num1, num2, num3;
    if (sscanf(line, "%d %d %d", &num1, &num2, &num3) != 3)
    {
        fprintf(stderr, "Format error on line %d\n", i+1);
        fclose(f);
        return;
    }

    printf("Numbers are: %d %d %d \n",num1, num2, num3);
    fclose(f);
}

答案 1 :(得分:1)

你差不多完成了,但你只需要更改格式说明符。下面的代码读取了你想要的行之前的行,但忽略了它的内容。

for (ii=0 (ii = 1; ii < (lineNum-1); ii++)
      {
      /*move through lines without scanning*/
      fscanf(f, "%*d %*d %*d%*c");
      // fscanf(f, "%*d %*d %*d\n");
      }
fscanf(f,"%d%d%d",&num1,&num2,&num3);

答案 2 :(得分:0)

您需要对输入扫描使用检查。您可能会遇到错误或EOF。

if(line < 1)       //check for invalid line number
{
    printf("Invalid line number..aborting\n");
    exit(1);   //aborting is optional
}
for(int i = 0;i<line-1;i++)
{
    switch(flag  = fscanf(fp,"%*d %*d %*d"))//flag is for debug only
    {
    case 0 ://since we are ignoring the read, fscanf return 0
    case 3:break;           //normal read (should not happen)
    default:printf("File read Error\n");//if fscanf returns EOF, 1,2
    }
}
if(EOF ==fscanf(fp,"%d%d%d",&n1,&n2,&n3))//check for EOF. last scan might have ignored till last line
{
    printf("File read Error: end of file reached");
}
else
{
    printf("\n%d, %d, %d",n1,n2,n3);//normal case
}