許せない心理テスト

こんにちは。
C言語で現在ある入力ファイルを読み込んで計算し、
ファイルを出力するというプログラムを作成中なのですが、
ファイルを読み込む場合に、
改行までの値を一文字ずつ読み込むという作業をさせたいと思っています。
データは、
abc

defgh

ijk

.....

といった感じで入力されており、

while((c = fgetc(fp)) != '\n'){
fscanf(fp, "%c", &q[i]);
}

と書いたのですが、セグメント例外が出て強制終了してしまいます。
初歩的なことで申し訳ないのですが、教えていただきたいと思います。よろしくおねがいします。

A 回答 (6件)

(1)fgetc() の時点でもう既に1文字データを読んでいるので、


fscanf() で'再度取得'することはできません。
q[i] には c の値をそのまま代入してください。

(2)i はインクリメントしなくてよいのでしょうか?

(3)行の終端 '\n' を検出して while を抜けた後、
printf 文などでそのまま表示させていませんか?
文字列 q[] の終端にヌル文字を入れる必要があります。
(q[]が予めゼロクリアされているのなら入れる必要はありません)

(4)それと、feof() でファイル終端をチェックしながらやった方がいいです。

オーバーフローを起こさない為に q[] には大きめの配列を確保してください。

char q[1024];
int i = 0, c;

while( !feof( fp ) )
{
  if( ( c = fgetc( fp ) ) == '\n' )
    break;
  q[i++] = c;
}
q[i++] = '0';

みたいな感じ。

この回答への補足

データの書き方が悪かったのですが、
実際のデータ自体は、いろいろな種類があって、

pqrs

01
p qs q
q r qr
r s p
s 0 p

p

qs


のようになっています。
一行の空行ごとにデータの種類が違うので、それによって読み込み方や、メモリを変えなければならないのです。(最後まで同じやり方でデータを読み込むのではなく、途中から途中まで。)なので、eof()の判定を使えないのではないかと
思います。

また、メモリ自体も動的に確保しなければならないので、もうちょっと変えなければなりませんよね。

やってみます。

補足日時:2005/11/03 21:54
    • good
    • 0

#5です。


最後の行
q[i++] = '\0';
の間違いです。
スミマセン…
    • good
    • 0
この回答へのお礼

この場を借りて・・・。
試行錯誤の結果、出来ました。ありがとうございました。
一番参考にさせていただいた方にポイントを差し上げます。

お礼日時:2005/11/05 11:46

長さが全くわからないバッファの場合は、malloc で多めに確保するのが普通ですが、reallco() で際割り当てすることも出来ます。



#include <stdlib.h>

char *a = 0;
int sizeNow = 0;

if (sizeNow が小さすぎる)
{
sizeNow += 10; // など、siezeNow を更新
realloc(a, sizeNow);
}

こんな感じで、再割り当てが出来ます。
    • good
    • 0
この回答へのお礼

malloc, callocについては知っていましたが、reallocというものがあることは知りませんでした。
うまく使えたら良いなと思います。

お礼日時:2005/11/03 21:57

こんにちは。



ファイルから1文字ずつ読み込むとい事ですが、書かれたプログラムでは、1つ飛ばしに読んでしまします。
セグメント例外といううことですが、fscanfの読み込み使われている配列変数qにアクセスするためのインデックス番号、iがqの容量を超えてしまったか、iが不定のために起こっていると思われます。
以下にサンプルを示します。サンプル中のLENは環境に合わせて変更してください。

#define LEN 80

char q[LEN+1];

i=0;
while((c = fgetc(fp)) != '\n')
q[i++] = c;
if(i == LEN ) break;
}
q[i] = NULL;

この回答への補足

No.1の方の補足にも書いたのですが、メモリは動的に取らなければならないので、LENを使って値を決め打ちすることはできないのです。
mallocやcallocで確保する方法をやってみたのですが、それも失敗してしまったので・・・。
もう少しトライしてみます。

補足日時:2005/11/03 13:52
    • good
    • 0

運が悪いと、全部の'\n'をfscanfで取得してしまい、その後もEOFを取得し続ける事になりそうですね。



c = fgetc(fp)で取得したcを使うようにする。
改行までという条件は、'\n'またはEOFを取得するまでと読み替えた方が安全です。よってcはintで宣言する事になります。

この回答への補足

cはintで宣言してました。
ご指摘ありがとうございます。

補足日時:2005/11/03 13:47
    • good
    • 0

他の方が詳細なソースを示してくれるとおもいますので基本的なところだけ。



fgetcで1文字読みしたときにファイルポインタは次の文字に進んでいるので、fscanfではその次の文字を読み込んでしまいます。

つまりfgetcで1文字、fscanfでもう1文字の2文字読んでいることになるため、q[]で用意したバッファサイズを超えてしまっているのではないでしょうか。

この回答への補足

早速のご回答ありがとうございます。
どうやらそのようです。
動的に領域を確保せよとのことだったので、始めに個数を数えてからq[n]のnの部分に数字を入れることは可能なのでしょうか。

補足日時:2005/11/03 13:37
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


おすすめ情報