• ベストアンサー

C言語 アロー演算子

このようなプログラムを作りたいのですが上手くいきません。 (入力と出力は必ずアロー演算子を使う。) <実行例> 番号を入力:1 名前を入力:taro 番号:1 名前:taro どなたかよろしくお願い致します #include <stdio.h> #include <string.h> typedef struct{ int no; char name[21]; }student; void in(student *std){ char namae[21]; int bango,i=0; scanf("%d", &bango); std->no = bango; while(1){ namae[i] = getchar(); if((i >= 20 ) || (namae[i] == '\n')) break; i++; } i++; namae[i] ='\0'; strcpy(std->name,namae); } void out(student *std){ printf("%d\n", std->no); printf("%s\n", std->name); } main(){ student person; in(&person); out(&person); return 0; }

noname#39315
noname#39315

質問者が選んだベストアンサー

  • ベストアンサー
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.2

★ほぼ出来ていますが…。 ・『in』関数の『while』の次にある『i++』は不要です。 ・『while』ブロックの中で『i++』を行っているため必要ありません。 ・場所分かりますか?→『in』関数の下から3行目の『i++』です。 ・また、『namae[i] = getchar();』の行は、『namae[i] = (char)getchar();』と  (char)キャストします。 ・『while(1){}』は『for(;;){}』とすると警告メッセージが出ません。 ・そして、一番重要なのが『scanf』関数の後(std->noの次など)に『fflush』の  関数で標準入力をフラッシュさせます。 ・こうしないとバッファに数字の『1』が溜まったままになってしまいます。 ●修正(in関数のみ→他はあっています) void in( student *std ) {  char namae[ 21 ];  int bango, i;    scanf( "%d", &bango );  std->no = bango;  fflush( stdin ); ←ここがポイント    for ( i = 0 ; ; i++ ){ ←この方が分かりやすいよ(初期化 ; 条件式 ; 増減式)   namae[ i ] = (char)getchar();      if( (i >= 20) || (namae[i] == '\n') ){    break;   }  }  ←ここにあった『i++』は不要です。  namae[ i ] ='\0';  strcpy( std->name, namae ); } 最後に: ・『for』文の2つ目の条件式を省略すると無限ループを構成します。 ・『while(1)』でもループできますが、警告メッセージなどが出ます。 ・よって、無限ループのときは『for(;;){}』という風にすれば良い。→3つ省略可能なのです。 ・以上。おわり。

参考URL:
http://www.bohyoh.com/CandCPP/C/Library/fflush.html
noname#39315
質問者

お礼

