fgets( ) はファイル終端に行くと0を返すらしいけど
それ以外の場合は何を返すんですか?

if( fgets( buf, 10, fp ) == 0 ) break;

のように、fgets( ) の返り値をそのまま使うことはできたけど
試しに、

char ret[255];
ret = fgets(buf, 10, fp);

とするとコンパイルエラーでした。

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

A 回答 (5件)

すみません、根本的な回答ではありませんでしたね。


バッファを読み込めた時は、読み込んだバッファの先頭ポインタを返します。
ファイルの終わり(EOF)や失敗した時はNULLを返します。
    • good
    • 0
この回答へのお礼

バッファの先頭ポインタを返すんですか。
それでバッファには char* を指定しなくては
いけなかったんですね。

お礼日時:2002/03/20 21:02

> fgets( ) はファイル終端に行くと0を返すらしいけど



既に回答が出ていますが、この表現にちょっと引っかかったので一言。

「0」と「'\0'」と NULL を、混同されていませんか?
大抵の処理系では NULL は 0 としても動きますが、規格上保証されているものではありません。(気の利いたコンパイラなら、警告が出るはずですが…)

> if( fgets( buf, 10, fp ) == 0 ) break;

ここは、きちんと「if (fgets(buf, 10, fp) == NULL) break; と書きましょう。
    • good
    • 0

すみません、madmanさんの御回答にちょっとだけ補足させて下さい。


質問者の方は恐らくretはその文字列領域の先頭アドレスを示す、つまりret自身はchar*扱いだからというつもりで御使用になったのだと思いますが、実はこちらは定数です。
同じchar*でもmadmanさんの示された例では変数領域として用意されていますが、A__さんのお使いになったretはretという文字列領域の先頭アドレス以外とはなり得ない定数なのです。
従って、定数を書き換えることはできませんから勿論コンパイルエラーになるわけです。
    • good
    • 0
この回答へのお礼

ありがとうございます。
buf も ret も char[] で宣言していました。

お礼日時:2002/03/20 21:06

fgets()の返り値は、読込が成功すると、bufのポインタを返します。


ファイルの終端、または失敗した場合、NULLを返します。

ファイルの終端と失敗の区別はfeof()を使うことにより可能です。

if( fgets( buf, 10, fp ) == 0 ) {
if( feof( fp ) != 0){
//ファイル終端
}else{
//エラー
}
}
    • good
    • 0

char *fgets(char *s, int size, FILE *stream);


ですので、
char *ret;
ret = fgets(buf, 10, fp);
としてください。
    • good
    • 0

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

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

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

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

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

Qfgetsで拾われる改行文字を削除したい

お世話になります

 C言語初心者のものです。今課題でC言語を用いたプログラミングを
Fedora上でやっています。問題は、fgetsでテキストファイルから、取得
した文字列の中から改行文字を削除できないことです。文字変数のアド
レスはわかっているのですが、終端文字に置換しようとすると、セグメ
ントエラーになってしまいます。これは如何にして解決すべきでしょう
か。よろしくお願いします。

Aベストアンサー

ポインタとかアドレスとか、C言語の用語としてあるものを別の意味に使うとまぎらわしいです。

「ポインタ」「アドレス」と言われたら、 この例なら str, str+i が思い浮びます。
「文字変数のアドレス」だと
char c ;
に対しての
&c
が思い浮びます。

配列なら「添字」、意味的には「x文字目」ですね。

> for(i=0;;i++){
> if(*(str+i)=='/n') {
> *(str+i)='\0';
> break;
> }
> }
/nが\nの間違いなら、この方法で半分正解です。もう少し広い範囲(可能なら全体)で見ないことにはなんとも言えません。
fgetsが最大文字数に達したり、ファイルの最後になったりで、strに改行文字が含まれない場合には、このループは止まりません(Segmentension Falutになって止まる)

・そのような状態になってないか、予めチェックする
・ループを終了させる仕組みを用意しておく
: forの終了条件を記述する、for中で if(*(str+i)=='\0') { break;} 等としておく、等
といった対策が必要です。


