- ベストアンサー
fscanfで格納された変数がおかしいです。
- ダブルポインタで定義した変数にfscanfでファイルから文字列データを読み込んでいるのですが、表示がおかしな事になっています。
- 読み込んだファイルの内容は、aiueo, kakikueko, sasisuseso, tatituteto です。
- 自分では解決しづらいのでここで質問をさせていただくことになりました。C/C++で記述してありますが、以下にソースを載せておきますのでご指摘ください。
- みんなの回答 (8)
- 専門家の回答
質問者が選んだベストアンサー
どうもめちゃくちゃ書きすぎてました & 最後まで動かしてなかった まず #4 にしたがった修正するなら char ** では無くて char * としてください どうしてもchar** にしたいのであれば >size = (char**)malloc(sizeof(char) * MAXSIZE * c); の部分を size = (char**)malloc(sizeof(char *) * MAXSIZE * c); とする必要があります ただしこの場合実際に格納しているのはファイルの読み取りデータであって 確保した変数名と型が一致してないのでとっても分かりずらいプログラムになります 今度一応ちゃんとプログラム通したから合ってるはず・あっててくれ
その他の回答 (7)
- asuncion
- ベストアンサー率33% (2127/6289)
どうでもいいけど、 誤:見ずらい、分かりずらい 正:見づらい、分かりづらい 見たり分かったりするのが「つらい」のです。 見たり分かったりするのが「すらい」のではありません。 # 変換の際に警告が出ないのかな?
お礼
つらい○ すらい×ですね。^^; 誤字脱字には気をつけておきます。
- n2201makita
- ベストアンサー率30% (8/26)
Microsoft VSコンパイラで同様のエラーメッセージが確認できました。 error C2440: '=' : 'char *' から 'char (*)[256]' に変換できません。 そうなら、行番号も分かっているので、機械的に (char*)malloc(); から (char(*)[MAXSIZE])malloc(); gcc -std=C99 ではWエラーでしたので、一発正解にならなくてすみません。 にしても、結局Microsoftのエラーメッセージは親切ですね。
お礼
なるほど。 char (*)[MAXSIZE]で char *size[MAXSIZE]に対応することができるんですね。 冷静に考えれば、 配列へのポインタ型ですから当然ですよね。 回答ありがとうございます。
- n2201makita
- ベストアンサー率30% (8/26)
こんちには、初投稿なのでインデントのしかたが分からなくて見ずらいかも知りません、ご勘弁を。 ポインタの配列つまりダブルポインタと、2次元配列の区別を勉強しするといいです。 コメントの//側を採用しても同じ動作です、理由は私も詳しくは知りませんが、&は付けなくて大丈夫です。 /* double pointa */ #include <stdio.h> #include <stdlib.h> #define MAXSIZE 256 //char** size; char (*size)[MAXSIZE]; // TEST void test(void) { for(int l = 0; l < 3; l++) { printf("\n%s", &size[l]); } // printf("\n%x %x", &size[1], &size[1], size[1]); // for(int l = 0; l < 3; l++) { // printf("\n%s", size[l]); // } } int main() { FILE* fp; int c = -1; char moji[MAXSIZE]; if((fp = fopen("test.txt","rb")) == NULL) { printf("error"); exit(1); } while(fscanf(fp,"%s",moji) != EOF) c++; size = (char*)malloc(sizeof(char) * MAXSIZE * c); // 初めに戻す fseek(fp, 0, SEEK_SET); // 最初の文だけ取り出す fscanf(fp,"%s",moji); // 一文を格納する for(int l = 0; fscanf(fp, "%s", &size[l]) != EOF; l++) { printf("\n%s", &size[l]); } // for(int l = 0; fscanf(fp, "%s", size[l]) != EOF; l++) { // printf("\n%s", size[l]); // } printf("\n"); test(); fclose(fp); getchar(); free(size); return 0; }
お礼
ご回答ありがとうございます。 ポインタの配列で上記のソースのようにしたのですが、 error C2440: '=' : 'char *' から 'char (*)[256]' に変換できません。 というエラーがでてきます。 ポインタ配列での取得の仕方がおかしいみたいなんです。
- koi1234
- ベストアンサー率53% (1866/3459)
追加書き込みしまくってるついで 修正箇所は以下のようになります size[l] を size[l * MAXSIZE] に変えれば動きます (char **で定義する必要無いって話もあるかもしれません)
お礼
回答ありがとうございます。 ダブルポインタの理解力が足りないみたいですね。 size[l * MAXSIZE]に直したらところ表示は正常になりましたが freeで解放しようとすると失敗するみたいです。 詳しくは分からないので調べてみようと思います。
- koi1234
- ベストアンサー率53% (1866/3459)
#1#2 ぼけまくってます 再訂正 sizeはダプルポインタの型定義してるだけで size[0]/size[1]・・・・ に256バイトのバッファ先頭アドレスはいってるわけではありません >for(int l = 0; fscanf(fp, "%s", &size[l]) != EOF; l++) { これでは全体で確保したバッファのポインタポンのアドレスを インクリメントしたバッファアドレスを渡してるだけです 読み込みしながらの表示では見た目上問題ありませんが 最後のtest関数では表示がおかしくなります
- koi1234
- ベストアンサー率53% (1866/3459)
#1訂正 ちゃんと見てなかった 2回目のtest関数では文字の終端がNULL(0)になってないので そのように表示されます 読み込み直後はたまたま0が入ってるだけ 本来意識的にクリアするなどの方法を取らないと 潜在的なバグになります
- koi1234
- ベストアンサー率53% (1866/3459)
> size = (char**)malloc(sizeof(char) * MAXSIZE * c); 行数カウントする際に c をインクリメント しかも -1 で初期化しているので実行数と取得した行数が食い違います > // 最初の文だけ取り出す > fscanf(fp,"%s",moji); ここで既にファイルポインタが移動するので次の読み込みは kakikueko が読み込まれます >// 一文を格納する >for(int l = 0; fscanf(fp, "%s", &size[l]) != EOF; l++) { >printf("\n%s", &size[l]); >test(); 上ではやってることは結果として同じ (結果として読み込みファイルの2行目から最後までを2回表示してるだけ) 実行結果がおかしいわけではありません
お礼
>まず #4 にしたがった修正するなら char ** では無くて char * としてください コンパイルしたら無事にできました。 普通のポインタでのやり方でも問題なくできそうですね。 >どうしてもchar** にしたいのであれば こっちの方も無事にできました。 ダブルポインタにたいしてもっと勉強しておこうと思います。 何より無事に解決できました。