丁寧に指摘していただきありがとうございます。 無限ループしたい時はだいたいwhile(1)を使っていました(汗 確かにfor文を使ったほうがスッキリした感じがしていいですよね。 とても参考になりましたありがとうございます!!

その他の回答 (2)

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.3

scanf で数字だけ読み取っても、バッファに改行が残っているので (これは#1の型のおっしゃるとおり)それを何らかの形で読み飛ばさないと getchar()で最初にその残った改行を読むことになってしまいます。 改行まで空読みするなどするか、行の読み取りとそこから 数値としての取り出しを二段構え(たとえば fgets + sscanf)で やるなどしたほうが良いと思います。 ところで入力に残った「ごみ」を片付けなければならないのはいいとして、 仮にも「専門家」を名乗る人が fflush(stdin) を最重要とか 云ってしまうのはいかがなものかと。 処理系によっては期待通りの動作をするかもしれませんが、 int fflush(FILE *ostream); ostream points to an output stream or an update stream in which the most recent operation was not input, the fflush function causes any unwritten data for that stream to be delivered to the host environment to be written to the file; otherwise, the behavior is undefined. この通り「未定義」動作です。

noname#39315
質問者

お礼

ご回答ありがとうございます。 とても助かりました!!

  • shibamu
  • ベストアンサー率50% (10/20)
回答No.1

最初のscanfをしたところで入力された改行コードがバッファに残ってしまい、それが次のgetcharのループで読み出されることですぐにループが終わってしまっているようです。 解決方法としては、scanfを行った後に、バッファの内容をクリアすれば良いと思います。 具体的には fflush(stdin); を追加します。 また、文字列の読み込みをgetcharをループさせることで行っていますが、fgets関数を用いることでこの場合と同様にscanfのように領域をオーバーしないで文字列の読み込みができます。 調べてみて、使ってみると良いと思います~。

参考URL:
http://kitaj.at.infoseek.co.jp/fgets.html
noname#39315
質問者

お礼

ご回答ありがとうございます!! scanfを使うと改行コードがバッファに残るということをはじめて知りました。fgetsでも試してみたいとおもいます。 とても助かりました^^

関連するQ&A

  • C言語のポインタorアロー演算子について質問です。

    はじめまして。 今回が初質問となります。 お時間がある方はぜひご回答をよろしくお願いいたしますm(_ _)m C言語を独学で学んでいるため無知なところが多いです... やさしく、わかりやすく教えて頂ければ幸いです(>_<) #include<stdio.h> typedef struct grades { int number; char name[20]; double average; }record; int main(void) { int i; record student1 = {6,"NODA",52.5}; record student2[5] = { {1,"CHIAKI",78.6},{2,"MINE",57.3},{3,"MIKI",66.4},{4,"OKUYAMA",91.4},{5,"SAKU",89.2} }; record *p; record *s; p = &student1; s = &student2[5]; printf("%d %s %5.1f\n\n", p->number, p->name, p->average); for(i=0; i<5; i++) { printf("%d %s %5.1f\n", s->number, s->name, s->average); } return 0; } 上記プログラムを実行しますと以下の結果で出力されてしまいます。 6 NODA 52.5 6 NODA 52.5 6 NODA 52.5 6 NODA 52.5 6 NODA 52.5 6 NODA 52.5 ポインタのとこでつまずいている気がするのですが 具体的にどこが悪いのかが分からずに進めずにいます。 (もしポインタでないならすいません...もしかしたらアロー演算子?) どうか優しい方、ご回答のほどお願いいたします。

  • c言語のプログラミングについて聞きたいのですが

    自分は課題で「10人分の名前と点数を入力して降順に並び替える」というプログラムを作ろうとしているのですが、なかなかうまくいきません。一応↓の形までできたのですがなぜか数字が変になります。 どうしてか教えていただけないでしょうか。 #include<stdio.h> int main(void) {     int i,j;     int tensu[10][3];     char namae[10][6]; for(i=0;i<10;i++){ printf("名前の入力>>"); scanf("%s",&namae[i]); printf("点数の入力>>"); scanf("%d",tensu[i]); } printf("名前   点数\n"); for(j=0;j<10;j++) { printf("%s ",&namae[j]); printf("%10d\n",tensu[j]); } return 0; } それとポインタ?みたいなのもよく理解できず、点数で降順にしたあとに点数を使って名前を並び替えるのかなと思うのですがそれもよくわかりません。 どなたか教えてください

  • C言語での構造体

    C言語の構造体で配列を扱うとき、 struct ○○{  char ○○[○] とすれば出来ますが、同じようにして構造体で二次元配列を扱うことは出来ますか? 一度組んでみたのですが、 #include<stdio.h> struct aaa{ int no; char name[128]; char y_name[128]; char n_name[128]; char s_name[128][128]; }; int main(void){ int i; struct aaa iryo[99]; printf("入力前\n"); /* 構造体配列に scanf()でデータを入力 */ for(i = 0; i < 3; i++) { // printf("input...\n"); scanf("%d", &iryo[i].no); scanf("%s", iryo[i].name); scanf("%s", iryo[i].y_name); scanf("%s", iryo[i].n_name); scanf("%s", iryo[i].s_name); } printf("入力後\n"); printf("出力前\n"); /* 入力データの確認 */ for(i = 0; i < 3; i++) { printf("番号:%02d 内容:%s Y分岐:%s N分岐:%s 他分岐:%s\n", iryo[i].no, iryo[i].name, iryo[i].y_name, iryo[i].n_name, iryo[i].s_name); } printf("出力後\n"); printf("%d",sizeof(struct aaa)); return 0; } としたら、エラーは出ませんが、実行すると何も表示されませんでした。

  • C言語について

    #include <stdio.h> struct syoukai{ int no; char name[5]; }; int main(void) { struct syoukai mine = {3, "aaaaa"}; int cmdID ; printf("コマンドを入力してください\n"); scanf("%d\n",cmdID); if(cmdID == 1) printf("%d\n",syoukai.no, syoukai.name); } これをコンパイルして実行すると Segmentation fault とエラーになってしまい原因がわかりません 教えていただけますか?

  • C言語のプログラムについてです

    5人の名前と身長を入力し、1番高い人の名前と身長を表示せよというものです。 下記のソースプログラムをコンパイルすると warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char (*)[10]’ と表示されます。どこを修正すればよいのでしょうか? またこのプログラムにはchar関数を使っていますが、char関数というのも良く分かりません その解説も付け加えていただけると幸いです#include <stdio.h> #include <string.h> int main(void) { int i,sincho,max_sincho; char max_namae[10],namae[10]; max_sincho=0; for(i=1;i<=5;i++){ printf("名前: "); scanf("%s", &namae); printf("身長: "); scanf("%d", &sincho); if(sincho>max_sincho){ max_sincho=sincho; strcpy(max_namae,namae); } } printf("身長が一番高い人は%sさんで%d cmです。\n", max_namae,max_sincho); return 0; }

  • C言語について教えてください。

    #include <ctype.h> #include <stdio.h> void name_toupper(char istr[], char ostr[]) { unsigned i = 0; while (istr[i]) { ostr[i] = toupper(istr[i]); i++; } ostr[i] = '\0'; } void name_tolower(char istr[], char ostr[]) { unsigned i = 0; while (istr[i]) { ostr[i] = tolower(istr[i]); i++; } ostr[i] = '\0'; } void name_change(char istr[], char ostr[]) { unsigned i = 0; while (istr[i]) { if(isupper(istr[i])) { ostr[i] = tolower(istr[i]); } else { ostr[i] = toupper(istr[i]); } i++; } ostr[i] = '\0'; } int main(void) { char buffer[100]; char result[100]; printf("文字"); gets(buffer); name_toupper(buffer,result); printf("大文字: %s\n", result); name_tolower(buffer,result); printf("小文字: %s\n", result); name_change(buffer,result); printf("大小交換: %s\n", result); return 0; } 出力結果 文字abc DEFG 大文字: ABC DEFG 小文字: abc defg 大小交換: ABC defg 上のプログラムで文字関数isupperを用いずにプログラムする方法を教えてもらえませんか? もしくわ、用いずにプログラムすることは不可能ですか? 教えてください。 よろしくお願いします。

  • C言語 構造体の並び替え 

    #include<stdio.h> typedef struct{ char mozi[10]; char namae[30]; }PE; void input_profile(PE *p,int *a); void printf_profile(PE *p,int *a); int main(void) { int i=0; PE c[999]; input_profile(c,&i); return 0; } void input_profile(PE *p,int *a){ int c,b; for(b=0;999>b;b++) { printf("名前を入力\n"); scanf("%s",(p+b)->namae); printf("文字を入力\n"); scanf("%s",(p+b)->mozi); printf("入力を終えるなら0を入力してください\n続けるなら、それ以外の数字を入力してください\n"); scanf("%d",&c); if(c==0)break; } b++; *a=b; printf_profile(p,a); } void printf_profile(PE *p,int *a) { int b; for(b=0;*a>b;b++) { printf("NO%d\n",b+1); printf("文字%s\n",(p+b)->mozi); printf("名前%s\n",(p+b)->namae); } } このプログラムを 自分で関数を作って データ一覧をmoziのアルファベット順に表示するように書きなおしたいんですけど どうなるのでしょうか? どうか教えてください

  • C言語

    入力した文字列と文字列'x'を受け取り、'x'の位置のポインタを返すのですが、例えば、saxcvと入力すると、xcvと表示されるのですが、このソースだと、saxcvと全部表示されてしまいます。分からないので、教えてください。宜しくお願いします。 #include <stdio.h> char *a(char *sew) { char *p=sew; while (*sew != 'x') { sew++; } return(p); } int main(void) { char str[21] ={'\0'}; int i=0,no=0; char ch; printf("文字を入力してください:"); while (i<21) { ch=getchar(); if (ch=='\n') {break;} else if (ch != '\0' && ch != '\0') { str[i] =ch; i++; } } for(i=0; i<20; i++) { if(str[i]=='x') { printf("'x'以降は%sです。\n", a(str)); no=1; break; } } if (no==0) printf("'x'は見つかりませんでした。"); return (0); }

  • Cプログラムがどうしても動きません

    Cを勉強中です。 年齢に-1が入力されるまで、名前、年齢、性別を聞くプログラムを作っているのですが、どうしてもうまく動きません。 具体的には、年齢を聞かれず、年齢?性別?_とまとめて表示されてしまいます。 ぜひともどこが間違っているか教えてください。お願いしますm(_ _)m #include<stdio.h> typedef struct{ char name[20]; int year; char sex[6]; }student; void read_data(int,student*); void write_data(int,student*); int main(void){ student data[10]; int i=0,j=0; do{ read_data(i,data); i++; }while(data[i-1].year!=-1); for(j=0;j<=i-1;j++){ write_data(j,data); } return 0; } void read_data(int i,student *data){ printf("%d人目\n",i); printf("名前?\n",i); scanf("%s\n",&(data[i].name)); printf("年齢?\n",i); scanf("%d\n",&(data[i].year)); printf("性別?\n",i); scanf("%s\n",&(data[i].sex)); return; } void write_data(int j,student *data){ printf("%d人目\t",j+1); printf("名前:%s",data[j].name); printf("年:%d",data[j].year); printf("性:%s",data[j].sex); return; }

  • C言語の初心者です。教えてください

    #include<stdio.h> #define NAME 4 void main() { char str[NAME]; int i; for (i = 0;i < NAME;i++){ scanf("%s", &str[i]); } for(i = 0; i < NAME;i++){ printf("%s\n", str[i]); } } どこか間違っているのですか?それとも何か足りないのでしょうか? お願いします。