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

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

よろしくお願いします。

A 回答 (4件)

あ,テキスト入力だからこんな大掛かりなことしなくてもいいんだ.


末尾に'\n'が出るまで掃出せばいいんですよね.

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

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

この回答への補足

ありがとうございます。かなりのヒントになりました。
お礼のついでに完成したのを載せておきます。
#include <stdio.h>
#include <string.h>

int main()
{
char str[20];
intchk_digit;

while(1)
{
chk_digit=0;
puts("入力");
fgets(str, sizeof(str), stdin);if ( str[strlen(str)-1] != '\n' )
{
while( getchar() != '\n' );
chk_digit=1;
}
if (chk_digit == 1 || str[0] == '\n' )
{
break;
}
}
printf("出力:%s\n",str);
return 0;
}

補足日時:2003/05/16 15:01
    • good
    • 4

システムは何ですか?fseek(stdin, 0, SEEK_END, 0)はLinuxでは効かないという話を読んだことがあります.SEEK_ENDをEOFと考えれば当然ですが.fseekでいけるシステムではSEEK_ENDを現状でのバッファエンドと捉えているんでしょうか.



で,おおがかりになってきますが,pollまたはselectを使って全部掃出すのはどうでしょう?

#include <stdio.h>
#include <sys/poll.h>

int
main(int argc, char **argv)
{
char s[11], ss[11];
struct pollfd fdlst = {0, POLLIN, 0};
int l;
l = read(0, s, 10); /* sに文字列読込み*/
s[l] = 0;
/* 掃出し */
do {
fdlst.revents = 0;
poll( &fdlst, 1, 1 );
} while ( (fdlst.revents&POLLIN) != 0 && read(0,s,10) > 0 );
/* ssに文字列読込み*/
l = read(0, ss, 10);
ss[l] = 0;
printf("%s", ss);
}

こうするとうちでは,sに何文字打とうと,それ以降に打った文字がssに入りました.ただし,pollはファイルポインタ(stdin)ではなくファイルディスクリプタ(0 = stdin)を使うので,読込みもそれに合わせてreadなどのシステムコールでやる必要があるようです.

#しかし私はfflush(stdin)に驚きでした.それでいけるシステムもあるんですね.

参考URL:http://www.linux.or.jp/JM/html/LDP_man-pages/man …
    • good
    • 0
この回答へのお礼