あと細かいところを言えば
・strを配列で用意したなら *(s+i)じゃなくてs[i]でいいんじゃないかな
・あるいは char *pみたいにしておいて、 iのループでなく pでループを組む( for(p=str;*p!='\0';p++) )とか。

ポインタとかアドレスとか、C言語の用語としてあるものを別の意味に使うとまぎらわしいです。

「ポインタ」「アドレス」と言われたら、 この例なら str, str+i が思い浮びます。
「文字変数のアドレス」だと
char c ;
に対しての
&c
が思い浮びます。

配列なら「添字」、意味的には「x文字目」ですね。

> for(i=0;;i++){
> if(*(str+i)=='/n') {
> *(str+i)='\0';
> break;
> }
> }
/nが\nの間違いなら、この方法で半分正解です。もう少し広い範囲(可能なら全体)で見ないことにはなんとも言えません。
fgetsが...続きを読む

Qfgetsなどのときのstdinのバッファを消すには?

こんにちは,今C(C++でない)を使用しています。
たとえば,
char str[20]
fgets(str,sizeof(str),stdin)
としたときに20字以上を打つと,stdinのバッファに20字以上の分が残ったままになります。

C++などでは
fflush(stdin)で,うまくいきますが,普通のCでは対応がされていないみたいでうまくいきません。

よろしくお願いします。

Aベストアンサー

あ,テキスト入力だからこんな大掛かりなことしなくてもいいんだ.
末尾に'\n'が出るまで掃出せばいいんですよね.

fgets(str, sizeof(str), stdin);
if ( str[strlen(str)-1] != '\n' ){
while( getchar() != '\n' );
}

でいいんだ.失礼しました.

Qfgets関数のEOFの扱い方について

fgets関数のEOFの扱い方って、
ファイルの終わり(EOF)を検出し、かつ配列に1文字も読み取れなかった場合、配列の内容を変化させずに残しNULLを返す。配列に1文字以上読み取れた場合、EOFをバッファに残し配列に'\0' を追加する。その後、EOFを読み取り終了。
であってますか?

Aベストアンサー

★回答者 No.1 です。追記。
・回答者 No.2、No.3 さんの通り『EOF』は『EOFコード(^Z)』をバッファに
 残すわけではありませんよ。→イメージ的には『あっている』のですよ。あくまで。
・厳密には、回答者 No.3 さんのアドバイスどおりです。
・つまり、『fgets』関数で1文字も読み取れなかった場合には、『ファイル終了』
 というフラグ情報をセットするのです。→EOFをバッファに残す感じですね。
・そのため、次に読み込んだ場合に、このフラグ情報を『EOF』として読み取って
 終了するわけです。→『fgetc』関数も同じ仕組みです。
・また、途中でエラーが発生した場合にも『fgets』関数は『NULL』を返します。
・この場合は、『エラー発生』のフラグ情報をセットしてから『NULL』を返すのです。
・よって『NULL』が返される多くの場合は、『ファイル終了』ですが、エラーが発生
 しても『NULL』が返されます。そこで、『feof』関数や、『ferror』関数でどちらか
 判定するわけです。feof(fp) や ferror(fp) で 0 以外が返されたら『ファイル終了』
 や『エラー発生』と判別します。→厳密にエラー発生の対策をする場合はね。
・あと、一度『エラー発生』のフラグがセットされると『fseek』関数などではその
 情報はクリアされません。→『clearerr』関数でクリアします。
・『ファイル終了』情報はファイル・ポインタの位置を変える『fseek』関数などで
 その情報がクリアされます。
・『ファイル終了』、『エラー発生』のフラグ情報などは、それぞれのファイル
 ポインタで管理されています。

最後に:
・イメージ的には、最後に『EOFを読み取り終了』という事になります。
・質問者さんは、プログラムや、テストプログラムを作って動作に疑問を持ったのですね。
 そうでないと、『EOF』を検出して、1文字も読み取れなかった場合、配列内容が変化
 しない事を推測できませんものね。
