2012-03-17 4 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)をご覧ください。第2引数を使用して、行全体を通るコールチェーンを設定できます。 – pmg

+0

コメントは完全な行だけですか、 '1 2 $ ignore'のような行は許可されますか? –

+0

1 2 $無視することはできません。しかし基本的には、毎回 'token == $'を呼び出さなければなりません(まだトークンとすべてのことについていくつかの研究があります)。 1 $無視することもできません。 – Sword22

答えて

1

fgetsの代わりにgetlineを使用すると、作業が楽になります。後者は信頼できません。あなたが探している試験条件は次のとおりです。

token == NULL; 

チェックthis:「STRの終端のNULL文字が最初のようにNULLポインタで、この関数へのすべての後続の呼び出しをstrtokは呼び出し中に発見された後引数はヌルポインタを返します。 "

+0

'fgets'について「信頼できない」と思われるものは何ですか? –

+0

テキストモードで開かれたストリームの場合、fseekはキャリッジリターンラインフィード変換によってfseekが予期しない結果を生成する可能性があるため、使用が制限されています。テキストモードで開かれたストリームで動作することが保証されているfseekの唯一の操作は、 *いずれかの原点の値に対して0のオフセットでシークします。 * ftellへの呼び出しから返されたオフセット値でファイルの先頭から検索します。 –

+0

xとyにしばらくお待ちですか?違いは何ですか? 文字列の次の要素に進むには、Ansはstrtok(NULL、 "\ t")ではありませんか? – Sword22

0

strspn()/ strcspn()およびsscanf()の "%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ループで読むのは簡単だと思いますが、パフォーマンスはほぼ同じでなければなりません。しかし、これのために親指アップ! –

+0

元のコードは3つの異なる場所(これは醜いIMHOです)でfgets()を使用していました。ほとんどの場合、外側のループにfgets()を入れると、最もきれいなコードが得られます。パフォーマンスは問題ではなく、ほとんどの時間はsscanf()内で費やされ、sscanf()への呼び出し回数は同じです。また、オリジナルはfgets()またはsscanf()の戻りコードをチェックしませんでした。 – wildplasser

+0

はい、確かに、ラベルを使用していますが、これは私がアドバイスしないものです! –

関連する問題