早速のお答えありがとうございます。
ただ,これを私のPCでコンパイルしようとすると,
(#include <unistd.h>を加えて・・)

[XXXXXXXX]$ gcc -g -Wall -o test test.c
[XXXXXXXX]$ ./test
abcdefghijk      (←1回目に打った内容)
abcdefghijk      (←2回目に打った内容)
abcdefghij[XXXXXXXXX]$ k
-bash: k: command not found
[XXXXXXXX]$

となり,1回目の入力は11文字以上がうけつけなく,サイドの入力の際は10文字だけが出力され後の一文字(k)がこのプログラムが終了したシステムのコマンドとして認識されるようになりました。
どうしたらいいでしょうか。

お礼日時:2003/05/16 13:57

fseek(stdin, 0, SEEK_END);


試してませんが。
他には、バッファが空になるまで読み捨てるとか。
    • good
    • 0
この回答へのお礼

こんにちわ,
それも,fssekも無理だったんですよ。

char str[20];
fseek(stdin, 0, SEEK_END);
if ((*fgets(sk,sizeof(sk),stdin) < 0x21) || strlen(sk) >= 21 )
{
puts("error");
goto start1;
}
のようにしたんですけど,むりでした。

お礼日時:2003/05/16 13:05

fflushはCの標準関数のはずです。


上手く行かないのには別の原因があるのではないでしょうか?
    • good
    • 0
この回答へのお礼

いや,ANSI C規格では、

「fflush関数は出力ストリーム(stdoutとかstderr)にしか使えないように定義されている」
参照:http://www.peke.jp/archive/fmc/article/dev/dev00 …

らしいんですよ。ですから,
fflush(stdout)
はできても,
fflush(stdin)
はできないみたいなんです。

お礼日時:2003/05/16 11:47

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

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

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

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

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 *だと思ってくれ」と書く必要が...続きを読む

QC,C++,C++/CLIの構造体とクラス

C++の構造体・クラスって、メンバのアクセス指定子のデフォルトが
privateかpublicかという違い「だけ」しか全くないのでしょうか?

クラスにおける
value class / ref class
という分類はC++/CLIのもので
これについては
value class の方は C言語の構造体に近いという事でいいでしょうか?

ref classの方は
ネイティブのC++のクラスを
マネージ用にしたようなもので

C++/CLIの構造体は
C++のそれと同じで
OKですか?

そしてそれらの構造体には、値型・参照型といった分類はないのでしょうか?

Aベストアンサー

> ということは、structも継承可、という事でしょうか?

structでも継承可能です。

> 継承のアクセス指定の方は
> クラスと構造体ではどうなるのでしょうか?

class A : Base {};



class A : private Base {};

と等価です。
一方、

struct A : Base {};



struct A : public Base {};

と等価です。

> そして「集成体」というのが初めて知ったのですが
> これはいわゆる、配列や・・・ある条件下でのクラス・・?
> なのでしょうか?

配列と以下の条件をすべて満たすクラスのことです。
・ユーザー定義のコンストラクタを持たない
・非公開または限定公開のメンバを持たない
・基底クラスを持たない
・仮想関数を持たない

ちなみにC言語の集成体は、配列と構造体の総称です(共用体は集成体ではありません)。

Q3週間でC,C++,VC++の勉強を済ませるのですが・・・

こんにちは。
私は、未経験でプログラマの職に就いた者です。
会社より、まずは勉強をしてほしいとのことで、

第1週 : 独習C(第3版 翔泳社)で、C言語の勉強
第2週 : 独習C++(第3版 翔泳社)で、C++の勉強
第3週 : MSDNライブラリのVisualC++チュートリアルで、VC++の勉強

というスケジュールで、勉強しています。
今は第3週の2日目ですが、なかなかはかどりません。

上司は、「これから先に実践で必要なことを覚えてもらうけれど、その基本を身に着けてもらいたい」と言っていましたし、
時間の関係もあるので、それぞれの項目の内容をほぼ理解できるまで読み、
例題などは極力とばして進めてきました。
そして今週VC++の勉強に入ったのですが、MFCなど新たなものが沢山でてくるし、
今までの本と違いMSDNライブラリは初心者の私にはあまり親切ではなく、プログラムの全体を把握することができずに頭がこんがらがってきています。

上司は別の場所で働いているのでなかなか意思の疎通がとれず、
勉強の指針など話す機会に恵まていない状況です。

そこで経験者の方に質問なのですが、
MSDNライブラリ以外に副読本として役に立つ本や役立つサイトなどオススメはありませんでしょうか?
また、この3週間のスケジュールで求められていることは、おおまかな全体の把握以外に、具体的にどのようなことと思われるでしょうか。
(例えば、このスケジュールで勉強するならVC++の~の事は重点的に覚えておいてほしい、など)

曖昧な質問で申し訳ありません。
この質問内容では不十分であれば指摘していただければ補足しますので、
どうぞよろしくお願いします。

こんにちは。
私は、未経験でプログラマの職に就いた者です。
会社より、まずは勉強をしてほしいとのことで、

第1週 : 独習C(第3版 翔泳社)で、C言語の勉強
第2週 : 独習C++(第3版 翔泳社)で、C++の勉強
第3週 : MSDNライブラリのVisualC++チュートリアルで、VC++の勉強

というスケジュールで、勉強しています。
今は第3週の2日目ですが、なかなかはかどりません。

上司は、「これから先に実践で必要なことを覚えてもらうけれど、その基本を身に着けてもらいたい」と言っていました...続きを読む

Aベストアンサー

ゼロから学ぶVisual C++
http://www.amazon.co.jp/exec/obidos/ASIN/4822216934/250-7140492-7151432
Visual C++〈3〉はじめてのMFCプログラミング
http://www.amazon.co.jp/exec/obidos/ASIN/4881358235/250-7140492-7151432

とりあえず初心者向けMFC本を2冊。
後、最終的にはWin32 APIというものに対する知識も必要なので、
Win32API完璧マスター
http://www.amazon.co.jp/exec/obidos/ASIN/4789836908/ref=pd_sim_dp_5/250-7140492-7151432
も挙げておこう。

むしろMSDNのチュートリアルを後回しにして良いと思う。あれは、ある程度わかるようになってからでしょ。

> この3週間のスケジュールで求められていることは、
> おおまかな全体の把握以外に、具体的にどのようなことと思われるでしょうか。
 さて・・・・君の会社が何を作っているのか知らないので一概には言えないのだが、やはりアプリの作り方、だな。何を置いても一通り作れるようになってからだ。ただ、その前に人のソースを読めるようになっておく方が上達が早いかも知れない。
 ところで今思ったんやけど、君の会社はMFCで作っているのかな?
> 第3週 : MSDNライブラリのVisualC++チュートリアルで、VC++の勉強
とあるが、もしこれで君の会社がWin32APIだけで作りよるとしたら、MFCの知識はかえって邪魔かも知れない。

 私はC言語(とWindowsでのC)を本当にマスターしたと言えるまで、2年かかった。NECのN88BASICという言語の経験が1年あった上での話だ。んな急に全部作れるようになれとは決して言わないはず。
 書けるよりは、まず人のプログラムを読めるようになると良いだろう。

ゼロから学ぶVisual C++
http://www.amazon.co.jp/exec/obidos/ASIN/4822216934/250-7140492-7151432
Visual C++〈3〉はじめてのMFCプログラミング
http://www.amazon.co.jp/exec/obidos/ASIN/4881358235/250-7140492-7151432

とりあえず初心者向けMFC本を2冊。
後、最終的にはWin32 APIというものに対する知識も必要なので、
Win32API完璧マスター
http://www.amazon.co.jp/exec/obidos/ASIN/4789836908/ref=pd_sim_dp_5/250-7140492-7151432
も挙げておこう。

むしろMSDNのチュートリアルを後回し...続きを読む

Qfgets, sscanf, バッファ、ストリーム について

ファイルからデータを入力するのに、fscanf の代わりに fgets と sscanf を用いようと考えています。
そこで、sscanf に与えるバッファ文字列を、ファイルストリームのように扱う方法は無いものでしょうか。
例えば以下のデータファイルに対して、以下のプログラムをうまく動作させるには、どのようにすればよいでしょうか。
どうぞ、よろしくお願いします。

(データファイル test.dat)
n_data 4
1 3 8 4

(プログラム)
#include <stdio.h>

main()
{
int i, n_data, *data;
char buf[100];
FILE *fp;

fp = fopen ( "test.dat", "r" );

fgets(buf, 100, fp);
sscanf( buf, "n_data %d\n", &n_data );
data = (int *)malloc( n_data * sizeof(int) );

for( i=0; i<n_data; i++ ){
fgets(buf, 100, fp);
sscanf( buf, "%d", &(data[i]) );
}
sscanf( buf, "\n" );
close( fp );

printf( "n_data %d\n", n_data );
for( i=0; i<n_data; i++ )
printf( " %d", data[i] );
printf( "\n" );
}

ちなみに、2行の fgets(buf, 100, fp); をコメントアウトして、
"sscanf( buf," を "fscanf( fp," に変更するとうまく動作します。

ファイルからデータを入力するのに、fscanf の代わりに fgets と sscanf を用いようと考えています。
そこで、sscanf に与えるバッファ文字列を、ファイルストリームのように扱う方法は無いものでしょうか。
例えば以下のデータファイルに対して、以下のプログラムをうまく動作させるには、どのようにすればよいでしょうか。
どうぞ、よろしくお願いします。

(データファイル test.dat)
n_data 4
1 3 8 4

(プログラム)
#include <stdio.h>

main()
{
int i, n_data, *data;
char buf[100];
...続きを読む

Aベストアンサー

アプローチの仕方は色々あるだろうけど、1つの方法
----------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(){
int i, n_data, *data;
char buf[100], *p;
FILE *fp;

fp = fopen ( "test.dat", "r" );

fgets(buf, 100, fp);
sscanf( buf, "n_data %d\n", &n_data );
data = (int *)malloc( n_data * sizeof(int) );

fgets(buf, 100, fp);
p=strtok(buf, " \t\n");
for( i=0; i<n_data; i++ ){
sscanf( p, "%d", &(data[i]) );
p=strtok(NULL, " \t\n");
}
fclose( fp );

printf( "n_data %d\n", n_data );
for( i=0; i<n_data; i++ )
printf( " %d", data[i] );
printf( "\n" );


return 0;
}

アプローチの仕方は色々あるだろうけど、1つの方法
----------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(){
int i, n_data, *data;
char buf[100], *p;
FILE *fp;

fp = fopen ( "test.dat", "r" );

fgets(buf, 100, fp);
sscanf( buf, "n_data %d\n", &n_data );
data = (int *)malloc( n_data * sizeof(int) );

fgets(buf, 100, fp);
p=strtok(buf...続きを読む

QC,C++,C#には共通点があるのでしょうか?

Cという言語に+や#が付いているだけ、と考えるとC言語がベースで、それに何か変更を加えてC++やC#に派生した、と思っているのですが、実際なにかつながりはあるのでしょうか?

C++を始める前にCをマスターしてから、というアドバイスをよく見かけますが、それもCがベースだからということなのでしょうか?

Aベストアンサー

この手の話では以下の読み物がオススメです
http://www.mwsoft.jp/column/program_top10.html


私の理解では、

C:
機械語を高級にしたもの

C++:
Cに、言語仕様的にオブジェクト指向を拡張したもの
Objective-C:
Cに、マクロ的にオブジェクト指向を追加したもの

Java:
C++の構文を下敷きに、JVM という仮想環境向けに簡単にしたもの
C#:
Javaの構文を下敷きに、.NET という仮想環境向けに複雑にしたもの


CとC++は関連があるので、難解なC++/ObjCを覚える最初の段階としてのCは、良い考えだと思います。
C/C++とJava/C#は無関係なので、Cを覚えても無駄でしょう。


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

人気Q&Aランキング

おすすめ情報