• 締切済み

助けてください。

C言語の勉強をしているのですがうまくいきません。 助けてください。 氏名、誕生日、血液型を入力し表示する関数を作りたいです。 形としては、氏名を入力し、誕生日を入力したあとに血液型を入力する関数ですが、血液型入力を下の表を表示して選択式にしたいのです。 --------------------------- 番号を入力してください 1;A 2;B 3;O 4;AB 5;? --------------------------- ここで仮に1を入力します。 最終的に入力したものが -------------------- 名前:taro 誕生日:19830917 血液型:A -------------------- と表示されるようにしたいです。 そのための関数を作ったのですが、うまく作動しません。 どこがおかしいか教えてください。 関数はこれです。 #include<stdio.h> #include<string.h> #include<stdlib.h> int main(void) { char Buff[20]; char Buff2[9]; char Buff3[5]; char Buff4[5]; int i; char BLOODNAME[5][4] = {"A","B","O","AB","?"}; printf("名前:"); fgets(Buff,20,stdin); printf("生年月日:"); fgets(Buff2,9,stdin); i = atoi(Buff2); printf("血液型を選べ\n"); printf("------------------------------------\n"); printf("1;A 2;B 3;O 4:AB 5;?\n"); printf("------------------------------------\n"); fgets(Buff3,5,stdin); if(strlen(Buff3) == 1) { switch(Buff3[0]) { case 1: strcpy(Buff4,BLOODNAME[0]); break; case 2: strcpy(Buff4,BLOODNAME[1]); break; case 3: strcpy(Buff4,BLOODNAME[2]); break; case 4: strcpy(Buff4,BLOODNAME[3]); break; case 5: strcpy(Buff4,BLOODNAME[4]); break; default: printf("強制終了ver1\n"); return 0; } } else { printf("強制終了ver2\n"); return 0; } printf("----------------------------------------\n"); printf("名前:%s\n",Buff); printf("生年月日:%d\n",i); printf("血液型:%s\n",Buff4); printf("----------------------------------------\n"); return 0; } あと誕生日なのですが今は入力したものがそのまま出力されますが、最終的には○○○○年○○月○○日と表示されるようにしたいのですが、上の関数にどう追加すればいいのかも教えてください。 お願いいたします・

みんなの回答

  • yama5140
  • ベストアンサー率54% (136/250)
回答No.3

>そのための関数を作ったのですが、うまく作動しません。  お示しのソースは、「関数」を作らずに、こんな風にもかける、ということで投稿します。 「ひとりだけ」で終了ですので(のちのちに)お役に立てず、あしからず。 なお、質問者様のソースを「動く」ようにするには、 >char Buff2[ 16 ];  ・ >fgets( Buff2, 16, stdin );  ・ >if( strlen( Buff3 ) == 2 )  ・ >switch( Buff3[ 0 ] - 0x30 ) の4行を修正するだけです(出力の見栄え?は別として)。 ☆ fgets(); は、\n まで取り込むので注意が必要です。 #include<stdio.h> #include<string.h> #include<stdlib.h> int main( void ) {  char cName[20];  int iDate, iBtype;  char BLOODNAME[5][4] = { "?", "A", "B", "O", "AB" }; // 順番注意  printf( "名前:" );  scanf( "%s", &cName );  printf( "生年月日(yyyymmdd):" );  scanf( "%d", &iDate );  printf( "血液型を選べ\n" );  printf( "------------------------------------\n" );  printf( "1;A 2;B 3;O 4:AB 5;?\n" );  printf( "------------------------------------\n" );  scanf( "%d", &iBtype );  iBtype %= 5; // 0, 1, 2, 3, 4 入力ミス一部対応(例 11 とチャタリング(笑)入力)  printf( "----------------------------------------\n" );  printf( "名前:%s\n", cName );  printf( "誕生日:%d年%2d月%2d日\n", ( iDate / 10000 ), ( ( iDate / 100 ) % 100 ), ( iDate % 100 ) );  printf( "血液型:%s\n", BLOODNAME[ iBtype ] );  printf( "----------------------------------------\n" );  return( 0 ); } 注:インデントに全角空白を用いています。コピペ後、タブに一括変換して下さい。

回答No.2

#include <stdio.h> int main(void) { char *bs = "19830917"; int bn = 19830917; printf("%.4s年%.2s月%s日\n", bs, bs + 4, bs + 6); printf("%d年%2d月%2d日\n", bn / 10000, bn / 100 % 100, bn % 100); return 0; }

  • nda23
  • ベストアンサー率54% (777/1415)
