• 締切済み

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)を用いればどうにかなるのではと思っていますがどうですか? 説明が長くなって申し訳ありませんが教えてください。 よろしくお願いします。

みんなの回答

  • chie65535
  • ベストアンサー率43% (8520/19369)
回答No.2

>自分で作った上のプログラムではKa siと入力すると(1)ではKA、(2)ではkaと表示されsiが消えてしまいます。原因がよくわかりません。 scanf("%s", str); scanfの「%s」は「入力の非読文字(空白、改行、タブなど)をスキップし、可読文字のみを取り込み、非読文字(空白、改行、タブなど)が来たら打ち切る」と言う動作をします。 つまり「Ka」まで取り込んで、次に半角スペースが来たので「Ka」だけをstrに格納します。その後ろにある半角スペースと「si」は、ストリーム(キーボード)の入力バッファに残ったままになります。 >あと(3)ができないし 1文字づつ「これは大文字だから小文字に、これは小文字だから大文字に、それ以外はそのまま」と言う処理が必要。 現状のプログラムは「大文字か小文字か判定しないで、toupper、tolowerにオンブにダッコ」してるから、少し考えないとならない。 >ただしを満たしているのかもあいまいです。 満たしていませんよ。 (1)は良いとして、(2)を実行する時に「入力した文字列ではなく、(1)で大文字に変換した文字列を、小文字に変換している」ので、問題の指示に従っていません。 (2)や(3)を実行する際には「入力したままで、書き替えしてない文字列」を変換させないとなりません。 ですが、質問者さんのプログラムでは(1)を実行し終わったら「入力したままで、書き替えしてない文字列」は失われています。 入力された変換前の文字列と、変換後の文字列を別にしろ、と言っているのですから、何度か変換を繰り返した後でも「入力された変換前の文字列が表示可能」でなければなりません。 つまり、質問者さんのプログラムで、変換して表示したあと、以下のように name_toupper(str); printf("大文字: %s\n", str); name_tolower(str); printf("小文字: %s\n", str); ★ printf("元の文字列: %s\n", ???); return 0; 「★の位置で、入力したままの、変換も何もしてない文字列を表示しろ」と言われたら、何もしてない文字列を表示出来ないと駄目なのです。 でも、質問者さんのプログラムでは、それは不可能です。 なので、今のまま提出しても「解答が題意に添ってないので不可の判定を貰う」でしょう。

cutebut
質問者

補足

どうすれば題意に添ったプログラムになるか教えてもらえませんか? よろしくお願いします。

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.1

scanf()直後のstrの中身を見てみればはっきりするでしょうが、スペースで入力終了扱いになっていてstr自体が"Ka"で終わってそうですね。 なお使うならgets()ではなくfgets()にしましょう。 また、この関数仕様では入力した配列を直接変換しているので「変換後の配列を別に定義する」という条件が全く満たせていません。

関連するQ&A

  • 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以外にもう一つ作らなくてはいけないと思うのですが、うまくいきません。 教えてください。よろしくお願いします。

  • 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++; ^~~~~~ ---------------------------------------------------- といった警告が表示されます。 どこをどう訂正すれば良いのでしょうか。 よろしくお願いします。

  • プログラム

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

  • 計算機言語(C言語)の課題です。

    ポインタstrが文字列の先頭文字を指している時、その文字列に含まれる英小文字を英大文字に変換する関数 void str_toupper(char *str) を作成しなさい。ただし、英小文字a~zおよび英大文字A~Zには、それぞれ昇順に、連続した1バイトの整数が割り当てられているものとする。例えば、aには10進数の97、zには10進数の122が割り当てられ、Aには10進数の65、Zには10進数の90が割り当てられるといった具合である。

  • toupper関数とstrcmp関数を使った問題

    前回答えてくださった方々へのお礼 ・前回質問した際、質問に答えてくださった方々、皆様のおかげで問題を解く事ができました。本当にありがとうございました。 ↓ここから質問です。 「end」と入力されるまで、キーボードから文字列を読み取るプログラムを作成してください。ただし、大文字と小文字が混ざった「EnD」などでも終了するようにしてください。小文字を大文字に変換する「toupper( )関数」を利用してください。また、文字列の比較には「strcmp( )関数」を利用してください。 という問題を解いているのですが、自分でした結果 #include <stdio.h> #include <ctype.h> #include <string.h> int main(void) { char str[10]; ←str[10]は適当に値を決めているだけです int i,ret; int result; do { printf("文字列を入力してください:"); scanf("%s", str); i = 0; while (str[i] != ???? ) // 文字列の最後かチェック { ret = toupper(?); // toupper関数に1つずつ渡す i++; } result = strcmp("END", str); //文字列の比較 if (result == 0) { break; //ループを抜ける! } } while (1);            // 条件が1の場合は永久ループ return 0; } ここまではできたのですが、どうしても while (str[i] != ???? ) // 文字列の最後かチェック { ret = toupper(?); // toupper関数に1つずつ渡す i++; } この部分の「?」と書いている部分がわかりませんでした。 わかる方が居られましたらどうか教えてもらえないでしょうか? あと、おかしな部分等がありましたら教えてください。 どうかよろしくお願いします。

  • C言語についてなのですが・・・

    さきほども上げたのですがカテゴリが間違っていたのでもう一回書き込みました まだプログラムの勉強をはじめた初心者なのですが、 テキストファイルから文字を読みこみ、大文字ならば小文字に変換し辞書順に並びかえるプログラムを作っているのですがどうしてもうまくいきません。 例えばtest.txtに XXX YYY YY XX BBB aaa aa BB とあれば aa aaa bb bbb xx xxx yy yyy と表示されるよにしたいんです。 自分が作ったプログラむはこれです。 まだテキストファイルからでなくキーボードからの入力になっていますが・・・ #include<stdio.h> #include<stdlib.h> #include<string.h> #include <ctype.h> int soto( const void *x, const void *y); int main(int argc, char *argv[]){ FILE *input; char str1[1000]; int i, j; for (i = 1; i < argc; i++){ qsort(argv[i], 1000, sizeof( char *), soto); strcpy(str1, argv[i]); for(j = 0; j < 100; j++){ str1[j] = tolower( str1[j] ); } printf("%s\n", str1); } return 0; } int soto( const void *a, const void *b){ char *x, *y; x = (char*)a; y = (char*)b; return x-y; } これだと小文字にはなるんですがソートされずに表示されてしまいます・・・ どのようにすればいけるのかご指摘のほどおねがいします

  • C言語について

    2つの文字列を入力して別の文字列にコピーするプログラムをつくっているのですが、どこが間違っているのでしょうか?教えていただけませんか? /*文字列連結*/ void *my_stract(char*, char*, char*); void main(void) { char bun1[100],bun2[100],bun3[200]; printf("文字列1を入力してください\n"); gets(bun1); printf("文字列2を入力してください\n"); gets(bun2); my_stract(bun1,bun2,bun3); puts(bun3); } char *my_stract(char *str3, char *str2, char *str1) { char *p1, *p2, *p3; p1=str1; p2=str2; p3=str3; while(*p1) { *p3=*p1; p1++; p3++; } while(*p2) { *p3=*p2; p2++; p3++; } *p3='\0'; return str3; }

  • 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); }

  • 文字列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); }

専門家に質問してみよう