2016-02-23 39 views
2

我要讀這樣的文件:在閱讀下一行之前,我該如何停止?

0 -> 1:50 2:30 3:10 
1 -> 
2 -> 0:10 3:20 
3 -> 1:20 2:10 3:30 

這裏是我的代碼:

graphs = fopen(argv[2],"r"); 

    if(graphs==NULL){ 
    printf("File hostgraphs not found\n"); 
    exit(EXIT_FAILURE); 
    } 
    while((err=fscanf(graphs,"%d ->",&num))==1){ 
    row=num; 
    while((err1=fscanf(graphs," %d:%d ",&column,&visits))==2){ 
     hostgraphs[row*n+column]=visits; 
    } 
    if(err1!=2) 
     break; 
    if(err==0){ 
     printf("Hostgraph out of bounds\n"); 
     exit(EXIT_FAILURE); 
    } 
    } 
    for(i=0;i<n;i++){ 
    for(j=0;j<n;j++){ 
     printf("%d ", hostgraphs[i*n+j]); 
    } 
    printf("\n"); 
    } 

它給了我下面的結果:

0 50 30 10 
0 0 0 0 
0 0 0 0 
0 0 0 0 

預期輸出必須是:

0 50 30 10 
0 0 0 0 
10 0 0 20 
0 20 10 30 

任何人都可以幫助我嗎?

+0

什麼是您預期的輸出? – Nitish

+5

使用'fgets'來讀取整行,然後自行解析該行。 –

+0

你在'n'和'num'之間混淆了嗎? –

回答

0

你可以這樣做一段時間,使用getline,然後分別在每條線上應用與您相同的邏輯。

在下面的代碼中,我首先使用getline方法從buffer中的文件中獲取一行。然後我處理使用fmemopen方法線作爲FILE指針fbuffer,這是用來讀取像一個文件中的字符串:

graphs = fopen(argv[2],"r"); 

if(graphs==NULL) 
{ 
    printf("File hostgraphs not found\n"); 
    exit(EXIT_FAILURE); 
} 

char *buffer = NULL; 
size_t len = 0; 

while(getline(&buffer, &len, graphs) != -1) 
{ 
FILE * fbuffer = fmemopen(buffer, len, "r"); 

while((err=fscanf(fbuffer,"%d -> ",&num))==1) 
{ 
    row=num; 

    while((err1=fscanf(fbuffer," %d:%d ",&column,&visits))==2) 
    { 
    hostgraphs[row*n+column]=visits; 
    } 

    if(err1!=2) 
    { 
    break; 
    } 

    if(err==0) 
    { 
    printf("Hostgraph out of bounds\n"); 
    exit(EXIT_FAILURE); 
    } 
    } 

    free(buffer); 
    buffer = NULL; 
    len = 0; 
} 

for(i=0;i<n;i++) 
{ 
    for(j=0;j<n;j++) 
    { 
     printf("%d ", hostgraphs[i*n+j]); 
    } 
    printf("\n"); 
} 

注:我剛纔添加的代碼,使現有代碼的工作,未做您的代碼的任何更改。

+0

非常感謝您的幫助! :) –

+0

