• 締切済み

C言語の変換する関数について教えてください。

キーボードからローマ字で入力された名前の英文字を変換する関数を定義し、その関数の機能を確認するプログラムを作成する問題について教えてください。 (1)英小文字であればそれを英大文字に変換する関数 (2)英大文字であればそれを英小文字に変換する関数 (3)英小文字であればそれを英大文字に、英大文字であればそれを英小文字に変換する関数 ただし、キーボードから入力された名前を格納する配列と、変換後の名前を格納する配列を別にする。 また、名前は関数main()内で表示する。 #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++; } } void name_tolower(char istr[], char ostr[]) { unsigned i = 0; while (istr[i]) { ostr[i] = tolower(istr[i]); i++; } } void name_change(char istr[], char ostr[]) { unsigned i = 0; while (istr[i]) { if(isupper(istr[i])) { ostr[i] = toupper(istr[i]); } else { ostr[i] = tolower(istr[i]); } i++; } } int main(void) { char buffer[100]; printf("文字"); gets(buffer); name_toupper(buffer); printf("大文字: %s\n", buffer); name_tolower(buffer); printf("小文字: %s\n", buffer); name_change(buffer); printf("大小交換: %s\n", buffer); return 0; } 上のプログラムでは、呼び出し時のパラメータが足りないとエラーが発生してしまいます。文字列を入れておく配列をbuffer以外にもう一つ作らなくてはいけないと思うのですが、うまくいきません。 教えてください。よろしくお願いします。

みんなの回答

  • chie65535
  • ベストアンサー率43% (8524/19373)
回答No.9

>上のように変えましたが出力結果が下のようになってしまいます。 >文字abc DEFG >大文字: ABC DEFGゥヲ・・・Tユ、v >小文字: abc defgゥヲ・・・Tユ、v >大小交換: abc DEFGゥヲ・・・Tユ、v >なぜだが分かりません。 大文字に変換する時、小文字に変換する時、大文字小文字を逆にする時、あなたは while (istr[i]) ってやってます。 これ、意味判ってやってますか? これは「istr[i]が0になったら文字列の終りだから、そこでヤメ」って事ですよね? つまり「文字列の終りは、文字が0になってる」のですね。 で、あなた、resultに「変換した文字」を入れたは良いけど「文字列の終りを示す0」は入れてますか? char result[100]; っってのは「100文字分の場所は取ったけど、中身はどうなってるか知らないよ」って宣言です。 あなたが「resultの先頭から、ABC DEFGと入れた」ら、その後ろは「ゴミ」です。 文字列の終りのマークの0を入れてないので、resultを表示したら、後ろのゴミも一緒に表示されます。 ここまで書いたら、どこをどう直せば良いか、もう判りますね。 もし判らないなら、以下の2つのプログラムを実行して、結果を比べてみましょう。 プログラム1 #include <stdio.h> int main(void) { char buffer[100]; char result[100]; result[0] = 'A'; result[1] = 'B'; result[2] = 'C'; result[3] = 'D'; printf("文字列: %s\n", result); return 0; } プログラム2 #include <stdio.h> int main(void) { char buffer[100]; char result[100]; result[0] = 'A'; result[1] = 'B'; result[2] = 'C'; result[3] = 'D'; result[4] = '\0'; // result[4] = 0;と同じ printf("文字列: %s\n", result); return 0; } 結果は プログラム1 文字列: ABCD=k裳ゥヲ・・・Tユ、v (「=k裳ゥヲ・・・Tユ、v」の部分は上記と違うかも知れない) プログラム2 文字列: ABCD となった筈。

noname#88772
noname#88772
回答No.8

 再びNo.6です。  すいません、補足のソースを見間違えました。No.7の回答は忘れてください。  とりあえず、動作が怪しい name_change() について  toupper() の前に、 printf( " istr[%d]:%c, ostr[%d]:%c\n", i, istr[i], i, ostr[i] );  toupper() の後に、 printf( " => istr[%d]:%c, ostr[%d]:%c\n", i, istr[i], i, ostr[i] ); を入れてみてください。思っていた動作になりましたか?

