-PR-
解決済み

配列の読み込み

  • 困ってます
  • 質問No.83659
  • 閲覧数137
  • ありがとう数2
  • 気になる数0
  • 回答数6
  • コメント数0

お礼率 27% (18/66)

タブ又はカンマ、又はスペースで区切られた配列が書かれたテキストを、配列として読み込みたいのですが、どのようプログラムしたらいいのでしょうか。

つまりは、下の例みたいに書かれたテキストを、そのまま3行4列の配列として読み込みたいのです。
例)
1222,2337,593,3488
2338,384,34,2229
534,23333,234,444

ちなみに、私は下のような1列で書かれたものなら読み込めます。
例)
123
343
23
253
通報する
  • 回答数6
  • 気になる
    質問をブックマークします。
    マイページでまとめて確認できます。

質問者が選んだベストアンサー

  • 回答No.1
レベル9

ベストアンサー率 48% (36/74)

こんにちは。
ご自身の勉強のために、あえてヒントだけを書きますと、
for
fgets
strtok
を使用すればできます。ヘルプを見て下さい。
strtokの使い方がポイントです。
これで分からなければ、再度投稿します。
補足コメント
deeppurple14

お礼率 27% (18/66)

ありがとうございました。とりあえず、こうやってみました。でも無理でした。
int a[3][4];
char str[50];
FILE *fp;

if((fp=fopen("test","r"))==NULL)exit(0);

for(i=0;i<3;i++)
{
fgets(str,50,fp);
for (j=0;j<4;j++)
{
a[i][j]=atoi(strtok(str,","));
}
}

上の例で試したところ、配列aは以下のようになってしまいました。
1222,1222,1222,1222
2338,2338,2338,2338
534,534,534,534

strtokが、forループの中で毎回初めの数字を読み込んでいます。
投稿日時 - 2001-05-31 20:21:41
関連するQ&A
-PR-
-PR-

その他の回答 (全5件)

  • 回答No.3
レベル12

ベストアンサー率 75% (398/526)

# No.1の補足に対して strtokは癖の強い関数なので、最初は悩みますよね。 この関数は内部に参照ポインタを持っていて、前回どこまで調べたかを覚えていてくれるのです。 2回目以降調べる場合は、第1引数にNULLを指定します。 最後まで調べ尽くすとNULLを返します。まぁ今回は数が分かっているので使いませんが。 以上を参考に改良をしてみてください。 # ただ、このような単純なフォー ...続きを読む
# No.1の補足に対して
strtokは癖の強い関数なので、最初は悩みますよね。
この関数は内部に参照ポインタを持っていて、前回どこまで調べたかを覚えていてくれるのです。
2回目以降調べる場合は、第1引数にNULLを指定します。
最後まで調べ尽くすとNULLを返します。まぁ今回は数が分かっているので使いませんが。

以上を参考に改良をしてみてください。

# ただ、このような単純なフォーマットのテキストファイルならば、普通はfscanfのループで十分だと思いますが。
補足コメント
deeppurple14

お礼率 27% (18/66)

fscanfの方法も分かりました。どうもありがとうございます。
単純なフォーマットならfscanfかsscanfが便利で、複雑なフォーマットや列が長い場合は、strtokを使えばいいことが分かりました。
投稿日時 - 2001-05-31 21:58:46
お礼コメント
deeppurple14

お礼率 27% (18/66)

ありがとうございます。
なるほど、下のように書けばうまくいきました。

for(i=0;i<3;i++)
{
fgets(str,50,fp);
j=0;
a[i][j]=atoi(strtok(str,","));
while(1)
{
j++;
if((a[i][j]=atoi(strtok(NULL,",")))==NULL)break;
}
}

この書き方でうまくいきますが、もっと効率のいい書き方ないでしょうか。
また、fscanfのループでうまくいくってのが分かりません。毎回先頭の数字を読み込みそうな気がしますが。
投稿日時 - 2001-05-31 21:28:06


  • 回答No.6
レベル11

ベストアンサー率 29% (114/390)

既に解決なさってるようですが一応・・・ No.2の補足に対する回答です。 >こんなかんじでいいでしょうか?  いいと思いますよ。 >列が非常に長いときは、strtokを使うしかないのでしょうか?  あまり長いと、sscanfで指定するフォーマットが長くなってしまうので、 よくないですね。("%d,%d,%d,%d,・・・"という感じになってしまうので) ...続きを読む
既に解決なさってるようですが一応・・・
No.2の補足に対する回答です。
>こんなかんじでいいでしょうか?

 いいと思いますよ。


>列が非常に長いときは、strtokを使うしかないのでしょうか?

 あまり長いと、sscanfで指定するフォーマットが長くなってしまうので、