@AntoniaAntoniou很高興幫助!歡迎來到SO。如果這個或者其他答案在任何意義上幫助了你,你可以[upvote](https://meta.stackexchange.com/questions/173399/how-to-upvote-on-stack-overflow)來表示感謝和表明答案是有幫助的。 –

0

修復的方法是簡單的:除去在fscanf格式字符串後間隔

fscanf(graphs," %d:%d ",&column,&visits) 

應該通過讀取文件,一條線在被簡化爲

fscanf(graphs,"%d:%d", &column, &visits) 
+2

文件的第二行總是會因爲fscanf不會返回而中斷... – LPs

+0

這不是它不起作用的問題我試過了 –

0

fscanf忽略然後換行讀第一行後,它移動到下一行和閱讀5err1結果1。這是根本原因。您可以添加fseek以後退並按照以下代碼片段開始新序列,或者將算法簡單地更改爲另一個有效的序列。

graphs = fopen(argv[2],"r"); 
if (!graphs) { 
     printf("File hostgraphs not found<%s>\n", argv[1]); 
     exit(EXIT_FAILURE); 
    } 

    while((err = fscanf(graphs, "%d ->", &num)) == 1) { 
     pos = ftell(graphs); // save position 

     while((err1 = fscanf(graphs, " %d:%d", &column, &visits)) == 2) { 
      hostgraphs[num * n + column] = visits; 
      pos = ftell(graphs); // save position 
     } 

     // seek back to previous one and start new sequence 
     fseek (graphs , pos, SEEK_SET); 
    } 

    for(i = 0; i< n; i++){ 
     for(j = 0; j < n; j++){ 
      printf("%d ", hostgraphs[i * n + j]); 
     } 

     printf("\n"); 
    } 
0

您已經關閉,但您需要找到每個'\n'而不讀取文件中下一行值的方法。對於fscanf這是非常困難的,您的輸入文件中每行都有不同數量的元素。

另一種方法是使用fgets來讀取整個行,然後將初始"row -> "前綴與數據值分開。如果將值移入單獨的值緩衝區(例如vbuf),則可以通過查找space,前進到下一個digit,然後使用sscanf拆分columnvisits來重複循環遍歷緩衝區。

(你實際上甚至不需要在vbuf拆分值,你可以簡單地使用指針前進過去"row -> "文本與整條生產線的工作。)

下面的例子把這些拼湊,將值分析到hostgraphs中的正確位置。看一下它,並讓我知道如果您有任何疑問:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

enum { COLS = 4, MAXH = 16, MAXC = 64 }; 

int main (int argc, char **argv) { 

    char buf[MAXC] = "", vbuf[MAXC] = ""; 
    char *p = NULL, *rfmt = "%d -> %[^\n]"; 
    int row, column, visits, hostgraphs[MAXH] = {0}; 
    size_t i, j, n = 0; 
    FILE *graphs = argc > 1 ? fopen (argv[1], "r") : stdin; 

    if (!graphs) { 
     fprintf (stderr, "error: file open failed '%s'.\n", argv[1]); 
     return 1; 
    } 

    while (fgets (buf, MAXC, graphs)) 
    { 
     *vbuf = 0; /* initialize vbuf, split %d:%d pars into vbuf */ 
     if (sscanf (buf, rfmt, &row, vbuf) < 1) 
      break; 

     if (!*vbuf) { /* check vbuf contians values */ 
      n++; 
      continue; 
     } 

     /* read 1st pair */ 
     if (sscanf (vbuf, "%d:%d", &column, &visits) != 2) { 
      fprintf (stderr, "error: invalid line format\n"); 
      exit (EXIT_FAILURE); 
     } 
     hostgraphs[row*COLS+column] = visits; 

     p = vbuf; /* assign p, parse remaining pairs */ 
     while ((p = strchr (p, ' '))) /* find space */ 
     { 
      while (*p < '0' || '9' < *p) /* find digit */ 
       p++; 

      if (sscanf (p, "%d:%d", &column, &visits) == 2) 
       hostgraphs[row*COLS+column] = visits; 
     } 
     n++; /* advance row count */ 
    } 

    for (i = 0; i < n; i++) { /* output values */ 
     printf (" row[%2zu] : ", i); 
     for(j = 0; j < COLS; j++) { 
      printf (" %2d", hostgraphs[i * COLS + j]); 
     } 
     printf ("\n"); 
    } 

    if (graphs != stdin) 
     fclose (graphs); 

    return 0; 
} 

輸入文件

$ cat ../dat/hostgraph.txt 
0 -> 1:50 2:30 3:10 
1 -> 
2 -> 0:10 3:20 
3 -> 1:20 2:10 3:30 

輸出

$ ./bin/hostgraph < ../dat/hostgraph.txt 
row[ 0] : 0 50 30 10 
row[ 1] : 0 0 0 0 
row[ 2] : 10 0 0 20 
row[ 3] : 0 20 10 30 
相關問題