毎回お世話になっています。
ただいまC言語を勉強中の学生です。
基本的な文法は頭に入れたつもりでしたが、まだポインタと ファイルの入出力に苦手意識があり 実際うまくできないでいるので
どなたか ご存知の方にアドバイスいただければと思って書き込ませていただきます。
今回練習しているのは 先に述べたように、テキストファイルに
abc
def
ghi
jkl
などと文字列を書いておき、そのファイルを読み込んで
二次元配列に格納したいのですが、何を勘違いしているのか、
うまく実現できません。
参考書などを見て 一次元配列へ格納する場合は できたようなのですが、今後このプログラムを発展させる段階で 二次元配列に文字列を
格納できたほうが好都合なので 今模索しています。。。
ちなみに 一次元配列に格納する場合は 以下のように書きました。
#include<stdio.h>
#include<stdlib.h>
main()
{
char a[10];
FILE *fp;
fp = fopen("word.dat", "r");
if (fp == NULL)
{
printf("File does not exist.\n");
exit(1);
}
while(fscanf(fp,"%s",a)==1){
printf("%s\n",a);
}
fclose(fp);
return 0;
}
実はコレに関しても分からない点があり、それは 目的の配列変数
a[]に格納できたのだから それを確認したいと思い
printfで a[0]~a[10]を表示してみようとしたところ 変に文字化け
したものが表示されたり、何も表示されなかったり よく分からないことが起きます。私は何を勘違いしてしまっているのでしょうか(>_<)
長々と書いてしまいましたが、今回 御教授いただきたいのは
(1)、テキストファイルから 英字の文字列を読み込んで二次元配列に格納するために用いるのに 一番最適な関数はどれか(fscanfやfgetsなど) そして、その関数を使って 一番シンプルな記述をするにはどのように記述すればよいのか
(2)、上のようなプログラムの書き方で、配列aにテキストファイルから読み込んで格納できたようなのに、a[0]~a[10]をprintfしたときに
うまく中身が表示されないのはなぜか。
という点なのですが、(1)をとりあえず急いでおりますので、(2)はおまけ程度に考えていただければと思います。
なぜかファイルの入出力がいまだに把握できなくて苦手としておりますので、どうか よろしくお願いいたします。
No.5ベストアンサー
- 回答日時:
#include <stdio.h>
int
main(void)
{
char a[10][10];
int i, maxi;
FILE *fin;
if ((fin = fopen("test.dat", "r")) == NULL){
fprintf(stderr, "Can't open file\n");
}
for (i = 0; i<10; i++) {
if (fgets(a[i], 10, fin) == 0) {
maxi = i;
break;
}
}
for (i = 0; i < maxi; i++) {
printf("a[%d] = %s", i, a[i]);
}
fclose(fin);
return 0;
}
ご親切に プログラムの書き方まで教えてくださったのにお礼が遅くなってしまい 大変申し訳ございませんでした!学生で 日々C言語を使っておりますが、普段使わない文法はどうしても苦手意識があり、路頭に迷っていました(>_<)そして、大まかには書けているのですが、把握しきれていないためにこまごまとバグがみつかるのですが どう間違っていてどう直せば良いのかというのが 本当に分からなくなっていたので 実際にソースを書いていただけて 読めて さらに理解することができました!本当に助かりました!ありがとうございました!
No.6
- 回答日時:
二次元配列の件は他の方が模範を書かれているので省くけど、
>...それは 目的の配列変数a[]に格納できたのだから それを確認したいと思い
>printfで a[0]~a[10]を表示してみようとしたところ
そらあかんだろ。
10個しか用意してない配列に a[10] はダメよ。最大で a[9]までね。配列のインデックスは0から始まるから a[10] とやった時点で、配列はみ出しちゃうよ。
たぶんコンパイラの親切で「文字化けしたものが表示されたり、何も表示されなかったり」で済むけど、ふつうは「即死」だよ。
この回答への補足
回答ありがとうございます。
それは私の表記ミスです!
上ではa[0]~a[10]をprintfさせようとした。
と書いてしまいましたが、
実際にはきちんと
for(i=0;i<10;i++){
printf("a[%d]=%s \n");
}
としておりますので その点に関しては大丈夫です(^_-)☆
ご指摘ありがとうございます!
No.4
- 回答日時:
>意図して代入したものでない 変な文字が入ってる可能性が
>あるということでしょうか?!
まちがえた。忘れてくれ。
>a[10][10]={"abc","def","ghi"}
>と同じ状況になるように 二次元配列aに格納するには
>どのように記述すればよいのか
先にも述べたように、「行単位」で処理する場合は fgets() を使った方がコードを読む人(自分を含む)が「1行ごとに何かをしてるんだな」とわかるので親切です。
要素数が同じだと説明しにくいので char a[5][10]; としよう。
これは「「要素数 10個の char 配列」の 5個の配列」です。a[0], a[1], .. , a[4] が各々 10個の char 配列ですね。
C 言語ではこれは同時に char[10] の先頭アドレス表現しているので
fgets(a[0], 10, fp); で a[0] から始まる char 配列に fp から読んだ文字列を格納できます。
(改行コードは自前でカットしてね)。以下 a[1], a[2], ... も同様。
もちろん、テキストファイルの行数や 1行のバイト数などはバッファオーバーランしないように適当にやっといてくれ。
お礼が遅くなってしまいすみません!(>_<)ご親切に何度もアドバイスしていただいて 本当にありがとうございました!本当に助かりました!独学では 苦手意識のある部分がどうしてもつかみきれずにいて路頭に迷っていたのです。アドバイスしていただいてイメージがしやすかったです!ありがとうございました!
No.3
- 回答日時:
> printf("a[%s][%d]=%s \n",i,j,a[i][j]);
%sは文字配列の先頭要素(※)へのポインタ(型は char *)を要求しますが、
a[i][j]は文字(型は char)なので書式指定子と後続の引数が合っていません。
そのためa[i][j]に入っている「文字」を
『「文字列の先頭アドレス」と解釈して、どことも知れぬメモリ領域にアクセスしている』
ことになります。
※途中から表示したいなら別に先頭である必要はないけど、普通は先頭なので。
文字(char)を表示したいなら書式指定子は%cです。
ついでに最初の%sも%dの間違いでしょう。
しかし、printfが間違ってるのに
> chara[10][10]={"abc","def","ghi","jkl"};
> のように定義しておいて 実行させたところ、上手く意図したように
> 実行が成されたので、
というのは変ですね。こっちでは正しく書いていたのでは?
> ANo.2
> fscanf() は空白を読み込まないので、単語単位で読む場合にしか使えません。
スキャンセットに空白文字も含めればscanf系でも一応空白読めますね。
まあ行単位の処理ならfgetsを使う方が良いでしょうけど。
お礼が遅くなってしまい 大変申し訳ありません(>_<)
ご指摘いただいて、書式の指定が間違っていることに気がつきました!ありがとうございます!
はい、正しく実行が成されたというのは、一番メインだったのは計算の内容でしたので、printfが間違っていてもそれはそこの表示だけが間違っているだけなので問題にはしなかったためです!printfは 正しく計算されているか確かめるために付加したものでしたのでねっ!
とにもかくにも ご親切に教えていただいて本当に助かりました!どうもありがとうございました!
No.2
- 回答日時:
>(1)、テキストファイルから 英字の文字列を読み込んで
>二次元配列に格納するために用いるのに 一番最適な関数はどれか
fscanf() は空白を読み込まないので、単語単位で読む場合にしか使えません。
fgets() は行単位で読んでくれるので汎用的です(逆に行を読んだ後の加工も自前でする)
いずれにせよ、ファイルを二次元配列に「どのように格納するか」は要件次第なので、それに応じてコーディングして下さい。
>a[0]~a[10]をprintfしたときにうまく中身が表示されないのはなぜか。
例えば a[0] には文字 'x' などが格納されており、それを書式指定子 %s にかけると、これを文字列の先頭アドレスと解釈して、どことも知れぬメモリ領域にアクセスしているからです。
この回答への補足
ご親切な回答 ありがとうございます!(>_<)
fscanfは 単語単位で読む場合しか使えない というのが
分かるようで分からないのですが、
読み込む元のテキストファイルに
abc(改行)
def(改行)
ghi(改行)
[EOF]
と書いている場合で
これらを
a[10][10]={"abc","def","ghi"}
と同じ状況になるように 二次元配列aに格納するには
どのように記述すればよいのかと 困っております(>_<)
もう少しだけ アドバイスをいただけるととても助かります。
申し訳ございません(>_<)
(2)a[0]には 文字'x'などが格納されており というのは
意図して代入したものでない 変な文字が入ってる可能性が
あるということでしょうか?!最初に初期可をすれば
解消できるのでしょうか?!それとも どのような対策を
施せばこの問題をかいしょうできると思われますか?!(>_<)
大変 お手数をおかけしております(>_<)
No.1
- 回答日時:
(1)について、
例えば、a[10][10]という配列があるとして、
この中に文字をどんな風に格納したいですか?
(2)について、
a[0]~a[10]を、どんな風にprintfしましたか?
なお、配列の定義でa[10]と書いたら、使えるのはa[0]~a[9]です。
この回答への補足
>(1)について、
>例えば、a[10][10]という配列があるとして、
>この中に文字をどんな風に格納したいですか?
はい。まず 最終的にはテキストファイルから読み込みたいのだけれど、読みこむ記述を足す前に、他の部分を完成させるために、
テストとして
chara[10][10]={"abc","def","ghi","jkl"};
のように定義しておいて 実行させたところ、上手く意図したように
実行が成されたので、後は テキストファイルから読み込むように
記述を追加させるだけ!と意気ごんだのですが ダメでした。。。
上のような記述をした場合は、a[0][0]にaが入っていて、a[0][1]にbが入っていると考えていたのですが、それが勘違いであるために(2)の
ような問題が起きているのでしょうか?!(>_<)
>(2)について、
>a[0]~a[10]を、どんな風にprintfしましたか?
>なお、配列の定義でa[10]と書いたら、使えるのはa[0]~a[9]です。
はい!
for(i=0;i<10;i++){
for(j=0;j<10;j++){
printf("a[%s][%d]=%s \n",i,j,a[i][j]);
}
printf("\n");
}
printf("\n");
と書きました。a[i][j]は最初にchara型として 定義していたので
%sという書式を指定しました。何がおかしいのか わかりますでしょうか(>_<)
すみません 再び 補足です(>_<)
上の書き込みに書き間違いを発見しました。。。
定義したのは
char a[10][10]です!(chara[10][10]と 書いてしまいましたが)
あ、はい それからa[10]まで定義した場合 値が格納できるのは
a[9]までであることは 理解しております(^^)
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- Excel(エクセル) Excelにて、フォルダ内のTextファイルをマクロで統合すると文字化けしてしまう時の解消コード 4 2023/01/01 07:32
- C言語・C++・C# 10人分の生徒の英語の点数{32,34,41,38,40,26,14,46,42,50} と数学の点 2 2022/05/26 21:31
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- Excel(エクセル) 【VBA】指定フォルダに格納中のテキストファイルをエクセルで処理し結果のエクセルを新規フォルダに保存 1 2022/03/25 14:19
- Visual Basic(VBA) ファイル全てを .xlsm に変更したところ、プログラムが途中で落ちてしまっています 17 2022/12/07 12:03
- C言語・C++・C# C言語初心者 構造体 課題について 2 2023/03/10 19:48
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- Excel(エクセル) PowerQueryに詳しい方教えてください(Office365) 1 2022/07/24 21:11
このQ&Aを見た人はこんなQ&Aも見ています
-
カンパ〜イ!←最初の1杯目、なに頼む?
飲み会で最初に頼む1杯、自由に頼むとしたら何を頼みますか? 最初はビールという縛りは無しにして、好きなものを飲むとしたら何を飲みたいですか。
-
「平成」を感じるもの
「昭和レトロ」に続いて「平成レトロ」なる言葉が流行しています。 皆さんはどのようなモノ・コトに「平成」を感じますか?
-
「覚え間違い」を教えてください!
私はかなり長いこと「大団円」ということばを、たくさんの団員が祝ってくれるイメージで「大円団」だと間違えて覚えていました。
-
いけず言葉しりとり
はんなりと心にダメージを与える「いけず言葉」でしりとりをしましょう。 「あ」あら〜しゃれた服着てはりますな 遠くからでもわかりましたわ
-
お風呂の温度、何℃にしてますか?
みなさん、家のお風呂って何℃で入ってますか? ぬるめのお湯にゆったり…という方もいれば、熱いのが好き!という方もいるかと思います。 我が家は平均的(?)な42℃設定なのですが、みなさんのご家庭では何℃に設定していますか?
-
関数から配列を返すには?
C言語・C++・C#
-
C言語を使って、ファイルの読み込みをして切り出して2次元配列に格納した
C言語・C++・C#
-
C言語のポインターに関する警告
C言語・C++・C#
-
-
4
c言語でのfscanfについて
C言語・C++・C#
-
5
C++ 数値データファイルから2次元配列への格納法
C言語・C++・C#
-
6
バッファとは何ですか
C言語・C++・C#
-
7
ファイルから読み取った改行文字を消す方法
C言語・C++・C#
-
8
ファイルから読み込んだデータを構造体に格納できますか?
C言語・C++・C#
-
9
Enterキーを押されたら次の処理に移るという事をしたい。
C言語・C++・C#
-
10
fgetsで拾われる改行文字を削除したい
C言語・C++・C#
-
11
Cで2次元配列にCSVファイルを格納するには?
C言語・C++・C#
-
12
C言語で複数列のデータを1列のみ読み込みたい
C言語・C++・C#
-
13
C言語で、メモリを解放しないで終わるプログラム
C言語・C++・C#
-
14
fgetsなどのときのstdinのバッファを消すには?
C言語・C++・C#
-
15
改行までの一文字ずつのファイル読み込み
C言語・C++・C#
-
16
<unistd.h>をVisualStudioでつかえるようにする
C言語・C++・C#
-
17
2次元配列の文字列"の初期化方法"
C言語・C++・C#
-
18
unsigned long long 型のフォーマット指定子
C言語・C++・C#
-
19
String^の^自体が何を意味しているのか、わかりません。
C言語・C++・C#
-
20
ファイル書込みで一行もしくは部分的に上書きする
PHP
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・【大喜利】【投稿~11/22】このサンタクロースは偽物だと気付いた理由とは?
- ・お風呂の温度、何℃にしてますか?
- ・とっておきの「まかない飯」を教えて下さい!
- ・2024年のうちにやっておきたいこと、ここで宣言しませんか?
- ・いけず言葉しりとり
- ・土曜の昼、学校帰りの昼メシの思い出
- ・忘れられない激○○料理
- ・あなたにとってのゴールデンタイムはいつですか?
- ・とっておきの「夜食」教えて下さい
- ・これまでで一番「情けなかったとき」はいつですか?
- ・プリン+醤油=ウニみたいな組み合わせメニューを教えて!
- ・タイムマシーンがあったら、過去と未来どちらに行く?
- ・遅刻の「言い訳」選手権
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・【お題】NEW演歌
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語 配列の長さの上限
-
配列を使わずに、変数名を動的...
-
メモリの初期値
-
複数の選択範囲の行番号を個別...
-
C言語初心者 ポインタについて...
-
C言語 配列の再初期化
-
C言語で特定列だけを抽出して配...
-
unsigned char配列への入力の仕方
-
C++ vectorに配列をプッシュしたい
-
VBでC言語のポインタみたい...
-
C# Listを使わずに2次元配列の...
-
C# 配列の変数宣言について。
-
なぜ配列は0から始まるのです...
-
テキストファイルから文字列を...
-
先頭アドレスとは何ですか?
-
C++、コンストラクタの引数の数...
-
VB.NET 構造体の配列の検索機能...
-
配列で格納したものをmsgboxで...
-
プログラムが書けません。
-
【Mathematica】 Protectされて...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語 配列の長さの上限
-
配列を使わずに、変数名を動的...
-
先頭アドレスとは何ですか?
-
C# 配列の変数宣言について。
-
配列で格納したものをmsgboxで...
-
C# Listを使わずに2次元配列の...
-
VBで構造体の配列を関数に渡す...
-
テキストファイルから文字列を...
-
C言語で特定列だけを抽出して配...
-
Excel、VBAのユーザーフォーム...
-
【C言語】配列の中に配列を入れ...
-
配列を含む構造体の初期値について
-
unsigned char配列への入力の仕方
-
複数の選択範囲の行番号を個別...
-
【速いブラインドタッチ】手を...
-
配列の参照渡しで型が一致しま...
-
ExcelVBAで質問です。離れた二...
-
VB.NET 構造体の配列の検索機能...
-
VBでC言語のポインタみたい...
-
Redimした動的配列はEraseする...
おすすめ情報