• 締切済み

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

私が作った関数がこれでいけるか気になったので、 評価してください。 内容は、決められた文字が入力されるまでループを繰り返すというものです。 評価して欲しい内容・・・ 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]; }

noname#16765
noname#16765

みんなの回答

回答No.2

・3の補足 3の入力をファイルに拡張する事を前提とした場合問題は発生します。ファイルは yEOF と書けますよね? また入力文字列が3文字以上の場合も改行コードがmoziに入りません。 まぁ、1文字入力だけを見るならばここは聞き流してください。 ・なぜ文字ではなく文字列対応にすべきか 自作された関数は「質問に対して決められた回答文字以外は受け付けない」機能を有したものですよね? その視点から見れば'y'や'n'だけでなく'キャンセル'や別の回答(例えば拡張して日本語回答にするかもしれない)を使用するケースもあるわけです。 >>ほとんど同じことを5ヶ所でしていたのでソースが見づらくなったのでそれならとわけて見ました。 と書かれている以上関数の意味合いを「まとめる」ものだけで見られているのかもしれません。関数は機能として作成するものであり「まとめられる」のはその特典の一つでしかありません。拡張性を失った時「まとめられる」特典は失われるからです。 >>GUIプログラムにして~ GUIにするのは一つの手段ですが、互換性を考えると得策ではないのはお判りかと。I/Fとしては誤入力を防ぐ効果は確かに高くユーザフレンドリーではあるのですが

回答No.1

色々ツッコミどころはあります。 1.関数名・変数名 日本語読みか英語かハッキリさせましょう。通常は英語ですが、英語に自信が無いなら日本語読みでも可です。自分だけが使うなら下手な英語よりは害悪がありません。 2.strchr()の使い方 使い方としては別に良いのですが、後で述べますが使う場面を間違っているように見られます。 3.その他の指摘 ・関数が複数の機能を有している…もしこの関数を入力がファイルから読み込んだものにする場合どうしますか?表示・入力チェックをキチンとばらしたモジュールにするか、せめて入力先は選択できる様にすべきでしょう。 ・文字列に改行コードが入っているのが前提になっている…前項とほぼ同じ理由ですね。 ・1文字入力しか想定していない…決められた文字が文字列の場合チェッカを別に作るのはナンセンスですよね? ・実はこの関数自体があまり必要ない…2と前項にも関わる事ですが'y'と'n'程度ならstrncmp()を使うべきでしょう。

noname#16765
質問者

補足

こんな頼みに回答してくれてありがとうございます。 3ですが入力はキーボードだけのつもりでした。 >>文字列に改行コードが入っているのが前提 fgets(mozi,sizeof(mozi),stdin); としたならば、どんなに長い文字列を入れた場合でもsizeof(mozi)の場所に\0が入るのではないのでしょうか? >>1文字入力しか想定していない それは自分も思いました。しかしyesかno、switch文の1~9ぐらいに使うだけなら特に文字列にする必要もないかと・・・ >>実はこの関数自体があまり必要ない ほとんど同じことを5ヶ所でしていたのでソースが見づらくなったのでそれならとわけて見ました。 ほかの回答は自分も思ってた部分もあります。 しかしここまでつっこまれるとは思ってもいませんでした。 やっぱしこういった無駄なものを作るぐらいならGUIプログラムにしてInputBoxとかでやらしたらいいのでしょうね(それにしたら必然的にYesとNoしか選べなくもなるし)