回答No.1

論理を組み立てないで、やたらコーディングしてもダメです。 文字列を入力したあとから考えましょう。 (1)入力文字数≠1バイト→エラー (2)入力文字<'1' OR 入力文字>'5'→エラー (3)入力文字を数値化(例:'1'→1) (4)入力文字を数値化したもの - 1 → BLOODNAMEの1次元目インデックス 先ず、文字の'1'は数値の1ではありません。switch(Buff3[0]) で 受けるべきcaseは'1'です。よって、case 1:(誤)→case '1'(正)です。 次に、血液型の名前をせっかく2次元配列にしているのに、switch文を 使うと言うのは如何なものでしょう?誰かの丸写しでもしましたか? ここは「文字→数値」,「数値=数値-1」として使いましょう。 int idx = Buff3[0] - '0' - 1; // '0'を減じると数値になる。 strcpy(Buff4,BLOODNAME[idx]); // 配列[0]~[4]のいずれかが転写される。 ポイント (1)文字を数値化するのには他にatoiもあるが、1文字のみなら'0'を  減じるか、0x0Fと論理積を取るほうが高速 (2)年月日が文字列の(0,4)、(4,2)、(6,2)と位置長さが決まっているなら、  memmove等を使って、各データに切り分けます。  【例】    char mon[3];    memmove(mon,&Buff2[4],2);    mon[2] = 0;  http://msdn.microsoft.com/ja-jp/library/8k35d1fx.aspx (3)自動変数に初期値は取れないので、char BLOODNAME[5][4]=~ のように  コーディングすると、常にデータを転送するコードが挿入されて、  処理効率が悪いので、(もっとも、無神経な人は気にしないが…)  static 属性を付けて静的な変数として定義しましょう。