noname#88772
noname#88772
回答No.7

 No.6です。  No.5さんの言いたい事を解りやすく言うと以下の通りです。  result さんが“なぜ、俺を出さない!”と思っています。

cutebut
質問者

補足

name_toupper(buffer,result); printf("大文字: %s\n", result); name_tolower(buffer,result); printf("小文字: %s\n", result); name_change(buffer,result); printf("大小交換: %s\n", result); にしてもダメでした。 出すとはどこにですか? よろしくお願いします。

noname#88772
noname#88772
回答No.6

 こんにちは。  関数に通す前にresultを初期化しておいてください。  ゴミが詰まってます。  ご参考までに。

  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.5

>name_toupper(buffer,result); >printf("大文字: %s\n", buffer); >name_tolower(buffer,result); >printf("小文字: %s\n", buffer); >name_change(buffer,result); >printf("大小交換: %s\n", buffer); 変換を行った結果がresultに出力されるので、 印字すべきは、resultの内容では内でしょうか。

cutebut
質問者

補足

申し訳ございません。 うまく理解できないので詳しく教えてもらえませんか? よろしくお願いします。

  • chie65535
  • ベストアンサー率43% (8524/19373)
回答No.4

当方の回答が意味不明ですね。 「この6行」じゃなく「下記の6行」ですね。

  • chie65535
  • ベストアンサー率43% (8524/19373)
回答No.3

>上のようにプログラムを変更したところコンパイルではエラーが出ないのですが、出力結果が下のようになってしまいます。 この6行だけ「じっ~~~~~」っと見ましょう。穴が開くほど見ましょう。モニタが焼け付くくらい見ましょう。 そして「自分が何を表示させようとしているのか?」に思いを馳せましょう。 そして「自分が表示したいのは何か?」にも思いを馳せましょう。 すべての原因は以下の部分にあります。 name_toupper(buffer,result); printf("大文字: %s\n", buffer); name_tolower(buffer,result); printf("小文字: %s\n", buffer); name_change(buffer,result); printf("大小交換: %s\n", buffer); もっと言えば、以下の3行にあります。 printf("大文字: %s\n", buffer); printf("小文字: %s\n", buffer); printf("大小交換: %s\n", buffer); それでも判らない場合は「選択授業にC言語を選んじゃったのを後悔する」しかありません。たぶん、貴方にC言語は向いてません。

cutebut
質問者

補足

#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++; } } void name_tolower(char istr[], char ostr[]) { unsigned i = 0; while (istr[i]) { ostr[i] = tolower(istr[i]); i++; } } void name_change(char istr[], char ostr[]) { unsigned i = 0; while (istr[i]) { if(isupper(istr[i])) { ostr[i] = toupper(istr[i]); } else { ostr[i] = tolower(istr[i]); } i++; } } 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ゥヲ・・・Tユ、v 小文字: abc defgゥヲ・・・Tユ、v 大小交換: abc DEFGゥヲ・・・Tユ、v なぜだが分かりません。 教えてもらえませんか。よろしくお願いします。

  • arain
  • ベストアンサー率27% (292/1049)
回答No.2

No.1です はじめに、きついことを書くことを宣言しておきます。 甘ったれるな! 質問に >上のプログラムでは、呼び出し時のパラメータが足りないとエラーが発生してしまいます。 とあるから、エラーが発生する理由も書いてある。 >エラー発生行だけをなおすだけじゃいけないというところまでしか分かりません。 そもそも、これは関数に合わせて引数を直しての発言か? 修正したのなら、そのソースを提示してから言え! 提示もなしに「なおすだけじゃいけない」なんてことは言えない。 エラー行を直せば、ひょっとしたら動くかもしれない。 動かないなら、どう動かない(もしくは正しくならない)かは書けるはず。 上記はそれすら放棄した発言ととる。 「分からないから質問する」これは誰しもあること。 但し、その際にあったアドバイスがどれだけ次に生きてくるかが問題。 すでに何度かの質問で様々な質問の仕方についてもアドバイスされている。 それが一切に生きていない。

