2013-05-15 88 views
2

我想要读取最多具有10行的txt文件。该文件的格式是这样上的所有行:使用fscanf从给定行读取

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

回答

1

你差不多快完成,但你只需要改变格式specifier.The下面的代码通过你的意行之前的行读取,但忽略它的读取。

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); 
+0

您需要每次检查'fscanf()'的结果。 –

+0

谢谢,这个窍门 – Dawson

+0

@JonathanLeffler'你需要检查每次fscanf()的结果 - 你能澄清你的意思吗?我没有得到你。 –

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

谢谢,这是好消息 – Dawson

+0

@JonathanLeffler有没有我们可以读,但忽略整行像我笨拙地用'的fscanf没有任何其他方式(F, “%* d%* d%* d”)' ?正在使用'%* [^ \ n]'为此可以做的最近的事情? –

+0

@Rüppell'sVulture:跳过整行的最好方法是使用'fgets()',就像我在答案中的代码的最后一个版本一样。显然,如果这些行中的任何一行长度超过4095字节,就会有错误的行数。 OTOH,这相当不可能。 –

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 
}