・そこで、最後にアドバイスします。
・疑問があったら簡単なテスト・プログラムを作ってみて確認することがとても大事ですよ。
 動作確認すると『fgets』関数などの仕組みをより理解できますから。
・以上。おわり。

★回答者 No.1 です。追記。
・回答者 No.2、No.3 さんの通り『EOF』は『EOFコード(^Z)』をバッファに
 残すわけではありませんよ。→イメージ的には『あっている』のですよ。あくまで。
・厳密には、回答者 No.3 さんのアドバイスどおりです。
・つまり、『fgets』関数で1文字も読み取れなかった場合には、『ファイル終了』
 というフラグ情報をセットするのです。→EOFをバッファに残す感じですね。
・そのため、次に読み込んだ場合に、このフラグ情報を『EOF』として読み取って
 終了するわけです。→『f...続きを読む

Qint型からchar型への変換

タイトル通り、int型からchar型への変換の仕方がわかりません!><
どうしたらいいのでしょうか?

Aベストアンサー

#include <stdio.h>


char buf[5];
int no;

no = 10;
sprintf(buf, "%d", no);

Qscanf("%s", buf);でスペースを含んだ文字

コンソールプログラムで
scanf("%s", buf);
を使用してユーザに入力された文字によって処理を行いたいのですが、このままではスペースを含む文字列がスペースの手前で切られてしまいます。
C:\Program Filesなどを入力可能にさせたい場合にはどのようにするのがベターですか?

Aベストアンサー

お任せください!
そもそもscanfを使うというのはお勧めでは
ありません。scanfは文字+改行文字が入力
されないと完了しないためです。
が、それは良しとしましょう。
scanfの書式ですが、

int n = scanf("%[^\r\n]",buf);

という便利な書式があります。
perlでもおなじみの書式ですね。
上記の山文字"^"より前が読み込ませたい文字の集まりで、ハイフン指定が出来ます。
"^"より後ろが読込みを停止させたい文字の集まりです。上記の指定は復帰改行以外の文字が現れるまで読み込みます、という書式です。
下記のような指定も出来ます。

int n = scanf("%[a-zA-Z0-9\\: \t^\r\n]",buf);

なお、戻り値は読み込んだ項目数ですので、
if(n >= 1)
{
}
で判断できますね。

Qfopne で失敗する原因

fopenで失敗する原因とはなんですか?

Aベストアンサー

#1の方の回答に加えて...

・ファイル名の文字列がでたらめ(存在するかどうか以前の問題)
・指定したファイル名が実はディレクトリだった。
・ファイル名に空ポインタまたは不正なポインタを渡した。
・オープンモードに空ポインタまたは不正なポインタを渡した。
・オープンモードの形式が不正
・メモリ不足でバッファ(実装によってはファイル記述子も)の割り付けに失敗した。
・同名の関数またはマクロをユーザーが定義した。
・関数原型なしで呼び出した。
・他のスレッド等で、同じファイルに対する操作中(再入可能とは限らないので)

QC言語で文字列をかえす正しい書き方が知りたいです?

C言語で次の警告が表示されます。
文字列を返したいのですが、正しい書き方はどのようにすれば良いのでしょうか?


jci.h(20) : warning C4172; ローカル変数またはテンポラリのアドレスを返します。


char *test(char *a, int b)
{
char str[BUFSIZ];
return str; <------

}

Aベストアンサー

再入可能にするかどうかで、回答は変わります。

A.2度呼び出した場合に前のデータを破壊してもよいケース(再入不可能)

char *test(...)
{
static char str[BUFSIZ]; // static指定でメモリは静的に確保されます。

...

return str;
}

B.2度呼び出した場合に前のデータを破壊しないケース(再入可能)
B-1.mallocを使ってもいいケース
char *test(...)
{
char *str;
str = malloc(BUFSIZ);
if(str == NULL) return NULL; // エラー

...

return str;
}
この場合は、呼び出し元でちゃんとfreeしましょう。

B-2.呼び出し元でメモリを確保するケース
(注意:同じアドレスを指定して複数回呼び出すと、メモリ内容は当然破壊されます)
char *test(char *str, ...)
{

...

return str;
}
これは#1の方の回答と同じです。