cutebut
質問者

補足

申し訳ございません。 #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++; } } void name_tolower(char istr[], char ostr[]) { unsigned i = 0; while (istr[i]) { ostr[i] = tolower(istr[i]); i++; } } void name_change(char istr[], char ostr[]) { unsigned i = 0; while (istr[i]) { if(isupper(istr[i])) { ostr[i] = toupper(istr[i]); } else { ostr[i] = tolower(istr[i]); } i++; } } int main(void) { char buffer[100]; char result[100]; printf("文字"); gets(buffer); name_toupper(buffer,result); printf("大文字: %s\n", buffer); name_tolower(buffer,result); printf("小文字: %s\n", buffer); name_change(buffer,result); printf("大小交換: %s\n", buffer); return 0; } 上のようにプログラムを変更したところコンパイルではエラーが出ないのですが、出力結果が下のようになってしまいます。 文字ABC defg 大文字: ABC defg 小文字: ABC defg 大小交換: ABC defg どうすれば、正しいプログラムになるか分かりません。 教えてください。

  • arain
  • ベストアンサー率27% (292/1049)
回答No.1

>上のプログラムでは、呼び出し時のパラメータが足りないとエラーが発生してしまいます。 エラーメッセージと一緒に、エラーの発生行が表示されるはずです。 その出ている場所をよく確認してください。 今回の場合は、関数宣言では引数が「二つ」なのに、呼び出しでは引数が「一つ」しかないからです。 だからパラメーターが「足りない」となります。

cutebut
質問者

補足

エラー発生行だけをなおすだけじゃいけないというところまでしか分かりません。 どうすればよいのか具体的に教えてもらえませんか? よろしくお願いします。