関連するQ&A

  • 文字列の入力

    文字列(名前)と誕生日を読み込み、表示するプログラムです。文字列を読み込むときに空行を入力すると、読み込みを終了して表示するようにしたのですが、うまくいきません。読み込む時に使う関数が違うのだと思います。scanfとgets、fgetsは試したのですが、だめでした。 教えてください。 #include <stdio.h> #include <stdlib.h> #include <string.h> #define DATA 3 int main() { char *name[DATA]; char work[31]; int month[DATA]; int day[DATA]; int count1,count2; printf("Data #1\n"); printf("name ="); fgets(work,31,stdin); for(count1=0;(work[0]!='\n')&&(count1<DATA);count1++){ printf("month ="); scanf("%d",&month[count1]); printf("day ="); scanf("%d",&day[count1]); name[count1]=(char *)malloc((strlen(work)+1)*sizeof(char)); strcpy(*(name+count1),work); printf("\n"); if(count1<DATA-1){ printf("Data #%d\n",count1+2); printf("name ="); fgets(work,31,stdin); } } for(count2=0;(count2<DATA)&&(count2<count1);count2++){ printf("Data #%d\n",count2+1); printf(" name: %s\n",*(name+count2)); printf(" birthday: %2d %2d\n",month[count2],day[count2]); } }

  • gets fgetsについて

    対話式のプログラムを作成したのですが、fgetsのところで勝手に文字が入力されてるような処理になってしまい、こちら側から入力できません。 fgetsのところで通常通り入力できるようにするにはどうしたら良いのでしょうか? コードは以下のとおりです。 #include <stdio.h> #include <string.h> main() { int kazu; char sentaku[1]; char string[10]; printf("文字を入力してください\n"); /*文字入力要求のメッセージ*/ fgets(sentaku,1,stdin); /*確認時にenterを読み込まないようにfgetsで文字取得*/ sscanf(sentaku,"%d",&kazu); putchar(sentaku[1]); /*putcharを使ってmojiを画面出力*/ putchar('\n'); /*改行コードを出力*/ printf("ここから先に進みますか?-Y/N->\n"); fgets(sentaku,1,stdin); /*確認時にenterを読み込まないようにfgetsで対話する*/ sscanf(sentaku,"%d%",&kazu); if(sentaku[0]==121) /*入力した文字がyだった場合*/ { strcpy(string,"spring\n"); /*strcpyを使って変数に代入*/ putchar(string[0]); /*putcharを使って画面出力*/ putchar(string[1]); putchar(string[2]); putchar(string[3]); putchar(string[4]); putchar(string[5]); } }

  • scanfの後のfgetsについて

    #include <stdio.h> int main(void) { char name[10]; int no; printf("ナンバーを入力してください: "); scanf("%d",&no); /* 35を入力 */ printf("文字列を入力してください: "); fgets(name,10,stdin); /*入力できない*/ return 0; } この例文だと、fgets関数が改行コードを読み取って、終了してしまい文字列入力が出来ないみたいなんですが、scanfの後にfgetsを使うような(scanfとfgetsの間にscanfの残した?改行コードを取り除く方法)処理はどのような方法があるのでしょうか? 試しにfgets文を2度書いたら思っていた動作をしてくれたのですが、はたしてfgets文を2度書くというような事をしていいものなのでしょうか?見た目もなんだか変な感じですし。。↓ #include <stdio.h> int main(void) { char name[10]; int no; printf("ナンバーを入力してください: "); scanf("%d",&no); /* 35を入力 */ printf("文字列を入力してください: "); fgets(name,10,stdin); fgets(name,10,stdin);  /*入力できる*/ return 0; }

  • DirectX9で文字を一文字ずつ表示

    現在、DirectX9の勉強のために簡単なノベルゲームを制作しています。 画像やテキストを表示させたりするといった事は出来たのですが、 ノベルゲームらしくテキストが一文字ずつ流れるように表示させたいのですが、 やり方がわからずに困っています。 自分なりに考えてみたのですが、こんなのしか思い浮かびませんでした・・・。 switch( ( timeGetTime() - nowtimedayo ) / 300 ){ case 3: strcpy(buff,"僕"); break; case 4: strcpy(buff,"僕は"); break; case 5: strcpy(buff,"僕はこ"); break; case 6: strcpy(buff,"僕はここ"); break; case 7: strcpy(buff,"僕はここに"); break; case 8: strcpy(buff,"僕はここにい"); break; case 9: strcpy(buff,"僕はここにいる"); break; } どうか、お力をお貸しいただけないでしょうか・・・。 宜しくお願い致します。

  • 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関数を使用すると不可能なのではないか?と思っています。 分かる方が居ましたらどうか教えて下さい。 よろしくお願いします。

  • 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言語で書いています。 そこで、質問なんですが・・・ fgetsで文字を入力し、構造体にデータを入れる関数に渡すと セグメンテーションエラーになってしまいます。 文字列のポインタの問題だと思うのですが、よくわかりません。 誰か教えてください!! ーーーーソースーーーーー printf("name "); fgets(xx,255,stdin); printf("%s",xx); printf("tel "); scanf("%s",t); strcat(t,"\n"); printf("zip "); scanf("%s",z); strcat(z,"\n"); printf("add "); scanf("%s",ad); strcat(ad,"\n"); printf("email "); scanf("%s",em); strcat(em,"\n"); root = makenode( *xx,ss,y,t,z,ad,em, root ); //関数で構造体にデータを挿入する 関数 BinNode *makenode( char *x,char *t,char *z,char*ad,char *em, BinNode *current ) { if( current == NULL ) //currentに何も入っていないとき { current = (BinNode*)malloc(sizeof(BinNode)); //領域を確保する strcpy( current->data, x ); //読みを入力 strcpy( current->tel, t ); //電話番号を入力 strcpy( current->zip, z ); //郵便番号を入力 strcpy( current->add, ad ); //住所を入力 strcpy( current->email, em ); //emailを入力 current->left = current->right = NULL; //右と左のノードをNULLにする }

  • プログラム高速化について

    http://oshiete1.goo.ne.jp/qa5810041.html で質問させていただいた者です。 ソースは下ので動いているのですが、北海道近辺の郵便番号を調べようとするとすぐに結果が返ってくるのですが、 沖縄県辺りですと少し時間がかかってしまいます。(わずかな差ですが…) 恐らく、上から1個ずつしらみつぶしに調べているのでそのような結果になっているのはわかるのですが… これを高速化するにはwhile文をいじる必要があると思うのですが、どのようにしたら良いでしょうか? 以下がプログラムになります。 ken_all.csvの場所:http://www.post.japanpost.jp/zipcode/dl/kogaki.html #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #define NAME "ken_all.csv" #define SIZE 1024 #define setstr(x,z) {strcpy(x,strtok(z,",\""));} struct tb{ //構造体設定 char dummy[SIZE]; //全国地方公共団体コード char old_num[SIZE]; //旧郵便番号 char now_num[SIZE]; //現在の郵便番号 char kana1[SIZE]; //都道府県名(カナ) char kana2[SIZE]; //市区町村名(カナ) char kana3[SIZE]; //町域名(カナ) char kanji1[SIZE]; //都道府県名(漢字) char kanji2[SIZE]; //市区町村名(漢字) char kanji3[SIZE]; //町域名(漢字) }; int main(int argc, char *argv[]) { struct tb line; FILE *fp; char *address, buff[SIZE], string_buff[SIZE]; int flag; clock_t start,end; start = clock(); if(argc == 1){ printf("引数を指定してください\n"); } if(argc > 2){ printf("引数が多すぎます、引数は1つにしてください。\n"); return -1; } if((fp=fopen(NAME,"r"))==NULL){ printf("ファイル%sが開けません\n",NAME); return -1; } flag=0; address = argv[1]; while(fgets(buff,SIZE,fp) != NULL){ //各項目の設定 strcpy(line.dummy,strtok(buff,",\"")); strcpy(line.old_num,strtok(NULL,",\"")); strcpy(line.now_num,strtok(NULL,",\"")); strcpy(line.kana1,strtok(NULL,",\"")); strcpy(line.kana2,strtok(NULL,",\"")); strcpy(line.kana3,strtok(NULL,",\"")); strcpy(line.kanji1,strtok(NULL,",\"")); strcpy(line.kanji2,strtok(NULL,",\"")); strcpy(line.kanji3,strtok(NULL,",\"")); //文字の連結 strcpy(string_buff,line.kanji1); strcat(string_buff,line.kanji2); strcat(string_buff,line.kanji3); //住所の比較 if(strcmp(string_buff,address)==0){ printf("〒%s \n",line.now_num); flag=1; break; } //郵便番号の比較 if(strcmp(line.now_num,address)==0){ printf("%s \n",string_buff); flag=1; break; } } fclose(fp); if(flag==0 && atoi(argv[1]) == 0){ printf("「%s」に該当する郵便番号はありませんでした\n",address); } if(flag==0 && atoi(argv[1]) != 0){ printf("「%s」に該当する住所はありませんでした\n",address); } end = clock(); printf("%.30f秒かかりました\n",(double)(end-start)/CLOCKS_PER_SEC); return 0; }

  • fgetsについて

    いつも大変お世話になっております。 またしても基本的なことで恐縮ですが、教えてください。 『fgets()』を使って、標準入力ファイル(stdin)からの情報を読み込む場合、指定されたサイズ以上を入力すると、サイズを超えた部分が切捨てられて最後に'\n'が自動的に付加されると学習しました。 しかし、切り捨てられた部分はまだstdinに残るため、次回の利用でおかしな結果を招くようです。 そこで、stdinのバッファをクリアたほうが良いと思ったのですが、方法が分かりません。 どのようにすればよいでしょうか? 【例】 #include<stdio.h> #include<string.h>     char name[5]; printf("文字列を入力して下さい。>>"); fgets(name,sizeof(name)-1,stdin); printf("読み込み文字列:%s\n",name); このとき、キーボードから4文字入力するとstdinのバッファに'\n'が残ってしまい、5文字以上だと4文字目以降の文字と'\n'が残ってしまうようです。 また、最後に'\0'が付与されるなら、サイズ以上が切捨てられた際もname[4]に'\0'を代入しなくてもいいということでよいのでしょうか? 乱文になってしまい、申し訳ありません。 どうぞ教えてください。

  • 自作の関数を見てください。

    私が作った関数がこれでいけるか気になったので、 評価してください。 内容は、決められた文字が入力されるまでループを繰り返すというものです。 評価して欲しい内容・・・ 1.関数名や変数名 2.strchrの使い方 3.その他だめなとこがあったらすべて お願いします。 ソース(わかりやすいようにmain関数もつけます): #include<stdio.h> #include<string.h> #include<stdarg.h> char Input_True_char(char *str,char *format,...); int main(void) { char mozi; mozi = Input_True_char("ny","あなたは%d才以上ですか?(y/n)\n",18); if(mozi == 'y') { printf("18才以上です\n"); } else if(mozi == 'n') { printf("18才未満です\n"); } else { printf("バグ\n"); } return 0; } char Input_True_char(char *str,char *format,...) { char mozi[3]; va_list args; va_start(args,format); do{ vfprintf(stdout,format,args); rewind(stdin); fgets(mozi,sizeof(mozi),stdin); }while(mozi[1] != '\n' || strchr(str,mozi[0]) == NULL); va_end(args); return mozi[0]; }