2013-05-15 79 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 
}