関連するQ&A

  • C言語の変換する関数について教えてください。

    キーボードからローマ字で入力された名前の英文字を変換する関数を定義し、その関数の機能を確認するプログラムを作成する問題について教えてください。 (1)英小文字であればそれを英大文字に変換する関数 (2)英大文字であればそれを英小文字に変換する関数 (3)英小文字であればそれを英大文字に、英大文字であればそれを英小文字に変換する関数 ただし、キーボードから入力された名前を格納する配列と、変換後の名前を格納する配列を別にする。 また、名前は関数main()内で表示する #include <ctype.h> #include <stdio.h> void name_toupper(char str[]) { unsigned i = 0; while (str[i]) { str[i] = toupper(str[i]); i++; } } void name_tolower(char str[]) { unsigned i = 0; while (str[i]) { str[i] = tolower(str[i]); i++; } } int main(void) { char str[100]; printf("文字"); scanf("%s", str); name_toupper(str); printf("大文字: %s\n", str); name_tolower(str); printf("小文字: %s\n", str); return 0; } 自分で作った上のプログラムではKa siと入力すると(1)ではKA、(2)ではkaと表示されsiが消えてしまいます。原因がよくわかりません。 あと(3)ができないし、ただしを満たしているのかもあいまいです。 文字列の入力の形式:char *gets(char *buffer)を用いればどうにかなるのではと思っていますがどうですか? 説明が長くなって申し訳ありませんが教えてください。 よろしくお願いします。

  • 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言語ののポインタについて

    「明解C言語 入門編」p262の演習11-4についての質問です。 このサイトも参考にしてみて、 入力された文字の大文字小文字を反転するプログラムをvimで書いてみたのですが #include <stdio.h> #include <ctype.h> void str_toupper(char *str) { while (*str = toupper(*str)) { *str++; } } void str_tolower(char *str) { while(*str = tolower(*str)) { *str++; } } int main(void) { char str[100]; printf("文字列を入力してください:"); scanf("%s", str); str_toupper(str); printf("大文字:%s\n", str); str_tolower(str); printf("小文字:%s\n", str); return(0); } clangを用いてコンパイルすると4warnings generatedと出ます。 ------------------------------------------------------------ ex11-4.c:6:13: note: use '==' to turn this assignment into an equality comparison while(*str = toupper(*str)){ ^ ------------------------------------------------------------- こんなのや ---------------------------------------- ex11-4.c:7:3: warning: expression result unused [-Wunused-value] *str++; ^~~~~~ ---------------------------------------------------- といった警告が表示されます。 どこをどう訂正すれば良いのでしょうか。 よろしくお願いします。

  • c言語 型変換について

    c言語 型変換について 下記のように文字コードは、unsigned int型('B')をunsigned char 型(str[1] ) 格下げする型変換する規則を教えてください。 *質問ソースプログラム: int main(void) { char str[4]; /* 文字列を格納する配列 */ str[0] = 'A'; /* 代入 */ str[1] = 'B'; /* 代入 */ ・・・・・・ printf("size B %u\n",(unsigned)sizeof('B')); printf("size str[1] %u\n",(unsigned)sizeof(str[1])); * 実行結果 size B 4 size str[1] 1

  • C言語

    文字列を逆順にするプログラムを考えているのですが分かりません。(例)qwerならrewqです。入力終了は、EOFです。考えたのですが、分かりません。(コンパイルエラーです。)教えてください。宜しくお願いします。#include <stdio.h> unsigned str_length(const char str[]) { unsigned len=0; while (str[len]) len++; return (len); } void put_rstring(const char str[]) { unsigned i = str_length(str): while (i-- >0) putchar(str[i]); } int main(void) { char str[30]; int ch; printf("文字列を入力\n"); /* ----この文字列を入力したあとに、Ctrl+Zを押すと、逆から表示               で反対から、文字列が表示----*/ while (1) { ch=getchar(); if (ch==EOF) break; } printf("逆から表示"); put_rstring(str); puts("です。"); return(0); }

  • c言語を用いた文書検索に関する質問です。

    いつもお世話になっています。 c言語にあまり詳しくないので、どなたか詳しい方お願いします。 今回、ディレクトリの複数文書内で特定の単語(今回はクエリと呼びます)を含む文書を探し出すして、テキストファイル名を表示する処理を行うプログラムを作成していました。 以下に添付したソースは、コンパイル自体は通るのですがコマンドラインを ./ex12 "green" corpus/*.txt と入力するとsegmentation faultとなってしまいます。 (ex12は実行ファイル名、greenに特に意味はありません。別の単語でも同じ結果が出てしまいます。) 複数ファイルではなく1つの文書内での検索は問題なかったのですが、何が原因なのかがよく分かりません。 1つの文書内検索の際は、メインループの最初のfor文を除いての処理となります。 printfを用いていろいろ試した結果、ファイル自体はきちんと読み込めているようなのでfor文を入れたのが原因ではないようなのですが・・・。 ちょっと原因が分からなくて詰まってしまったので、どなたか詳しいかたよろしくお願いします。 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<ctype.h> int main(int argc, char* argv[]){ FILE* fp; char buffer[2048]; char kueri[256]; char* s; char* delimiter = " .,"; //単語の区切れの定義 int i; int flag = 0; /*コマンドラインが正しく入力されているかの確認*/ if(argc < 3){ printf("error1\n"); exit(1); } /*入力されたクエリをkueriに格納する*/ strcpy(kueri,argv[1]); /*英小文字を英大文字に変換する処理を\0まで繰り返す*/ s = kueri; while(*s != '\0'){ *s = toupper(*s); s++; } /*メインループ*/ for(i = 2; i < argc; i++){ /*ファイルを開く*/ if((fp = fopen(argv[i], "r")) == NULL){ printf("error2"); exit(1); } while(fgets(buffer,sizeof(buffer),fp) != NULL){ /*最後に\0を格納する*/ buffer[strlen(buffer)-1] = '\0'; /*英小文字を英大文字に変換する処理を\0まで繰り返す*/ s = buffer; while(*s != '\0'){ *s = toupper(*s); s++; } /*strtokを用いて単語毎に区切っていく(1単語目)*/ s = strtok(buffer,delimiter); if(strcmp(s,kueri) == 0){ printf("入力されたクエリを文書内に発見しました。\n"); printf("file name: %s\n",argv[i]); flag = 1; }else{ /*strtokを用いて単語毎に区切っていく(2単語目以降)*/ while((s = strtok(NULL, delimiter)) != NULL){ if(strcmp(s,kueri) == 0){ printf("入力されたクエリを文書内に発見しました。\n"); printf("file name: %s\n",argv[i]); flag = 1; } } } } fclose(fp); } if(flag == 0){ printf("クエリを文書内に発見できませんでした。\n"); } exit(0); }

  • 文字列str内の全ての数字を削除する関数

    文字列str内の全ての数字を削除する関数 void del_digit(char str[]) を作成。 (例えば、"ab1C9"を受け取ったら、"ABC"にする) という関数を作りたいのですが、うまくいきません。 過去に似たような『文字列内の数字削除』の質問をされた方が いましたが、ポインタを使っていました。 http://okwave.jp/qa1775576.html ポインタを使わずにするには、どうしたらよいのでしょうか? 途中まで作ってみたのですが、うまく動きません。 #include <stdio.h> #include <ctype.h> void del_digit(char str[]) {     unsigned i = 0, j = 0;     char ctr[] = {'0'};     while (str[i] != '\0') {           ctr[i] = str[i];           i++;     }     i = 0;     while (ctr[i] != '\0') {           if (ctr[i] < '0' || ctr[i] > '9') {              str[j] = toupper(ctr[i]);              j++;           }           i++;     }     str[j] = '\0'; } int main(void) {     char str[100];     printf("文字列を入力してください:");     scanf("%s", str);     del_digit(str);     printf("%s\n", str);     return (0); }

  • C言語 ポインタ 関数

    キーボードから文字列”abcdefg”を入力し、main関数で配列aryに格納する。 main関数から配列aryの先頭アドレスを副関数に引き渡す。 副関数で配列aryの最後尾の要素の内容を';'に変更する。 main関数で配列aryの内容を表示する。 この問題が解けません... #include <stdio.h> int main (void) { char ary[]="abcdef"; int *p; int i,x; p=&ary[0]; func(&i); for (x=0;x<=7;x++){ printf("%s",ary[x]); void func (int i) if(i==\0) i=';' else i++ } return 0 } とりあえずこんな感じなんですけど、出来ませんでした...

  • プログラム

    文字列str内のすべての英字を大文字に変換する関数および小文字に変換する関数void str_toupper(char *str)    void str_tolower(char *str) を作成したいのですが、検討つかなくて困っています、、 表示例としては、 文字列を入力:asDFgH 大文字:ASDFGH 小文字:asdfgh

  • 関数がうまく動作しない

    関数get_monthにchar *型の文字列を引数にして、先頭の三文字(大文字でも小文字でも可)が正しいかどうかを関数strnxcmpでチェックしていくものです。 ところが、関数get_month中のreturn iで帰ってくるのはメインプログラムを動作させたところいつも0になってしまっているようです。(本当は1~12が帰ってくるようにしたい。) for(i=1;i<=12;i++) { if(strnxcmp(tuki[i],s,3)==0) { return i;←ここのリターンで0が帰ってきてしまう。 } } } 何がおかしいためにこのようになってしまうのでしょうか? よろしくお願いします。 int strnxcmp(const char *s1,const char *s2,size_t n) { while(n && toupper(*s1) && toupper(*s2)) { if(toupper(*s1) != toupper(*s2)) { return ((unsigned char)*s1 - (unsigned char)*s2); } s1++; s2++; n--; } if(!n)return 0; if(*s1) return 1; return -1; } int get_month(char *s) { int m,i; char *tuki[]={"","January","Feburary","March","April","May","June","July","Augst", "September","October","November","December"}; for(i=1;i<=12;i++) { if(strnxcmp(tuki[i],s,3)==0) { return i; } } return -1; }

専門家に質問してみよう