- ベストアンサー
fgetsを用いたループ処理後の入力について
Oh-Orangeの回答
★フィルタ・コマンドですか。 ・標準入力(stdin)でキーボードからの入力では必ず『改行』を含むように 注意するしかないような気がします。 ・過去に MS-DOS 用のフィルタコマンドをよく作成しましたが fgets で 『改行』コードが最終行に追加されない場合を入力の終わりと判定する スマートな方法はないです。低水準の関数を使って直接読み取るように すれば可能ですが移植性も考え高水準の関数を使うべきです。 元々低水準関数は処理系が高水準を実現するために用意されているだけで プログラマに利用するようには考えられていません。 ・私の対策方法 最終行に改行コードがなくて『^Z』+『Enter』を押すとまだ入力待ちに なるのためもう一度『^Z』+『Enter』を押して終わりと判定させるように 入力側(人間)が気をつけるようにしています。 ※ほかにもっと良い方法があれば私も乗り換えたいです。 ・OS(Windowsなど)限定で利用するならAPI関数を直接呼び出して fgets と ほぼ同じ処理をする関数を自作すれば要求通りの動作が可能です。 あまりお勧めではありませんが方法としてはあります。 また conio.h の kbhit()、getch()関数を使って fgets 同等の関数を 作り出す方法もあります。こちらも処理系や OS によって conio.h が 用意されていない場合もありますので注意すべきです。 ・さて、どうしますか?
関連するQ&A
- C言語におけるfgetsを用いたループ処理について
C言語において、文章を読み込むためにfgetsを用いて下記のプログラムを書いたのですが、*において入力を受け付けなくなります。 これを解消する方法はないでしょうか? ちなみにコンパイラはBBC、開発環境はVistaです。 なお、簡略のため#include,main等は省略しています。 //以下プログラム #define SIZE 16384 char moji[SIZE] = {""}; char buf[SIZE]; //EOF(^Z)になるまで、文字列を受け取る while(fgets(buf, sizeof(buf), stdin) != NULL){ if(sizeof(moji) < strlen(moji) + strlen(buf)) break; strcat(moji, buf); }; getchar(); //* //プログラムここまで
- 締切済み
- C・C++・C#
- fgetsとsscanf
C言語の勉強をしております。 初歩的な質問なのかもしれないですが、 char buf[80]; char data[32]; fgets(buf,sizeof(buf),stdin); sscanf(data, "%s", buf); と、 fgets(data, sizeof(buf), stdin); は何が違うのでしょう? 他の質問内容やネットで探してみたんですが、基本的には組み合わせて使用されているみたいなんですが、必要性がわかりません・・・。 例えば、fgetsで構造体のメンバ(文字配列)へキーボードからデータを入力したい場合は、どちらで行うのが良いのでしょう? また、入力データが未入力かどうか判断させるには、 fgets(buf,sizeof(buf),stdin); if(buffer[0] == '\n'){ /* ループを抜ける */ break; } で良いですよね? ※関連している質問 http://oshiete1.goo.ne.jp/qa4438371.html あと、同じ処理内で、getsやscanfを混同して使用すると、どこかの入力時に改行がバッファに残ってしまい、入力処理が飛ばされてしまいますか? 以上、よろしくお願いいたします。
- ベストアンサー
- C・C++・C#
- fgets関数を使用したときの文字あふれについて
fgets関数を用いて文字列を入力し、その長さを測るプログラムを作っています。 #include <stdio.h> #include <string.h> #define MAX 256 int main ( int, char *[] ); int main ( argc, argv ) int argc; char *argv[]; { char buf[( MAX )]; while ( 1 ){ memset ( buf, 0, sizeof( buf )); fgets ( buf, MAX, stdin ); if( fgets == NULL ){ break; } printf("入力した文字列の長さは%dです\n" ,strlen( buf )); } return 0; } このプログラムでは、256までしか文字列の長さを測ることができません。 もしこのプログラムで256を超える文字列を入力してしまうと、文字のあふれが発生し、 「入力した文字列の長さは256です」 「入力した文字列の長さは(あふれた文字列の長さ)です」 とこのようになってしまいます。 このプログラムで256以上の文字を読み捨てて、 「入力した文字列の長さは(あふれた文字列の長さ)です」 を表示しないようにできるのでしょうか? また読み捨てた文字列の長さを知ることはできるのでしょうか? もしかしたらfgets関数を使用すると不可能なのではないか?と思っています。 分かる方が居ましたらどうか教えて下さい。 よろしくお願いします。
- 締切済み
- C・C++・C#
- fgetsでエラー
C言語を勉強しているものです。 fgetsやfscanfで第一引数にダブルポインタ変数を用いるとエラーが出ます。 なぜそうなるんでしょうか? ダブルポインタだと不可能なんでしょうか? char **moji; FILE *fp; moji = (char**)malloc(sizeof(char*) * 128 * 256); fp = fopen("test.txt","r+"); fgets(moji[0], 26, fp); //ここでエラー mojiを[0]で指定してあげてもエラーなんでしょうか? fgetsだけでなくfscanfでもそうです。 どうしてそうなんるんでしょう?
- ベストアンサー
- C・C++・C#
- fgetsで2行目から文字化け
fgetsでファイルを一行ずつ読み込みたいのですが、二行目以降が文字化けしてしまいます。 ******* ソース ******* #include <windows.h> #include <stdio.h> FILE *fp; if ((fp = fopen("textlist.txt", "r")) == NULL){ MessageBox(NULL, TEXT("ファイルを開けません"), NULL, NULL); exit (1); } while (1) { TCHAR buf[128] = {0}; if (fgets(buf, sizeof(buf), fp) == NULL) break; MessageBox(NULL,buf,NULL,NULL); } fclose(fp); ***** textlist.txt ***** あいうえお かきくけこ さしすせそ メッセージボックスの一回目は正しく"あいうえお"と表示されますが、二回目・三回目は文字化けしています。 最終的に一行ずつ分けて配列に入れたいので、fgetsで出来たらと思っています。 よろしくお願いします。
- ベストアンサー
- C・C++・C#
- C言語のファイル処理について
環境 OS:Windows VISTA Ultimate コンパイラ:Borland C++ Compiler 5.5 Cの基礎的な勉強をしています。2つほど質問があります。 1つ目は、ファイル処理の勉強としてプログラムを作っているのですがファイルが上手く開けません。プログラムとしてはファイルを開いて、ファイル内に記述されている数値を取り出し、計算を行う簡単なものを作っています。ソースは以下のものになります。 #define N 256 int file_read(char filename[] , int count[]) { int m; FILE *fp; fp=fopen(filename,"r"); if(fp==NULL) { /* オープン失敗 */ printf("Not Found File\n"); return -1; /* 戻り値-1 */ } while((m = fgetc(fp)) != EOF) { 読み取った数値配列に格納する処理 } fclose(fp); return 0; } int operation(int count[]) { 計算処理 return 0; } int main(void) { int *count[N]; char *filename[256]; memset(count, 0, sizeof(count)); /* 変数・配列初期化 */ printf("Please Input Filename:"); fgets(filename, sizeof(filename), stdin ); if(file_read(filename,count) != -1) operation(count); return 0; } バッファオーバーランの事を考え、fgetsによるキー入力にしたのですがファイルオープン失敗になってしまいます。fgetsのあと、変数filenameの中身を確認したところ、キー入力した文字はきちんと代入されていました。オープンするファイルはきちんとあるのですが・・。 fgetsをscanfに変えた場合は上手くいくので書式指定をしてscanfを使えばいいのでしょうが、なぜfgetsで上手くいかないでしょうか? 2つ目はgetchar()とfgets()に関してです。 while((c = getchar()) != EOF) { . .処理 . fgets(変数, sizeof(変数), stdin ); . .処理 . } とした場合、fgetsの処理が無視されてしまいます。 これはどういったことが原因なのでしょうか。 ご教授、お願いいたします。
- ベストアンサー
- C・C++・C#
- c言語のscanfとfgetsについて
2つの単語A, Bを入力して、AがBに含まれるか否かというプログラムで 以下のようなものを作成しました。 そこで質問なのですがscanf()をfgets()に変えるとうまく動作しません どこが間違ってますか? 変更したいfgets fgets(key, sizeof(key), stdin); fgets(word, sizeof(word), stdin); ------------------------------------------------- int main(void) { char key[101], word[101]; scanf("%s", key); scanf("%*c%s", word); if (strstr(word, key) != NULL) { printf("Find %s In %s\n", key, word); } else { printf("Not Find\n"); } return 0; }
- ベストアンサー
- C・C++・C#
- enterでループ終了
#include <stdio.h> int main(void) { char str[255]; int i, len; while (1){ printf("文字列を入力してください:"); if (fgets(str, sizeof(str), stdin) == NULL) { break; } len = strlen(str); if (len > 0 && str[len - 1] == '\n') str[len - 1] = '\0'; if (str[0] == '\0') break; enterで終了するプログラムの例ですが、 if (fgets(str, sizeof(str), stdin) == NULL) のNULLはどういった理由で必要ですか? また、 if (len > 0 && str[len - 1] == '\n') str[len - 1] = '\0'; を消して、 if (str[0] == '\0') break; を、if (str[0] == '\n') break; と書き換えれば、終了すのではないですか?不適な理由がありますか?
- ベストアンサー
- C・C++・C#
- ループのとめ方
入力した文字を小文字から大文字に 変えるプログラムで、コントロール+z で、ループを抜け出すようにしたい。 連続して2度コントロール+zを 押さないととまらないのですが、 どのようにすれば、1度コントロール+zを 押すだけで、終了できるのでしょうか? 何かアドバイスをお願いします。 ======================================== #include <stdio.h> #include <ctype.h> #include <string.h> int main(void) { char moji[50],check=0; int i,len; while(check !=EOF){ printf("Enter : "); check = scanf("%s",moji); len=strlen(moji); if(check!=EOF){ printf("Display : "); for(i=0;i<len;i++){ printf("%c",toupper(moji[i])); } } } return 0;
- ベストアンサー
- C・C++・C#
- C言語 strlen 再入力を促す
文字列の比較で、 文字列の長さが60以上の時、再入力を促します。 while文を使って書いてみたのですが、 文字列Bの入力の前に、もう一度意味もなく 「文字列Aを入力===>」が表示されたり。 文字列Aのほうが小さいのに「Aのほうが大きい」と 表示されるようになったり、変な感じです。 どなたかご指摘・ご指導のほどよろしくお願いします。 int main(void) { char moji1[100]; char moji2[100]; while(strlen(moji1)>60){ printf("文字列Aを入力===>"); scanf("%80s" ,moji1); } while(strlen(moji2)>60){ printf("文字列Bを入力===>"); scanf("%80s" ,moji2); } if(compare(moji1,moji2)>0){ printf("===AはBより大きい===\n"); } else if(compare(moji1, moji2)<0){ printf("===AはBより小さい===\n"); } else if(compare(moji1, moji2)==0){ printf("===AとBは等しい===\n"); } return 0; } int compare(char *x, char*y) { while(*x==*y && *x!=0){ x++; y++; } return (*x-*y); }
- ベストアンサー
- C・C++・C#
お礼
暫定的には、入力画面やreadmeなどで注意を喚起し、あとは使用者に任せるしかありません。 ファイル入力への対応へ踏み切れれば、標準入力による入力方法を止め、ファイル入力のみに絞ることでエラーの発生を回避する方法を取りたいと思います。 まだ先の話ではありますが、将来的にはWin32 APIへ移行したいと思っているので、それまでは使用者に不便を強いるしかないかと。 長々と、ありがとうございました。