関連するQ&A

  • 可変長引数の扱い

     以下のプログラムが、 Hello,world. Hello, という出力しかしません。どうしてでしょう?  もしこういったことはcでは無理なのだとすれば、printfやsyslogなどのフォーマット指定のある出力関数のラッパーを書く他のいい方法があるんでしょうか? #include <stdio.h> #include <stdarg.h> #include <stdlib.h> void messout(const char *format, ...); int main(void) {   char *str = "world.";   printf("Hello,%s\n", str);   messout("Hello,%s\n", str);   exit(0); } void messout(const char *format, ...) {   va_list list;   va_start(list, format);   printf(format, list);   va_end(list); }

  • プログラミング 関数

    逆順する関数reverseを作成したいんです。 以下のは関数reverseを利用したmainのプログラムです。 #include <stdio.h> void reverse(char str1[],char str2[]); int main (void) { char strin[255]="abcdefg"; char strout[255]; reverse(strin, strout); printf(" input=%s\n",strin); printf("output=%s\n",strout); return 0; } 教えてください。

  • malloc関数(strtok関数の自作版)につきまして分からないこと

    malloc関数(strtok関数の自作版)につきまして分からないことがあります。 以下のプログラムにmallo関数がフリーする最適な位置を明示しなさいといわれました。 文字が分離した時にfreeすると助言されたのですが いまいち理解できません・・・。 条件式の中で使用するともいわれていました。(おそらくif文・・・。) 色んな意見を参考にしたいので詳しい方助言のほうよろしくおねがいします。 なおプログラムはほかの箇所を変更したり、他の場所でもmalloc関数を使用することが認められています。 またfreeする場所はメイン関数ではなくあくまでもstrtok関数の中で宣言するようです。 よろしくお願いします。 #include <string.h> #include <stdio.h> #include <stdlib.h> main(){ char* s2 = ",/"; char* result; char* r1; char* r2; char* r3; char* r4; result = strtok("//123//,45/,678,9/","/,"); r1 = strtok(NULL, s2); r2 = strtok(NULL, s2); r3 = strtok(NULL, s2); r4 = strtok(NULL, s2); printf("%s\n",result); printf("%s\n",r1); printf("%s\n",r2); printf("%s\n",r3); printf("%s\n",r4); return; } char *strtok(char *s1, const char *s2) { int i,len; char *str1, *str2 , *str3; static char *tok ; static char* mstr; if(s1 != NULL) { str1 = s1; } else { str1 = tok; } str2 = str1 + strspn(str1, s2); /* strspnを利用 */ if (*str2 == '\0') { return (NULL); } len = 1; i = 0; while(*(str2 + i) != '\0'){ len++; i++; } mstr = (char*)malloc(sizeof(char)*len); if(mstr == (NULL)) { return 0; } i = 0; while(*(str2 + i) != '\0'){ *(mstr + i) = *(str2 + i ); i++; } *(mstr + i ) = '\0'; str3 = mstr + strcspn(mstr, s2); /* strcspnを利用 */ if (*str3 != '\0'){ *str3 = '\0'; str3 = str3 + 1; } tok = str3; return (mstr); }

  • ログ出力関数

    C言語で、「可変長引数」を受け取る ログ出力関数を作っています。 /* ------------------------------------------------------ */ #include <stdio.h> #include <stdarg.h> void my_logger(char *format, ...) { va_list argptr; va_start(argptr, format); vprintf(format, argptr); va_end(argptr); } int main(void) { int n = 0; my_logger("logger : hello (%d)\n", n++); my_logger("logger : thank you (%d)\n", n++); my_logger("logger : bye (%d)\n", n++); return 0; } <実行結果> logger : hello (0) logger : thank you (1) logger : bye (2) /* ------------------------------------------------------ */ 出力する文字列に、"logger : "を毎回記述するのは面倒なので my_logger関数の中で"logger : "を追加したいのですが どうすればいいでしょうか。 ↓みたいなのもありかもしれませんけど、何だかねぇ、、、って感じですし -- 省略 -- va_start(argptr, format); printf("logger : "); vprintf(format, argptr); va_end(argptr); -- 省略 -- ↓のようなマクロを使う手もありますけど、、、わけあって使えません。 #define my_logger(fmt, ...) printf("logger : " fmt, __VA_ARGS__) どなたか、ご教授お願いします。

  • 自作関数について

    下記の時、関数copyを作成したいのですが、 関数copyにその都度、違う引数を渡たす為には どうしたら良いのでしょうか? 教えてください。 #include <stdio.h> void main() {      char a[20]={"ABCDEF"}; char b[20]; copy(a,b); printf("%s\n",b); copy(a,&a[3]); printf("%s\n",buf); copy(&b[2],dat[5]); printf("%s\n",dat); }

  • C言語 strcmp 半角スペースがあるとだめ?

    C言語 strcmp 半角スペースが文字列に含まれている場合 文字列の比較がうまくいきません。半角スペースがあると比較できないのでしょうか? プログラム //strcmp #include <stdio.h> #include <string.h> int main(void){ char input[256]; char str[] = "HelloWorld!";   //char str[] = "Hello World!";だとうまくいかない。 printf("%s\n>", str); scanf("%s", input); if ( strcmp(input, str) == 0){ printf("同じです。\n"); }else{ printf("違います。\n"); } return 0; }

  • 文字列のコピー

    C言語で、文字列をコピーする関数で、処理が止まってしまいます。 以下が実行したプログラムです。 #include<stdio.h> #include<string.h> void copy(char *str2 ,char *str3){ strcpy(str2,str3); } void input(char* str){ scanf("%s",str); } int main (void){ char *a; char *b="TEST"; printf("%s\n",b); input(a); copy(b,a); printf("%s",b); return(0);} copy(b,a);で処理が止まってしまいます。入力した文字列を表示できるように、御指摘お願いします。

  • C言語 文字列操作

    トリム関数とリムーブ関数を作成してみました。改良点はありますでしょうか? ~~~~以下ソース~~~~ #include <stdio.h> #include <stdlib.h> #include <string.h> char *Trim(char *str); char *Remove(char *str, char *rmv); void main(void) {  char str[10], rmv[10], *p;  int c;  /* " abcd "をトリムする */  strcpy(str, " abcd ");  printf("トリム前 |%s|\n", str);  p = Trim(str);  printf("トリム後 |%s|\n", str);  /* 指定文字列を削除する */  printf("削除する文字列を入力してください :");  scanf("%s", rmv);  Remove(str, rmv);  printf("削除後 |%s|\n", str);  exit(0); } char *Trim(char *str) {  char space[] = " ";  char null[] = "";  int index = 0;  while(1){   if(strcmp(&(str[index]), null) == 0){    index--;    if(strncmp(&(str[index]), space, 1) == 0){     strcpy(&(str[index]), &(str[index]) + 1);    }else{     break;    }   }else{    if(strncmp(&(str[index]), space, 1) == 0 && index == 0){     strcpy(&(str[index]), &(str[index]) + 1);    }else{     index++;    }   }  }  return str; } char *Remove(char *str, char *rmv) {  int c, size, i;  char *p;  c = '\0';  p = strchr(rmv, c);  size = p - rmv;  for(i = 0; i < size; i++){   c = (int)rmv[i];   p = strchr(str, c);   if (p != NULL) {    strcpy(&(str[p-str]), p + 1);   }   else{    printf("""%c""は見つかりませんでした\n", c);   }  }  return str; }

  • プログラミング(関数reverseを作る)

    プログラミングの勉強会で文字列を反転させる関数(例:ABCDE→EDCBA)を作れという課題が出たのですが、以下のように書いたきり進みません。あと、何を書けばいいのでしょうか?教えてください。 #include <stdio.h> void reverse(char *); void reverse2(char *); void main(){ char buf[10]; printf("str :"); fgets(buf, 10, stdin); reverse(buf); printf("rev :%s", buf); return; } //文字列を反転させる関数 void reverse(char *s){ return; }

  • プログラミング 関数

    教えてください。 入力された文字列のうち、文字aの数を数える関数count_aを作成する。 以下は関数count_aを利用したmainのプログラムの例です。 #include <stdio.h> int count_a(char str[]); int main ( void ) { char str[255]="abcaeag"; printf("%d\n",count_a(str)); return 0; }

専門家に質問してみよう