B-3.B-1/B-2の複合
(注意:NULL以外の同じアドレスを指定して複数回呼び出すと、メモリ内容は当然破壊されます)
char *test(char *str, ...)
{
if(str == NULL)
{
str = malloc(BUFSIZ);
if(str == NULL) return NULL; //エラー
}

...

return str;
}

こんなところですかね。

再入可能にするかどうかで、回答は変わります。

A.2度呼び出した場合に前のデータを破壊してもよいケース(再入不可能)

char *test(...)
{
static char str[BUFSIZ]; // static指定でメモリは静的に確保されます。

...

return str;
}

B.2度呼び出した場合に前のデータを破壊しないケース(再入可能)
B-1.mallocを使ってもいいケース
char *test(...)
{
char *str;
str = malloc(BUFSIZ);
if(str == NULL) return NULL; // エラー

...

return str;
}
この場合は、呼び...続きを読む

Qchar*を初期化したいのですが

Cの標準関数だけで
char*を初期化したいのですが
どの様にすればいいのでしょうか?

char* a = "aaaa";
char* b = "bbbb";
strcat( a, b );//"aaaabbbb"?
とし使いまた後で
aにまた値を入れ直したいので
初期化して再利用したいのですが

どのようにすればいいのでしょうか?

ポインタとかもうっすら(ほとんどわかりません)
よろしくお願いいたします

Aベストアンサー

> char* a = "aaaa";
> char* b = "bbbb";
> strcat( a, b );//"aaaabbbb"?
この上のコードは間違っていますよ。
変数a、bに入っているのはあくまでも文字列の"ポインタ"です。
従いまして、strcat( a, b );とすると、aがさしているメモリは5バイトしかないのでメモリを破壊してしまいます。
static char sza[] = "aaaa";
static char szb[] = "bbbb";
char szBuffer[256];
char* a = szBuffer;
strcpy (a, sza);
strcat (a, szb);
としないとだめです。

またポインタ変数はNULLで初期化可能です。

Qファイル出力で改行を入れたい!

data.txtにファイル出力を行うのですが、gets(c)で入力した一語一語に改行を入れてdata.txtに出力したいのですがどうすればよいでしょうか。
返答のほどよろしくお願いいたします。
include<stdio.h>
#define SIZE 20
void main(void)
{
char c[SIZE], *p;
FILE *fp;

fp = fopen("data.txt","w+");
p = c;
while(gets(c) != NULL){
fputs(p,fp);
}

fclose(fp);
printf("data.txtへ出力しました\n");

}

Aベストアンサー

一語一語ってのは、1回の入力毎って事でしょうか?
とするならば、これでどうでしょうか?

#include <stdio.h>
#define SIZE 20
void main(void)
{
  char c[SIZE], *p;
  FILE *fp;
  
  fp = fopen("data.txt","w+");
  p = c;
  while(gets(c) != NULL){
    fputs(p,fp);
    fputc('\n', fp);
  }
  
  fclose(fp);
  printf("data.txtへ出力しました\n");
  
}

Q複数桁10進数の*桁目だけを抽出したい

タイトルがすべてと言えてしまうのですが、
例えば、int宣言された"4287"(この値は変動します)という数値があったとして、1桁目の"7"だけを別の変数へ引き抜きたいのですが、その場合にはANDによるマスク処理による演算で処理可能なのでしょうか?
また、他に良い方法などありましたら教えていただけますでしょうか?

Aベストアンサー

★10進数ですので AND は使えませんね。
・簡単なサンプルを載せますので読み取って下さい。

サンプル1:
int value = 4287;
int a[ 4 ];

a[0] = (value % 10); value /= 10; // 1桁目を取り出す
a[1] = (value % 10); value /= 10; // 2桁目を取り出す
a[2] = (value % 10); value /= 10; // 3桁目を取り出す
a[3] = (value % 10); value /= 10; // 4桁目を取り出す

サンプル2:
int value = 4287;
int a;

a = (value % 10);
value -= a;

value → 4280
a → 7
になります。


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

人気Q&Aランキング