よくないですね。("%d,%d,%d,%d,・・・"という感じになってしまうので)
 strtokの方がスマートに書けると思います。
(No.3の補足に書いてあるとおりです)
  • 回答No.5
レベル9

ベストアンサー率 48% (36/74)

方法としては、No.4の回答でほとんど問題はないと思います。 実際にコードを書く場合には、ループの回数=配列の大きさを #define で定義して 使用すると、間違いが少なくなるでしょう。 また、fscanfではなく、fgetsとstrtokの組合せを勧めたのもミスを防ぎ、配列の 大きさに柔軟に対応させるためです。 たとえば、読み込むファイルをExcelで作成し、CSV形式で保存すれば、上の例に ...続きを読む
方法としては、No.4の回答でほとんど問題はないと思います。
実際にコードを書く場合には、ループの回数=配列の大きさを #define で定義して
使用すると、間違いが少なくなるでしょう。
また、fscanfではなく、fgetsとstrtokの組合せを勧めたのもミスを防ぎ、配列の
大きさに柔軟に対応させるためです。
たとえば、読み込むファイルをExcelで作成し、CSV形式で保存すれば、上の例に
あるファイルを作成できますが、行末にもカンマが付くことがあります。
例)
1222,2337,593,3488,
fscanfを使用すると、書き方によっては最後のカンマのために、2行目以降の
データが全てずれる可能性がありますが、No4の回答の例では、カンマがあっても
無くても正確に読み込めます。
どのようなフォーマットにしろ、テキスト(ascii)形式のファイルは、1行ずつ
fgetsで読み込んでから処理する事をお勧めします。
  • 回答No.2
レベル11

ベストアンサー率 29% (114/390)

1列のデータは4つの数字がカンマで区切られたものですので、  sscanf を用いればできると思います。 1列のデータを読み込んで、sscanfで数字を取り出して・・・。 と、ここまでにしておきます。 頑張って下さいね。 ...続きを読む
1列のデータは4つの数字がカンマで区切られたものですので、
 sscanf
を用いればできると思います。

1列のデータを読み込んで、sscanfで数字を取り出して・・・。

と、ここまでにしておきます。
頑張って下さいね。
お礼コメント
deeppurple14

お礼率 27% (18/66)

ありがとうございます。下のように書いたところ、うまくいきました。
こんなかんじでいいでしょうか。
列が非常に長いときは、strtokを使うしかないのでしょうか?

for(i=0;i<3;i++)
{
fgets(str,50,fp);
sscanf(str,"%d,%d,%d,%d",&a[i][0],&a[i][1],&a[i][2],&a[i][3]);
}
投稿日時 - 2001-05-31 21:48:08
  • 回答No.4
レベル12

ベストアンサー率 75% (398/526)

# No.3お礼より こんな感じでどうでしょうか? for (i = 0; i < 3; i++) {   a[i][0] = atoi( strtok( fgets(str,50,fp),"," ) );   for (j = 1; j < 4; j++)     a[i][j] = atoi( strtok( NULL,"," ) ); ...続きを読む
# No.3お礼より
こんな感じでどうでしょうか?

for (i = 0; i < 3; i++) {
  a[i][0] = atoi( strtok( fgets(str,50,fp),"," ) );
  for (j = 1; j < 4; j++)
    a[i][j] = atoi( strtok( NULL,"," ) );
}

# 括弧の対応に要注意!
# データを間違えて読むことより、不正な配列アクセスをする方が危険なので、確実に3行4列を超えないようにループを組む必要があります。
  ↑非常に大事!

またfscanfループの1つの解として、こんなのもあります。が、、、

for (i = 0; i < 3*4; i++)
  fscanf(fp, "%d,", *a + i);

これは必ずしも「よいプログラム」ではありません。
なぜなら「理解しにくい」からです(笑)

# 理解しやすいコーディングというのはとても大切なことなのですが、プロでもできてない人が大勢いるんです。
# こういうことをやる人に限って、自分のコードは素晴らしいと思ってる人が多くって・・・
# 素直なプログラムを書けるように頑張りましょう。

leaz愚痴モードでした。
このQ&Aで解決しましたか?
関連するQ&A
-PR-
-PR-
こんな書き方もあるよ!この情報は知ってる?あなたの知識を教えて!
このQ&Aにはまだコメントがありません。
あなたの思ったこと、知っていることをここにコメントしてみましょう。

その他の関連するQ&A、テーマをキーワードで探す

キーワードでQ&A、テーマを検索する
-PR-
-PR-
-PR-

特集


新大学生・新社会人のパソコンの悩みを解決!

いま みんなが気になるQ&A

関連するQ&A

-PR-

ピックアップ

-PR-
ページ先頭へ