C言語標準入力でquitを入力で終わるプログラムを作っているのですが
うまくいきません
#include <stdio.h>
int main(void) {
int i, n;
double data[100];
printf("数字を入力してください。\n");
printf("入力を終えるときにはCtrl-dを押してください。\n");
n = 0;
while (scanf("%lf", &data[n]) != EOF) {
n++;
}
for (i=0; i<n; i++) {
printf("data[%d] = %f\n", i, data[i]);
}
return (0);
}
と今はとりあえづ作ってみたのですが
今のままではCtrl-dでループから抜ける形になっています
strcmp関数を使うとは思うのですが
strcmp関数はchar型なのでエラーが出てしまいます;
このやり方じゃないchar型にしてやり直さないといけないでしょうか;
Linux CentOS gcc
でやっています
標準入力で数字を入力しそれを格納
quitを入力するまで繰り返す
quitを入力で終了、これまで格納していた文字列の表示
簡単なプログラムの流れとしては上記の感じです
よろしくお願いします。
A 回答 (13件中1~10件)
- 最新から表示
- 回答順に表示
No.13
- 回答日時:
終了しますね。
>#12hogehog12345670000004quit
とか入力すると妙な挙動に見えるかも知れませんね。
標準入力に残る関係上しょうもないですかね。
まぁ、エラーケース考えるのは質問者さんに任せるとします。
# 勉強用だとエラー処理とか入っていなかったりとか多いですし。
# fgets()の戻り値もチェックしていなかったなぁ、そういえば…。
No.11
- 回答日時:
こんな感じですかねぇ……
インデントを全角空白でやっているのでコピペする場合はご注意を。
一応、CentOS6.5で動作確認はしましけど。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MCH 8
#define N 20
int main()
{
int data[N];
int nc = 0, i, flag;
char bff[MCH];
do
{
/* 入力 */
printf("data%d?:", (nc + 1));
fgets(bff,MCH,stdin);
/* "quit"だったら抜け */
if(strcmp(bff,"quit\n") == 0)
{
break;
}
/* 数字以外があるか確認 */
for(i = 0,flag = 1;bff[i] != '\n' && bff[i] != '\0';i++)
{
if(!isdigit(bff[i]))
{
flag = 0;
}
}
if(flag != 1)
{
printf("error:数字のみでお願いします。\n");
continue;
}
/* 5桁以上ならエラー(先のforループの結果、iは入力した文字数になっている) */
if(i > 5)
{
printf("error:5桁以内でお願いします。\n");
continue;
}
/* データ格納 */
if(i != 0)
{
data[nc++] = atoi(bff);
}
}while(nc < N);
/* 結果表示 */
printf("データ:\n");
for(i = 0;i < nc;i++)
{
printf("data[%d]=%d\n", i, data[i]);
}
return 0;
}
No.10
- 回答日時:
先は長そうですねぇ……
>:27: error: ‘else’ without a previous ‘if’
>else if(!isdigit(bff))
のelseに流れる為のif文はどれでしょう?
>:33: 警告: passing argument 1 of ‘strcpy’ makes pointer from integer without a cast …
>strcpy(a,bff);
char型に「文字列」は入れられません。
というか、この場合変数aに入っている謎の値がアドレスとして処理されます。(型が違うので怒られてますが)
>:35: 警告: passing argument 1 of ‘atoi’ makes pointer from integer without a cast …
>i=atoi(nc);
atoi()の引数はchar *かと。ncでは…アドレス0~10に数字が入っていることになります。
# 型がおかしいからやっぱり怒られる。
>:48: error: expected ‘while’ at end of input
久しぶりに「{」と「}」の対応が取れていません。
do {に対応する}は一番最後のものです。
よって、main()が閉じていませんので…
>:48: error: expected declaration or statement at end of input
こう言われます。
さて、他のツッコミ満載を消化しましょうかね。
>if(!(strcmp(bff,"quit\n")==0||nc==N))
ncがNだった時に…
>ch[nc++] = bff[0];
バッファオーバーフロー達成です。
ch[20]は安全に使える領域でしたか?
>char ch[N],a;
char型では値が入らない…と指摘済みですよね?
>scanf("%5d",bff);
%dで指定する場合は、結果を格納するアドレスを渡す必要があります。
bffはアドレスなのでまぁ、OKでしょう。
想定する動作はしませんが。
# bffからの連続する4バイトに「数値」が入ります。「数字」ではありませんのでご注意を。
# どう格納されるかは…エンディアン次第ですかね。(4バイトである保証もありませんが…まぁ、この場合どうでもいい話)
>else if(!isdigit(bff))
「isdigit()で1文字ずつ」と書いたかと思われますが……
何より引数の型が違うかと。(char *がintになったんですかねぇ…)
>printf("@ bff=%s",bff);
>printf("@ atoi(bff)=%d\n",atoi(bff));
入力のループの外にありますよ?
それで正しいのですか??
>fget(bff,MCH,stdin);
で数字を入力した場合は、まるっと捨てます。
# 後でscanf()しているから。
というかfgets()…ですよね??
なんというか、そろそろ回答例なコードでも乗せて強制終了した方がいいんじゃないか?
とか思い始めてきた……。
勉強にはたぶんならないけど。
すいません
長々付き合ってもらってしまって…
申し訳な過ぎるので
もお解答例を頂いて自分で勉強しようかと思ったのですが…
ご迷惑じゃなければ解答例を頂けないでしょうか
本当に長々付き合わせてすいませんでした
No.9
- 回答日時:
>→数値=コンピュータで計算できる数字
>数字=人間語でコンピュータで計算できない
>って言う認識なんですが…;
おおむね合っている…かなぁ。
念のため、「数値 数字」などでWeb検索してください。
>→条件:数字以外入力時はエラー表示し、再入力・全角数字の場合入力時はエラー表示し、再入力
>というのもあるので
エラー判定の追加があるようなので…
イメージとして掲示した中の
入力内容をコピー(ch[nc]=入力内容(数値で保持なら数字=>数値変換))
の前で、入力した文字列が数字のみかどうかの判定処理を追加してください。
http://linux.die.net/man/3/isdigit
のisdigit()で「1文字ずつ」判定していけばよいでしょう。
# 数字=>数値変換でエラーになったら…とかいう手もありますけどね。
# ただしatof()は使えないですが。sscanf()でもダメ…かなぁ…(先頭が数字だと…ね)
とりあえず
大まかな流れとしてはこんな感じですかね?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MCH 8
#define N 20
int main(){
char ch[N],a;
int nc,quit,ic,b;
char bff[MCH];
printf("入力(quit by quit):\n");
nc=0;
do{
fget(bff,MCH,stdin);
if(!(strcmp(bff,"quit\n")==0||nc==N))
{
ch[nc++] = bff[0];
break;
}
else
{
scanf("%5d",bff);
printf("error:5桁以内でお願いします。\n");
}
else if(!isdigit(bff))
{
puts("error");
}
else
{
strcpy(a,bff);
ch[nc]=a;
i=atoi(nc);
}
while(!quit);
printf("@ bff=%s",bff);
printf("@ atoi(bff)=%d\n",atoi(bff));
printf("データ:\n");
for(ic=0;ic<nc;ic++)
{
b = ch[ic];
printf("ch[%d]=%d\n",ic,b);
/*printf("ch[%d] = %f\n",ic,ch[ic]);*/
}
return 0;
}
: In function ‘main’:
:27: error: ‘else’ without a previous ‘if’
:33: 警告: passing argument 1 of ‘strcpy’ makes pointer from integer without a cast
/usr/include/string.h:128: note: expected ‘char * __restrict__’ but argument is of type ‘char’
:35: 警告: passing argument 1 of ‘atoi’ makes pointer from integer without a cast
/usr/include/stdlib.h:148: note: expected ‘const char *’ but argument is of type ‘int’
:48: error: expected ‘while’ at end of input
:48: error: expected declaration or statement at end of input
めっちゃエラー出てしまったんですけどね…
これでも半分まで減らしましたが今出てるエラーは意味がわからなくて…
No.8
- 回答日時:
>ch[]の値はどこでどんな感じで入れたら良いですか?;
数値で入れたいのか、文字で入れたいのか…どちらです?
# とりあえず、「数値」と「数字」の区別はつきますか?
>charじゃないほうが良いということはdoubleとかにしないとってことですかね…?
数値…であれば、int型の配列でいいんじゃないですかね?
文字として…ということならばchar型の二次元配列なりになると思いますが。
>あと条件で
>5文字以上の場合入力時はエラー表示し、再入力
>というのがありまして
nc=0;
do{
fgets(bff,MCH,stdin);
bffがquitじゃないか判定。
=>quitだったらループ脱出フラグ設定
else
bffが5文字(5桁?)以内か判定
=>5文字以上ならエラーメッセージ表示
else
入力内容をコピー(ch[nc]=入力内容(数値で保持なら数字=>数値変換))
nc加算
ncが10か?
=>10だったらループ脱出フラグ設定
}while(!quit);
って感じですかね。
数字=>数値変換でエラーになる可能性もありますけど。
「"wktk"を数値にせよ。」とか言われても困るでしょう?
# とりあえず、「数値」と「数字」の区別はつきますか?
→数値=コンピュータで計算できる数字
数字=人間語でコンピュータで計算できない
って言う認識なんですが…;
数値…であれば、int型の配列でいいんじゃないですかね?
文字として…ということならばchar型の二次元配列なりになると思いますが。
→条件:数字以外入力時はエラー表示し、再入力・全角数字の場合入力時はエラー表示し、再入力
というのもあるので
intですかね;
nc=0;
do{
fgets(bff,MCH,stdin);
bffがquitじゃないか判定。
=>quitだったらループ脱出フラグ設定
else
bffが5文字(5桁?)以内か判定
=>5文字以上ならエラーメッセージ表示
else
入力内容をコピー(ch[nc]=入力内容(数値で保持なら数字=>数値変換))
nc加算
ncが10か?
=>10だったらループ脱出フラグ設定
}while(!quit);
って感じですかね。
→ありがとうございます。ちょっとそのやり方でやってみますね;
No.7
- 回答日時:
>データ:
>ch[0] = ?
>ch[1] = A
>となって値が出てこなかったです;
出てきたら恐怖です。
>do{
>fgets(bff,MCH,stdin);
>if(!(quit=strcmp(bff,"quit\n")==0||nc==N)){
>nc++;
>}
>}
>while(!quit);
のどこで、ch[]に値を入れているのでしょうか?
あと…ch[]はchar型なので、入力した内容を数値として持つつもりなら
>234
>345
234はともかく345は入りません。(char型には255まで…でしょう。signed charだったら127)
さらに…
>printf("ch[%d] = %c\n",ic,ch[ic]);
%cで出力すると入力値によっては画面壊れたりしますよ。
# 表示できない文字コードだった…とか、コントロールコードだった…とか……。
ch[]の値はどこでどんな感じで入れたら良いですか?;
あと条件で
5文字以上の場合入力時はエラー表示し、再入力
というのがありまして…記載するのを忘れていましたが…
charじゃないほうが良いということはdoubleとかにしないとってことですかね…?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MCH 8
#define N 20
int main(){
char ch[N];
int nc,quit,ic,b;
char bff[MCH];
printf("入力(quit by quit):\n");
nc=0;
do{
fgets(bff,MCH,stdin);
if(!(quit=strcmp(bff,"quit\n")==0||nc==N)){
ch[nc++] = bff[0];
}
}while(!quit);
printf("@ bff=%s",bff);
printf("@ atoi(bff)=%d\n",atoi(bff));
printf("データ:\n");
for(ic=0;ic<nc;ic++)
{
b = ch[ic];
printf("ch[%d]=%d\n",ic,b);
/*printf("ch[%d] = %f\n",ic,ch[ic]);*/
}
return 0;
}
No.6
- 回答日時:
指摘漏れ。
>printf("str[%s] = %s\n",i,str[i]);
最初の%sで、アドレス0からの文字列を表示。
gccってことだからたぶん"(null)"で済むでしょう。
が、その次の%sで…str[0]の値がアドレスとして使用されて…ここでもセグメンテーションフォルト発動…でしょうね。
>char str[10];
では、入力された情報を保持し続けるには足りません。
>while(scanf("%s",str[n])){
>if(!(quit=strcmp(str,"quit\n") == 0 || n == 10))
でnが10になっていた時には手遅れです。
配列の添え字の範囲について再度勉強し直してください。
# char str[10];
# で確保された配列は…
# str[0]~str[10]まで使えますか?
# str[1]~str[10]でしったけ?
指摘と自分なりに考えて下記のようにしてみました。
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MCH 8
#define N 20
int main(){
char ch[N];
int nc,quit,ic;
char bff[MCH];
printf("入力(quit by quit):\n");
nc=0;
do{
fgets(bff,MCH,stdin);
if(!(quit=strcmp(bff,"quit\n")==0||nc==N)){
nc++;
}
}
while(!quit);
printf("データ:\n");
for(ic=0;ic<nc;ic++)
{
printf("ch[%d] = %c\n",ic,ch[ic]);
}
return 0;
}
gccでコンパイラ時のエラーはありませんでした
実行
入力(quit by quit):
234
345
quit
データ:
ch[0] = ?
ch[1] = A
となって値が出てこなかったです;
No.5
- 回答日時:
>error: expected declaration or statement at end of input
14行目と16行目が対。(問題なし)
18行目と22行目が対。(だけど途中のreturnで終了)
5行目のmain()開始の「{」と、12行目のwhile()ループ開始の「{」が片思い中です。
あと……
>char str[10];
>scanf("%s",str[n])
入力された文字列を、どっか判らないアドレス(str[]は未初期化の変数なので入っている値は不定)に入れてね♪
ということで、コンパイルエラーを修正しても実行して入力した段階でセグメンテーションフォルトの魔法が発動でプロセス殺人事件が発生します。
犯人は……OSだっ!!
# 真犯人は仕組んだプログラマーだ。
No.4
- 回答日時:
>passing argument 1 of 'strcmp' from incompatible pointer type
strとした時とstr[n]とした時で型が異なりますが、その辺りは理解してます?
>while(scanf("%s",str[n]));
>if(!(quit=strcmp(str,"quit\n") == 0 || n == 10))
scanf()で入力を受け取ったのはstr[n][0]からstr[n][9]の範囲。
strcmp()で比較したいのはどこですか?
# あと、scanf()で受け取った時に改行文字入っていますか??
>error: expected 'while' at end of input
while()の後にセミコロンありますが、正しいですか?
というか、12行目にあるdoに対応するwhile()ってどれです?
>error: expected declaration or statement at end of input
「{」と「}」の対応が取れていません。
main()の「{」(5行目)に対応する「}」がありません。
vimでも対応する括弧は色を変えて表示してくれるオプションがあったと思いますのでその辺り確認しましょう。
ちなみに、16行目と18行目が対、
20行目と22行目が対、
13行目と24行目が対になっています。
# 24行目の対がmain()の開始…なのでしょうから、13行目の対が無い(というかdoに対応するwhile()が不明)というのが問題なのでしょう。
すいません;
少し直してみました;;;
#include <stdio.h>
#include <string.h>
int main(void)
{
int i,n,quit;
char str[10];
printf("プログラムを終了するにはquitを入力してください\n");
n = 0;
while(scanf("%s",str[n])){
if(!(quit=strcmp(str,"quit\n") == 0 || n == 10))
{
n++;
}
for(i=0;i<n;i++)
{
printf("str[%s] = %s\n",i,str[i]);
return 0;
}
gcc後のエラー↓
#ファイル名: In function 'main'*
#ファイル名#:22: error: expected declaration or statement at end of input
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
高校生はアルバイトするべきだろうか?賛成だったら「賛」、否定だったら「否」を文頭においてあなたの意見を教えてください。
-
フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
あなたが普段思っている「これまだ誰も言ってなかったけど共感されるだろうな」というあるあるを教えてください
-
映画のエンドロール観る派?観ない派?
映画が終わった後、すぐに席を立って帰る方もちらほら見かけます。皆さんはエンドロールの最後まで観ていきますか?
-
海外旅行から帰ってきたら、まず何を食べる?
帰国して1番食べたくなるもの、食べたくなるだろうなと思うもの、皆さんはありますか?
-
天使と悪魔選手権
悪魔がこんなささやきをしていたら、天使のあなたはなんと言って止めますか?
-
C言語のポインターに関する警告
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・歩いた自慢大会
- ・許せない心理テスト
- ・字面がカッコいい英単語
- ・これ何て呼びますか Part2
- ・人生で一番思い出に残ってる靴
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・初めて自分の家と他人の家が違う、と意識した時
- ・単二電池
- ・チョコミントアイス
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
数字以外が入力されたらエラー...
-
java初心者です。入力されたの...
-
"gets"は危険なのでしょうか?
-
enterでループ終了
-
プログラミング初心者です。 Py...
-
VB.NETで16進数+16進数や16進...
-
Eclipseコンソール表示を、リセ...
-
C-Builderで数値(数字)以外を入...
-
Linuxで入力待ちなしkeyread関...
-
C++:cinが上手く使えない
-
文字のリアルタイム検索がした...
-
キーボード入力によるループの終了
-
MinGWのC言語でCTRL+Zで処理が...
-
フローチャートについて
-
*をユーザーが入力した数字の数...
-
ワードで文字を入力する時の変...
-
正負を反転させて出力するプロ...
-
EDITコントロールで入力できる...
-
java プログラム 繰り返しにつ...
-
Spreadのコンボボックス
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
正負を反転させて出力するプロ...
-
プログラミング初心者です。 Py...
-
数字以外が入力されたらエラー...
-
Eclipseコンソール表示を、リセ...
-
Excel VBAで、Application.Inpu...
-
*をユーザーが入力した数字の数...
-
java初心者です。入力されたの...
-
Linuxで入力待ちなしkeyread関...
-
batプログラム上で文字列を入力...
-
WindowsでEOF
-
Userformの入力順序をタブオー...
-
コマンドプロンプトからのEOFの...
-
EDITコントロールで入力できる...
-
VisualStudio2019のコードアナ...
-
電卓の小数点
-
Eclipseでコマンドラインを入力...
-
小数か整数かを判定する方法
-
cout関数を使っているのですが...
-
UWSCで変数をキー入力
-
ワードで文字を入力する時の変...
おすすめ情報