C言語を今日から始めたじいさんです。
宜しくお願い致します。

メモ帳を使って3行ほどの文字列を入力して、text.txtファイルに保存します。
この文字列を読み込んで、1行ずつ印刷しようとしていますが fgetsでtxtファイルの終了条件がわかりません。

while(fgets(row , sizeof( row ) , fp) != NULL){
printf("%s\n , row);
}
fclose( fp );
return 0;

のようにしているのですが、3行印字処理をして異常終了してしまいます。
本に出ている例をそのまま実行しているのですが、うまくいきません。

txtファイルをダンプしてみると各行の後ろに0d 0aたぶんCR,LFが入っていてNULL=00(?)はありません。テキストファイルの作り方に問題があるのでしょうか?
それともfgetsの使い方に誤りがあるのでしょうか?

このQ&Aに関連する最新のQ&A

A 回答 (7件)

txtファイルの3行目の次が空行(改行だけの行)になっていないですか?



3行目の終わりのCRLFの次にもうひとつのCRLFがないか、ダンプで確認してみて下さい。
    • good
    • 0
この回答へのお礼

0d 0aがCR,LFならば、3行目の終わりの0d 0aのみで
もうひとつの0d 0aはありませんでした。
ダンプからすると変なコード等は一切はいっていないのですが、
もう一度、作成しなおしてみたら動いてしまいました。
正常に動いたファイルのダンプと全く同じなのですが???

これ以上は初心者なのでギブアップです。
色々とアドバイス頂き有難う御座いました。

お礼日時:2009/05/24 00:38

>実際のファイルはカンマであることを確認しました。



ということは、データファイルの内容は正しいが、
#3さんの回答への補足で提示されたソースコードだと
実行時に落ちてしまうということですか?

この回答への補足

データが画面に出力され
[NULL]
が最後に出力されて
「問題が発生しました・・・・」
になってしまいます。

補足日時:2009/05/23 23:22
    • good
    • 0

今回の件の原因は、#4さんの回答のとおり、データファイルの形式に問題があったためです。



それはさておき、

>実際はこのようなソースコードになっています。

何だか小出しにされると、困ってしまうのです。
じゃあ、最初に提示されたソースコードは何だったの?それに対する回答はムダだったの?という話です。

この回答への補足

申し訳ございませんでした。
初めてのC言語で、変なコメント等をたくさん入れていたので、
わかりやすくしようとしてかえっておかしくしてしまいました。

補足日時:2009/05/23 23:31
    • good
    • 0

>001,aiueo.05


>003,sasisuseso.55
名前と年齢の区切りがカンマ","ではないですが。

この回答への補足

コピペすれば良かったですね。
新たに入力したので間違えてしまいました。
実際のファイルはカンマであることを確認しました。
どうもすいませんでした。

補足日時:2009/05/23 23:06
    • good
    • 0

fgets()は「読み込むものが無い」、つまりファイル終端に辿り着いたらNULLを返します。


ぱっと見では(#2で修正されてる部分はともかくとして)コード自体に問題はないと思いますが、どのようなtext.txtを読んだらどのように異常が発生しましたか?

この回答への補足

テキストファイルはメモ帳を使って以下のような文字列を入力しています。
001,aiueo.05
002,kakikukeko,99
003,sasisuseso.55
実際のソースコードは
#include <stdio.h>
#include <string.h>
typedef struct list{
char id[3+1];
char name[10+1];
char age[2+1];
}list;
int main(void)
{
list lists[100];
FILE *fp;
char row[20];
char *p;
int i=0;

fp = fopen("./test.txt","r");

if(fp == NULL){
printf("ファイルをオープンできませんでした。\n");
return 1;
}
else{
printf("ファイルをオープンしました。\n");
}


while(fgets(row, sizeof(row), fp) != NULL){
p = strtok(row, ",");
printf("%s\n",p);
strcpy(lists[i].id, p);
p = strtok(NULL, ",");
printf("%s\n",p);
strcpy(lists[i].name, p);
p = strtok(NULL, ",");
printf("%s\n",p);
strcpy(lists[i].age, p);
i++;
}

fclose(fp);
return 0;
エラーメッセージは
「問題が発生したため、xxx.exeを終了します。ご不便をおかけして申し訳ありません」

補足日時:2009/05/23 22:21
    • good
    • 0

ご提示くださったソースコードには、



>while(fgets(row , sizeof( row ) , fp) != NULL){
全角の{ を使っている

>printf("%s\n , row);
" の対応が取れていない

というエラーがありました。これらを修正した下記のコードを使って、
aaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbbb
cccccccccccccccccccc

という内容のtest.textを読込むと、当方の環境では想定どおりの結果を得ました。
お使いの入力ファイルの1行の長さが配列の定義範囲を超えている、というようなことはありませんか?


#include <stdio.h>

int main(void)
{
FILE *fp;
char row[24];

fp = fopen("./test.text", "r");
if (fp == NULL) {
printf("ファイルオープンエラー\n");
return -1;
}
while (fgets(row, sizeof(row), fp) != NULL) {
printf("%s\n", row);
}
fclose(fp);
return 0;
}

この回答への補足

申し訳ございません。
実際はこのようなソースコードになっています。

test.txt
001,aiueo.05
002,kakikukeko,99
003,sasisuseso.55

#include <stdio.h>
#include <string.h>
typedef struct list{
char id[3+1];
char name[10+1];
char age[2+1];
}list;
int main(void)
{
list lists[100];
FILE *fp;
char row[20];
char *p;
int i=0;

fp = fopen("./test.txt","r");

if(fp == NULL){
printf("ファイルをオープンできませんでした。\n");
return 1;
}
else{
printf("ファイルをオープンしました。\n");
}


while(fgets(row, sizeof(row), fp) != NULL){
p = strtok(row, ",");
printf("%s\n",p);
strcpy(lists[i].id, p);
p = strtok(NULL, ",");
printf("%s\n",p);
strcpy(lists[i].name, p);
p = strtok(NULL, ",");
printf("%s\n",p);
strcpy(lists[i].age, p);
i++;
}

fclose(fp);
return 0;

補足日時:2009/05/23 22:09
    • good
    • 0

ソースコードを、全部見せていただけますか?


断片だけを見ても、原因や対策がわからないことがあります。

この回答への補足

以下のようなプログラムです。

#include <stdio.h>
#include <string.h>

int main(void)
{
FILE *fp;
char row[24];

fp=fopen("./test.text","r");
if(fp==NULL){
printf("ファイルオープンエラー\n");
return -1;
}
while(fgets(row , sizeof( row ) , fp) != NULL){
printf("%s\n , row);
}
fclose( fp );
return 0;

補足日時:2009/05/23 20:39
    • good
    • 0

このQ&Aに関連する人気のQ&A

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

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

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qclipboxの使い方を教えて下さい。 動画のダウンロードのやり方が分からなくなりました。 どの項目

clipboxの使い方を教えて下さい。
動画のダウンロードのやり方が分からなくなりました。
どの項目をタップして動画をどうやって探してダウンロード出来るのか、ダウンロード出来た動画のプレイリストの作り方、動画再生等のやり方を知りたいです。
1年前は使っていたのに、1年して改めてインストールして「さあーやるぞー!」と思い挑んだんですが記憶してるやり方では何も出来ませんでした。
幼い子供でも分かるように詳しく教えて頂けたら助かります。
宜しく御願い致します。

Aベストアンサー

clipboxの公式サイトに使い方が出ています。
これ以上に分かりやすい資料はないと思います。
http://clipbox-official.com/usages/p/dl1

Qfgets((char*)&rbof,sizeof(ADR),fp) != NULL )

第2種情報処理技術者試験 平成7年春 午後 問7
http://www.bohyoh.com/ITEE/C/1995A07.html


中盤の
「while (fgets( (char*)&rbuf , sizeof(ADR), fp )!= NULL ) 」
が読めません

(char*)&rbuf , sizeof(ADR), fp
ファイルポインタからsizeof(ADR)サイズの分だけ取り出した文字を変数(char*)&rbufにほおりこむ

これが自分なりの解釈です
ですが「(char*)&rbuf」が意味不明。。。


根本的に解釈が間違っているのだと思います


詳しくわかる方教えてください

Aベストアンサー

rbufはADR型の構造体です。

&rbufは、ADR型の構造体rbufの実体へのポインタです。

つまり「&rbuf」は「(ADR *)&rbuf」です。

fgetsの引数は「char *」「size_t」「FILE *」ですから
fgets(&rbuf,sizeof(ADR),fp)
と書くと「char *」であるべき引数に「ADR *」を渡す事になります。

すると、コンパイラは「なにしてんねん。fgetsの1番目の引数はchar *やねんで。ADR *を渡されても困るねん」って言って、エラーになります。

なので「&rbufはADR *じゃなくて、char *だと思ってくれ」と書く必要があります。それが「(char *)&rbuf」と言う書き方です。

これを「型キャスト」と言います。

以下の例を参考に、考えてみて下さい。

typedef struct {
  (略)
} ADR;
(略)
  union PTR {
    char *char_ptr;
    ADR *adr_ptr;
  } ptr;
  ADR rbuf;
(略)
  ptr.adr_ptr = &rbuf;
(略)
  fgets(ptr.char_ptr,sizeof(ADR),fp);

この例は、ADR *とchar *を共有する共用体「ptr」を使用し「rbufのポインタ」を「ADR *型のadr_ptr」で受け取り、そのポインタを「char *型のchar_ptr」で参照しています。

つまり「型キャストを使用しないで書くと、上記のように共用体を使うなど、面倒な事をしなきゃなんない」のです。

これが、型キャストを使えば、
typedef struct {
  (略)
} ADR;
(略)
  ADR rbuf;
  fgets((char *)&rbuf,sizeof(ADR),fp);
だけで済んじゃうのです。

rbufはADR型の構造体です。

&rbufは、ADR型の構造体rbufの実体へのポインタです。

つまり「&rbuf」は「(ADR *)&rbuf」です。

fgetsの引数は「char *」「size_t」「FILE *」ですから
fgets(&rbuf,sizeof(ADR),fp)
と書くと「char *」であるべき引数に「ADR *」を渡す事になります。

すると、コンパイラは「なにしてんねん。fgetsの1番目の引数はchar *やねんで。ADR *を渡されても困るねん」って言って、エラーになります。

なので「&rbufはADR *じゃなくて、char *だと思ってくれ」と書く必要が...続きを読む

QE-TAXについて動画による使い方を知りたい。

問い合わせ先が違うかもしれませんが確定申告のE-TAXの使い方について「動画」で詳細を解説したWEBサイトをご存じの方が
有ればURLを教えて下さい。「税務署から返事が来ない為」

使用OS:VISTA HP SP-2
使用ブラウザ:IE-8

Aベストアンサー

国税局のHPに使い方が載ってます。

参照ください

参考URL:http://www.nta.go.jp/tetsuzuki/shinkoku/shotoku/tokushu/tvcm.htm

QSendMessage(hW,WM_CREATE,0,0);を

SendMessage(hW,WM_CREATE,0,0);
を実行するとシステムがWM_DOWNやWM_CHARを発行しなくなるみたいです
というのはそれ以降キー入力を無視するようになるのです
いったんアプリをアイコン化してウィンドウ化するとWM_DOWNやWM_CHARを発行するようになります
WM_CREATEを送ってもWM_DOWNやWM_CHARを発行しなくなるのを阻止するために何か方法はないでしょうか?

Aベストアンサー

>プログラムのイニシャライズのために送ったのですが送らないで住むプログラムに変更しました

普通はそんな方法はとりません。
システムが何をするか分からないからです。

自分でメッセージを定義して、初期化処理を行うようするためのメッセージを送るほうが無難です。
WM_CREATEと同じ処理を初期化処理として行わせたいのであれば、初期化処理を関数化して自分で定義したメッセージでも呼び出せばいいのですし。


>作ったプッシュボタンを押してシステムがWM_COMMANDを送ってきた後キー関係のメッセージを送ってくれなくなります

プッシュボタンがキーボードフォーカスを持ってのるでは?

ボタンがキーボードフォーカスを持っていてもキー関連のメッセージを親ウィンドウが受け取りたいのであれば、サブクラス化をするしかないでしょう。

Q近いうちにYouTubeに動画をupしようと思って、 でも使い方がいまいちわからず、 試しにギャ

近いうちにYouTubeに動画をupしようと思って、

でも使い方がいまいちわからず、

試しにギャラリーにあったアーティストの動画を出してしまいました。

そうしたら著作権がなんとかかんとかでブロックされました。

捕まりますか?

試しの動画だったのですぐ消したんですけど...。

Aベストアンサー

捕まりませんよ。そんなことで捕まえていたら、警察はパンクします。

Qdc.TextOut(0 ,0 , *str) ;について

環境 WIN98 VC++6.0 MFC にて

パターンBはOKですが、パターンAだと不正な処理で落ちてしまいます。

どうしてなのかお教えください。

void CFffView::OnPaint()
{
CPaintDC dc(this);
//パターンA
CString* str ;
str = (CString*)("999");
dc.TextOut(0 ,0 , *str) ;

//パターンB
CString aaa ;
aaa = (CString)("999");
dc.TextOut(0 ,0 , aaa) ;
}

Aベストアンサー

両方ダメ。
Aのパターンで動くのは、たまたま。

CString aaa ;
aaa = "999";
dc.TextOut(0 ,0 , aaa) ;

これで十分。

あえてキャストするんだったら、
CString aaa ;
aaa = (LPCSTR)"999";
dc.TextOut(0 ,0 , aaa) ;


aaa=のところでは、ただの代入が行われているわけではありません。
オーバーロードされたオペレータが呼ばれています。


>str = (CString*)m_array.GetAt(i) ;

これは、m_arrayの要素にCString*を入れていて、初めて成り立つ式です。
値をいれているところと、m_arrayの宣言を確認してください。

str = (CString*)("999");
も、
aaa = (CString)("999");
も、リテラル文字列をつっこもうとしています。
リテラル文字列とCStringはまったく別物です。

QDreamweaver 8 の使い方で、音声入りの動画サイト探しています。

 Dreamweaver 8 の使い方についてお願いします。初心者です、書籍と下記サイトを見ながら作成中です。Dreamweaver 8 の使い方で、音声入りの動画サイトがあればご伝授ください。有料で購入品があればご紹介ください。よろしくお願いします。

http://www.dougamanual.com/apps/tools/index.cgi?_cmd=view_select&l=ap&ai=35&g=ap

Aベストアンサー

アップグレードに関しては、アドビのサイトをご参照ください。

http://www.adobe.com/jp/products/dreamweaver/?promoid=BPBRI

Qif ( fp == NULL ){ を if ( fp == 0){ へ変更した場合

http://oshiete.goo.ne.jp/qa/8897349.html
 ですが
if ( fp == NULL ){ を
if ( fp == 0){
 fopen dekina と表示してくれるのでしょうか?
  試す環境がございませんので
 よろしくお願いいたします。

Aベストアンサー

>if ( fp == 0){
> fopen dekina と表示してくれるのでしょうか?

はい、表示してくれます。
NULLは、通常、(void*)0 の値が定義されていますので、実体は0と同じです。
しかし、NULLはポインターに対して定義されているのなので、
if ( fp == NULL) と書いたほうがよいでしょう。
一方、0は数値を表すので、
if (fp == 0)とは、書かないほうがよいでしょう。
int a;
が定義されていたとき、
if (a ==0) は、a(という数値を表す変数)の値が0か否かを判断するので、これでよいですが
if ( a== NULL) は、a(という数値を表す変数)の値がNULLか否かを判断するので、
違和感がありますから、使用しないほうが良いでしょう。

Q携帯動画変換君の使い方…

カテ違いだったらスイマセン。

携帯動画変換君の使い方を教えてください!!
SO903iにyoutubeの動画を入れたいのですがやり方が分かりません…
http://so903i.jugem.jp/?page=1&cid=3
↑このサイトの2番の手順通りにやっても○○.mqvになりません!!!
お願いします。教えてください!!

Aベストアンサー

FOMAならわざわざ.mqvファイルを.3gpにしなくても、セットアップの上から3番目「3GPPファイル、音声AAC形式一般設定」を選択して変換すればいいと思いますが…。あとは上記のサイトの方法で見れるかと思います。ところでQuickTimeはインストールされていますか?

Qint i,j; \n i=0,j=5;

int i,j;
i=0;
j=5:
と書いてあるソースは普通ですが、
int i,j;
i=0,j=5:
と書いてあるソースもあります。
後者はC++の正しい書式ですか?

カンマ演算子というのは後者のカンマのことですか?

Aベストアンサー

 正しい書式です。

i=0,j=5;
 における、「,」をカンマ演算子といいます。2項の演算子です。カンマで区切られた演算を「左から順番に」実行し、最後の演算を結果として返します。
 したがって、例の文であれば、i=0を実行し、次にj=5を実行。そして、j=5の結果の5を結果として返します。
 ・・・
 が、本来的には、あまり、例のような使い方はしませんね。よく見られるのは、次のような場合です。

 for (i=0,j=0 ; i < 50 ; ++i,++j) {

 のような形でよく見られます。for文の各式は、一つの式でなければならないので、こんな書き方をするわけです。初期化と更新部が一つにまとまり、ループが読みやすくなるのが利点かな。


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング

おすすめ情報