2012-03-17 77 views
1

我試圖將一個文件的內容提取到一個矩陣中,但該文件可能看起來完全不同。fgets和strtok在一個雙「for」循環中

例如,所有這些文件應該給出相同的結果:包含1,2,3,4,5,6,7,8,9的3x3矩陣。


1 2 3 
4 5 6 
7 8 9 

1 2 3 
4 5 6 
7   8 9 

1 2 3 4 
5 
6 
7 8 
9 

1 2 3 
$something 
$something else 
4 5 6 
$something else else 
7 8 9 

希望我知道的尺寸矩陣以及表示這些行將在當前進程中被忽略的「$」字符。

我目前使用fscanf的算法效果很好,但它不能與「$ something」行一起工作。

我想我應該使用fgets/strtok/sscanf方法,但有一些問題。

// File* file (already assigned) 
char line[32]; //assuming 32 is enough 
char* token; 

fgets(line,32,file); 
token = strtok(line," \t"); 

for (y=0; y<ySize; y++) 
{ 
    for (x=0; x<xSize, x++) 
    { 
     if (token[0] == '$') //should use a str function 
     { 
      fgets(line,32,file); 
      token = strtok(line," \t") 
      x--; 
     } 
     else 
     { 
      if (we are at the end of the line) 
      { 
       fgets(line,32,file); 
       token = strtok(line," \t") 
      } 
      sscanf(token,"%d",&matrix[x][y]; 
      token = strtok(NULL," \t"); 
     } 
    } 
} 

基本上我想有一定的幫助寫的:「如果(我們是在該行的末尾)」的條件和我的方法的一些投入,是它完美無瑕?我有沒有正確的想到這個過程?

謝謝。

+0

看看['strtol()'](http://pubs.opengroup.org/onlinepubs/9699919799/functions/strtol.html)。您可以使用第二個參數來設置貫穿整行的呼叫鏈。 – pmg 2012-03-17 15:19:24

+0

是隻評論全行,還是會允許像'1 2 $ ignore'這樣的行? – 2012-03-17 15:22:52

+0

1 2 $忽略是不可能的。但bascially我只需要每次調用'token == $'(仍然有一些關於令牌和所有的研究)。 1 $ ignore 2也是不可能的。 – Sword22 2012-03-17 15:35:44

回答

1

您應該使用getline而不是fgets來簡化操作。後者是不可靠的。您正在尋找的測試條件爲:

token == NULL; 

檢查this:「一旦海峽的終止空字符已經在通話中被發現strtok函數,這個函數的所有後續調用空指針作爲第一個參數返回一個空指針。「

+0

你認爲'fgets'的「不可靠」是什麼? – 2012-03-17 15:21:08

+0

對於在文本模式下打開的流,fseek的用途有限,因爲回車換行轉換會導致fseek產生意外的結果。保證在文本模式下打開的流的唯一fseek操作是: *尋找相對於任何原始值的偏移量0。 *從文件的開頭尋找從調用ftell返回的偏移值。 – 2012-03-17 15:24:32

+0

你是說在x和y上有一段時間?有什麼區別? Ans不是strtok(NULL,「\ t」)是否需要進入字符串的下一個元素? – Sword22 2012-03-17 15:28:15

0

通過使用strspn()/ strcspn()和sscanf()s「%n」說明符,可以輕鬆地解析strtok()。另外:在原始代碼中有一個',',';'本來應該。

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

#define XSIZE 3 
#define YSIZE 3 

int matrix[XSIZE][YSIZE]; 

int main(void) 
{ 
char line[200]; 
int pos,eat,xx,yy, rc; 

xx = yy =0; 
while (fgets(line, sizeof line, stdin)) { 
    if (line[0] == '$') continue; 
    for(pos=0; line[pos]; pos += eat) { 
     pos += strspn(line+pos, " \t\n"); 
     rc =sscanf(line+pos, "%d%n", &matrix[xx][yy], &eat); 
     if (rc < 1) break; 
     if (++xx >= XSIZE) {xx = 0; if(++yy >= YSIZE) goto done; } 
     } 
    } 
done: 
     /* show it to the world ... */ 
for (yy = 0; yy < YSIZE; yy++) { 
    for (xx = 0; xx < XSIZE; xx++) { 
     fprintf (stdout, " %d", matrix[xx][yy]); 
     }  
    fprintf (stdout, "\n"); 
    } 
return 0; 
} 
+0

或多或少是我在用while循環時想到的,但我認爲使用for循環更容易閱讀,並且性能應該差不多。豎起大拇指雖然這! – 2012-03-17 19:48:32

+0

原始代碼在三個不同的地方使用fgets()(這是醜陋的恕我直言)。在大多數情況下,將fgets()放在外部循環中將產生最乾淨的代碼。性能不是問題,大部分時間都用在sscanf()中,並且對sscanf()的調用次數相同。另外:原來沒有檢查fgets()或sscanf()的返回碼。 – wildplasser 2012-03-17 19:56:53

+0

是的,的確,但你使用了一個標籤,這是我不會建議的! – 2012-03-17 20:04:03