ファイルの中身が例えば
600
0.6
3.5
となっているとき,
fscanfで読み込むと改行\nを読み込んでくれる場合と読み込まない場合がありませんか?
また,これだったら,経験から
fscanf(fp,"%d",&a);
fscanf(fp,"%f",&b);
fscanf(fp,"%c",&c); // \nの読み飛ばし
fscanf(fp,"%f",&d);
fscanf(fp,"%c",&e); // \nの読み飛ばし
でやるとできそうですが,fscanf(fp,"%d",&a);のあとの\nの読み飛ばしがいらないのは何故ですか?
No.5ベストアンサー
- 回答日時:
#1です。
scanf()系は、
空白文字(スペース、改行、タブなど)の前まで読み込む
↓
最後の改行文字はバッファの中に残っている
↓
読み込む
↓
空白文字はスペースとして扱われるため、
書式が"%c"以外なら読み込むが無視して次の行のものを読み込む。
書式が"%c"ならば、残っている改行文字を変数に入れてしまう
ということです。
#3の補足のソースで言えば、
fscanf( fp, "%d", &a ); //1行目の600を変数aに格納
//→バッファに最後の改行が残る
fscanf( fp, "%f", &b ); //書式が"%f"なので、バッファに残った改行を無視
//→2行目の0.6を変数bに格納
//→バッファに最後の改行が残る
fscanf( fp, "%f", &c ); //書式が"%f"なので、バッファに残った改行を無視
//→3行目の3.5を変数cに格納
//→バッファに最後の改行が残る
fscanf( fp, "%c", &d ); //書式が"%c"なので、バッファに残った改行を変数cに格納
fscanf( fp, "%c", &e ); //4行目の"XYZ"の"X"を変数eに格納
//→バッファに"YZ"と改行コードが残る
fscanf( fp, "%c", &f ); //バッファに残っている"YZ"と改行コードから
//最初の"Y"を変数fに格納
ということです。
http://www9.plala.or.jp/sgwr-t/c/sec05.html#s5-4
も参考にしてください。
> C++の入門書にコアダンプっていうことばがあったんですけどこれはどんな意味かご存知ですか?
下のURLが参考になるかと。
http://www.atmarkit.co.jp/icd/root/39/63458339.h …
http://e-words.jp/w/E382B3E382A2E38380E383B3E383 …
参考URL:http://www9.plala.or.jp/sgwr-t/c/sec05.html#s5-4,http://www.atmarkit.co.jp/icd/root/39/63458339.h …
この回答への補足
%c以外で%sのときはどうなるのかと思い、下のテストプログラムを試しました。変な結果になっています。これはどのように説明がつくのでしょうか?
○テストプログラム
#include<stdio.h>
#include<stdlib.h>
int main()
{
int a;
float b, c;
char d[10], e[10], f[10];
FILE* fp;
fp = fopen( "datafile.txt", "r" );
fscanf( fp, "%d", &a );
fscanf( fp, "%f", &b );
fscanf( fp, "%f", &c );
fscanf( fp, "%s", d );
fscanf( fp, "%s", e );
fscanf( fp, "%s", f );
printf( "a %d\n", a );
printf( "b %f\n", b );
printf( "c %f\n", c );
printf( "d %s\n", d );
printf( "e %s\n", e );
printf( "f %s\n", f );
fclose(fp);
return 0;
}
●注;datafile.txtの中身
600
0.6
3.5
XYZ
○実行結果
a 600
b 0.600000
c 3.500000
d XYZ
e フフフフフフフフフフフフXYZ
f フフフフフフフフフフフフフフフフフフフフフフフフXYZ
丁寧な回答ありがとうございました。とても分かりやすく理解できました!!原因がすっきりしました。
コアダンプについてもURLを載せて頂きありがとうございました。
No.8
- 回答日時:
#5です。
#5の補足のソースを拝見しました。
まず、最初に言っておきますが、Cでは、変数を宣言した時点では、
変数は初期化されておらず、ごみが入っています。
#5の補足のソースのfscanf()の4行目から説明しますと、
(3行目までは、#5と同じです)
fscanf( fp, "%s", d );//書式が"%s"なので、バッファに残った改行を無視
//→ファイル4行目の"XYZ"を変数dに格納
//→バッファに最後の改行が残る
fscanf( fp, "%s", e );//書式が"%s"なので、バッファに残った改行を無視
//→ファイルがEOF(ファイルの終わり)
//まで達したので読み込まない
//変数eには何も入らない(ごみが入ったまま)
fscanf( fp, "%s", f );//ファイルがEOFまで達したので読み込まない
//変数fには何も入らない(ごみが入ったまま)
ですから、実行結果のeとfについては、たまたま変数に入っていたごみのデータ
を表示していることになります。
このことは、変数を初期化するなり、
最初にprintf()で変数の中身を表示するなりで確認できるかと思います。
ちなみに、私の環境では実行結果がこうなりました。(コンパイラ bcc)
a 600
b 0.600000
c 3.500000
d XYZ
e 漾
f
%sも改行を無視してくれるんですね。
XYZを読み込んだあとEOFとなることを見落としていました。それでごみが残ったままになってしまっていたんですね。よく分かりました!!
長々と本当にありがとうございました。今まで抱いていた疑問が一気に解消できました!またC言語の事で分からない事があったらよろしくお願いします。
No.7
- 回答日時:
#3です。
>「fscanfで読み込むと改行\nを読み込んでくれる場合と読み込まない場合がありませんか?」
と最初の質問で言ったできごとをちゃんと起こす事ができました。
>補足回答よろしくお願いします。
うーむ。再現しましたね。私の環境でも再現しました。
>このようにどうやら%cで読み込む時になんか変なことが起こってしまうようなんです。
>何故なのでしょうか??
#3で「たぶん、正常なデータが入ってなかったのだと思います。」と回答しましたが、これは誤りでした。
#5の方が回答を書かれていますが、まさしくその通りです。お詫びして、訂正致します。
No.6
- 回答日時:
#1、5です。
#5で訂正があります。
#3の補足のソースのfscanf()の4行目は、
fscanf( fp, "%c", &d ); //書式が"%c"なので、バッファに残った改行を変数dに格納
です。
(変数cに格納 ではありません・・・)
No.3
- 回答日時:
>ダンプって何ですか?
ファイルの内容を文字列ではなく、文字列のコードで出力することです。
たとえば、先頭の行は
600改行 ですので、文字列のコードを16進数で表示すると
3630300d0a と表示されるはずです。
このことにより、格納されている文字がなんなのかを正確に判断することができます。
空白の文字は見た目では半角のスペースか全角のスペースかタブなのか改行なのかが判りません、このような時に16進数で文字列のコード表示すると違いがはっきりと判ります。
このような表示が出来るエディタを「バイナリエディタ」と読んでいますので、そのエディタを使用して見てください。(無償でダウンロード可能なものが、たくさんあります)
>でも他のプログラムではそうならないときがあったんだけ>どなぁ?
>どうしてでしょうか?
たぶん、正常なデータが入ってなかったのだと思います。(例えばデータの後に全角のスペースがあると正しく動作しません)
そのファイルが、まだあれば、バイナリエディタで内容を参照してみてください。
この回答への補足
このようにどうやら%cで読み込む時になんか変なことが起こってしまうようなんです。
何故なのでしょうか??
「fscanfで読み込むと改行\nを読み込んでくれる場合と読み込まない場合がありませんか?」
と最初の質問で言ったできごとをちゃんと起こす事ができました。
補足回答よろしくお願いします。
○問題発生のテストプログラム
#include<stdio.h>
#include<stdlib.h>
int main()
{
int a;
float b, c;
char d, e, f;
FILE* fp;
fp = fopen( "datafile.txt", "r" );
fscanf( fp, "%d", &a );
fscanf( fp, "%f", &b );
fscanf( fp, "%f", &c );
fscanf( fp, "%c", &d );
fscanf( fp, "%c", &e );
fscanf( fp, "%c", &f );
printf( "a %d\n", a );
printf( "b %f\n", b );
printf( "c %f\n", c );
printf( "d %c\n", d );
printf( "e %c\n", e );
printf( "f %c\n", f );
fclose(fp);
return 0;
}
●注;datafile.txtの中身
600
0.6
3.5
XYZ
○実行結果
a 600
b 0.600000
c 3.500000
d
e X
f Y
補足回答ありがとうございました。
なんかC++の入門書にコアダンプっていうことばがあったんですけどこれはどんな意味かご存知ですか?
正常なデータが入っているにもかかわらず,
問題を発生させることに成功しました!
補足回答のプログラムをご覧下さい!!
No.2
- 回答日時:
通常は、全て正常データであれば、
fscanf(fp,"%d",&a);
fscanf(fp,"%f",&b);
のあと
fscanf(fp,"%c",&c); // \nの読み飛ばし
を行う必要はありません。
但し、
600のデータが
600Xとか600の後に全角スペース
とかになっていると、次のデータを正しく読み込めません。
1.各データは全て正常なデータであること。
2.各データの後は改行だけであること。
上記の2条件が必ず成立するデータでも、\nの読み飛ばしが必要でしょうか。
また、このテスト環境は、windowsでしょうかunixでしょうか。windowsの場合、正しい改行になってますか。(16進ダンプで0x0d0aが表示されますか)
上記の点をチェックしてみて下さい。
この回答への補足
○#1から\n読み飛ばしをなくしたテストプログラム
#include<stdio.h>
#include<stdlib.h>
int main()
{
int a;
float b, d;
FILE* fp;
fp = fopen( "datafile.txt", "r" );
fscanf( fp, "%d", &a );
fscanf( fp, "%f", &b );
fscanf( fp, "%f", &d );
printf( "a %d\n", a );
printf( "b %f\n", b );
printf( "d %f\n", d );
fclose(fp);
return 0;
}
●注;datafile.txtの中身
600
0.6
3.5
○実行結果
a 600
b 0.600000
d 3.500000
あらら??
ちゃんと綺麗になっています。読み飛ばしがいらない!?ということを意味している!?
??????
でも他のプログラムではそうならないときがあったんだけどなぁ?
どうしてでしょうか?
回答ありがとうございました。
>また、このテスト環境は、windowsでしょうかunixでし>ょうか。windowsの場合、正しい改行になってますか。>(16進ダンプで0x0d0aが表示されますか)
Windowsです。
ダンプって何ですか?
No.1
- 回答日時:
参考になりそうなURL。
http://www.bohyoh.com/CandCPP/C/Library/fscanf.h …
http://homepage2.nifty.com/tenk/cgokai/scanf.htm
※scanfとfscanfは標準入力かファイル入力かが違うだけで、2つは等価です。
http://www9.plala.or.jp/sgwr-t/c/sec05.html#s5-4
http://www.catnet.ne.jp/kouno/c_faq/c12.html#20
基本的には、fscanf()ではなく、fgets()を使った方がいいです。
この回答への補足
○作成したテストプログラム
#include<stdio.h>
#include<stdlib.h>
int main()
{
int a;
float b, d;
char c, e;
FILE* fp;
fp = fopen( "datafile.txt", "r" );
fscanf( fp, "%d", &a );
fscanf( fp, "%f", &b );
fscanf( fp, "%c", &c ); // \n
fscanf( fp, "%f", &d );
fscanf( fp, "%c", &e ); // \n
printf( "a %d\n", a );
printf( "b %f\n", b );
printf( "c %c\n", c );
printf( "d %f\n", d );
printf( "e %c\n", e );
fclose(fp);
return 0;
}
●注;datafile.txtの中身
600
0.6
3.5
○実行結果
a 600
b 0.600000
c
d 3.500000
e フ
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- フィナンシャルプランナー(FP) FP検定は「エフピーけんてい」で読み方会ってますか汗 2 2022/04/20 22:37
- PHP ファイルの書き込みについて教えて下さい。 1 2023/03/20 12:01
- 個人事業主・自営業・フリーランス 都会に行けば、フルコミの営業とかあるらしいけど、それって完全にフリーランスやないですか? 普通、独立 1 2023/04/10 16:30
- Excel(エクセル) VBA フォルダ見える化のコードについて 2 2023/06/19 15:04
- フィナンシャルプランナー(FP) FPやDCプランナーなどの資格で試験の出題内容の改定は毎年何時ですか?古いテキストは使えませんか? 2 2022/11/05 14:23
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- PHP PHPでテキストファイルに保存した時の改行問題 1 2022/11/19 15:07
- C言語・C++・C# プログラミングの問題です。至急教えてください。 /***から***/の部分をプログラミングにしてほし 1 2022/10/13 11:48
- フィナンシャルプランナー(FP) FP相談に、本人確認は必須ですか? 3 2022/04/25 11:03
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBAのコマンドボタンの文字列の...
-
エスケープ文字の復帰(¥r)と...
-
ファイルから読み取った改行文...
-
ソースコードの1行が長いとき...
-
COBOLの改行
-
エクセルVBA 文字列領域が不足...
-
ToolTipTextの改行はできないの...
-
JavaMail,本文中の改行について
-
aspで作成するcsvファイルで、e...
-
PHPExcelでのexcelヘッダ編集に...
-
C#における改行を含む文字の探索
-
【VBA】エクセルで最後の不要な...
-
1行ごとに取得して、その改行...
-
項目内改行があるCSVの書式設定...
-
文字列型変数に1024を超えた文...
-
JAVA System.out.println の ...
-
textarea内での改行がechoで反...
-
awkで改行を除いて文字列を抜き...
-
VBでcsv読込TextFieldParser...
-
改行コード(CR/LF)の設...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBAのコマンドボタンの文字列の...
-
ソースコードの1行が長いとき...
-
エスケープ文字の復帰(¥r)と...
-
ファイルから読み取った改行文...
-
JAVA System.out.println の ...
-
C++で空Enterの入力を判...
-
COBOLの改行
-
テキストファイルから改行コー...
-
改行について
-
【VBA】エクセルで最後の不要な...
-
1行ごとに取得して、その改行...
-
jsp 改行コードで改行させて表...
-
VBAでCSVをExcelに取り込む時に...
-
エクセルVBA 文字列領域が不足...
-
最終行の改行について
-
改行を読み飛ばす
-
コンボボックスの項目中に改行を
-
テキストボックス行の桁数を制...
-
ExcelVBAでメールを作成してメ...
-
JavaMail,本文中の改行について
おすすめ情報