C言語のプログラミングでポインタを使用して文字列を変換する方法

このQ&Aのポイント
  • C言語プログラミングで文字列を変換するために、ポインタを使用する方法について詳しく説明します。
  • string.hとctype.hに含まれる関数を使用せずに、文字列の大文字を小文字に変換する方法を解説します。
  • 提供されたコードのビルドエラーについて、原因を特定し、修正する方法について解説します。
回答を見る
  • ベストアンサー

C言語のプログラミングでつまずいてます

ポインタをりようする。string.hとctype.hに含まれる関数は使用しないこと。 以下の実行例のように、文字列を受け取り、アルファベットの大文字を小文字にして表示する関数を作成したいのですが 実行例: Original string is <AbCdE1f2> Modified string is <abcde1f2> #include <stdio.h> #define NUMOFCHAR 10 void print_char(char *ptr); int main(void) { char string[NUMOFCHAR+1]; printf("Input a sentence (# of letters <= %d): ", NUMOFCHAR); fflush(stdout); scanf("%s", string); string[NUMOFCHAR] = '\0'; printf("Original string is <%s>\n", string); printf("Modified string is <"); print_char(string); printf(">\n"); return 0; } void print_char(char *ptr) { int i=0; for(i=0 ; i<NUMOFCHAR+1 ; i++){ if( *ptr>='A' && *ptr<='Z'){ *ptr += 'A'-'a' ; } ptr++ ; } printf("%s",ptr); } よ書いたのですがビルドえらーがおこります。 どこがだめなのかわかりません。。。 C言語に詳しい人でわかるかた、どこがいけないのか、なぜいけないのか、どうすればいいのか詳しくおしえてください。 お願いします

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

  • ベストアンサー
  • wormhole
  • ベストアンサー率28% (1622/5659)
回答No.1

試しにコンパイルしてみたところ問題なくコンパイルできましたけど。 ビルドエラーが起こるということですが どういうエラーメッセージが出力されていますか? >C言語に詳しい人でわかるかた、どこがいけないのか、なぜいけないのか、どうすればいいのか詳しくおしえてください。 どこがいけないかで、ひとまずいえることは ・出力されているエラーメッセージを読んでいないこと。

kzmsreo
質問者

お礼

すみません。 なんかウィンドウズでやるとエラーないのにエラー表示されることがあるんです・・・ もう一回コピーしてはりつけたらエラーはありませんでした。 でも思惑通りに動作してませんでした。 大文字小文字のところはもう理解したので大丈夫ですが、ほかがまだなので詳しくかいていただけるとありがたいです。

その他の回答 (7)

  • TT414
  • ベストアンサー率18% (72/384)
回答No.8

>scanf("%s", string); >string[NUMOFCHAR] = '\0';//完全に無駄です、この文は削除しましょう。 >printf("Original string is <%s>\n", string); >int i=0; >for(i=0 ; i<NUMOFCHAR+1 ; i++){//バグおよび無駄です、「for(i=0 ; *ptr ; i++){」にしましょう。 >if( *ptr>='A' && *ptr<='Z'){ void print_char(char *ptr){ int i;char *s; for(s=ptr;*ptr;ptr++) for(i=0;i<26;i++) if(*ptr=="ABCDEFGHIJKLMNOPQRSTUVWXYZ"[i]){ *ptr=abcdefghijklmnopqrstuvwxyz[i]; break; } printf("%s",s); }

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.7

if( *ptr>='A' && *ptr<='Z') で「大文字かどうか」を正しく判定できるとは限らないんだけど, そのことは無視していいの?

kzmsreo
質問者

お礼

無視したらだめです… どうしたらいいでしょうか?

回答No.6

>どこがいけないのか、なぜいけないのか、どうすればいいのか詳しくおしえてください。 void print_char(char *ptr) で受けて、ptr++ ; のようにポインタを変えておきながら、printf("%s",ptr); として変わってしまっている ptr を出力しているところが大きな誤りです。 int i; を尊重して void print_char(char *ptr) はポインタで受けるのではなく、文字配列 void print_char(char ptr[]) として受けましょう。 void print_char(char ptr[]){ int i; for(i=0 ; ptr[i] != '\0' ; i++){ //ヌルまで繰り返す if( ptr[i]>='A' && ptr[i]<='Z'){ ptr[i] += 'a' - 'A' ; } } printf("%s",ptr); }

kzmsreo
質問者

お礼

ありがとうございます! 書き忘れててすみません 書き換える内容は下記の部分だけでお願いできますか? 参考にしてまた明日やってみますのでお暇があればまたお願いします ありがとうございました { int i=0; for(i=0 ; i<NUMOFCHAR+1 ; i++){ if( *ptr>='A' && *ptr<='Z'){ *ptr += 'A'-'a' ; } ptr++ ; } printf("%s",ptr); }

  • wormhole
  • ベストアンサー率28% (1622/5659)
回答No.5

>全然くわしくないので質問もうまくできません。。。 くわしいくわしくないは関係ないと思いますけど。 期待する結果と実際の結果がどう違うのかも説明しきれませんか? >引数の文字列を変換して返す >と >引数の文字列を変換したものを出力 >の違いもよくわかりません。 >結局同じ結果になるようなきがします・・・>< print_char()の処理からすれば同じにはなりませんよ。 前者だと少なくともprintf()で出力することはありませんし 後者だと*ptr += 'A'-'a';のように引数の文字列を書き換える必要はありません。 前者と後者の違いが具体的にわからないのであれば main()内のprint_char(string);のあとにprintf("%s", string);をいれてみてください。 出力するだけのprint_char()が、stringの内容を書き換えている(変換したものを返している)のが確認できると思います。

kzmsreo
質問者

お礼

前者だと少なくともprintf()で出力することはありませんし→returnを使うということですか?(どのように使うかわからなくてprintfでも同じかと思ったのでprintfつかいました) 後者だと*ptr += 'A'-'a';のように引数の文字列を書き換える必要はありません。→ではどうするのですか??全然わかってなくてすみません… main()内のprint_char(string);のあとにprintf("%s", string);をいれてみてください。 出力するだけのprint_char()が、stringの内容を書き換えている(変換したものを返している)のが確認できると思います。 →やってみます また明日やってみますのでよければ明日もお願いします 何度も回答ありがとうございます

  • wormhole
  • ベストアンサー率28% (1622/5659)
回答No.4

>でも思惑通りに動作してませんでした。 >大文字小文字のところはもう理解したので大丈夫ですが、ほかがまだなので詳しくかいていただけるとありがたいです。 あなたが思われている「ほか」とは何でしょうか? 私が思うとこの「ほか」をあげると動作結果とは直接関係のない とこまで及んでしまいますけど。 どういう事か、あえて1点あげるなら ・print_char()は「引数の文字列を変換して返す」 「引数の文字列を変換したものを出力」どちらが目的ですか? 関数名からするとprint_char()は後者の出力するのが目的だと思いますが、 実際のコードは引数の文字列そのものを加工してしまっているので、 前者と後者2つの目的を持つことになってしまってます。

kzmsreo
質問者

お礼

すみません 全然くわしくないので質問もうまくできません。。。 引数の文字列を変換して返す と 引数の文字列を変換したものを出力 の違いもよくわかりません。 結局同じ結果になるようなきがします・・・>< 具体的にどうちがってくるのでしょうか・・・; 違うのなら目的は後者だとおもいます。 プログラムをどうかきかえればうまくいくのでしょうか??><

  • not_ace
  • ベストアンサー率52% (35/67)
回答No.3

ビルド自体は通ると思うのですが・・・どうなんでしょう? プログラムが上に張られたものそのものならビルドは通りますが、 意図通りの動作はしないと思われます。 以下要修正点 大文字と小文字の大きさは逆です。 誤:*ptr += 'A'-'a' ; 正:*ptr += 'a'-'A' ; printf("%s",ptr); for文のなかでptrを直接書き換えているので文字列の末尾を printfが参照しようとします。 for文で回す前にptrの値を別の変数に保存するなりしましょう。

kzmsreo
質問者

お礼

ありがとうございます^^ 前半は理解しました。 for(i=0 ; i<NUMOFCHAR+1 ; i++){ if( *ptr>='A' && *ptr<='Z'){ *ptr += 'A'-'a' ; } ptr++ ; } printf("%s",ptr); } こうはんですが、ptr++で文字列の最後までいくからそれをプリントしてしまうということですよね。 ptr++がないとptrの最初の文字をさすことになりますよね?。 ということは、ptrを置き換えなくても最後のprintf("%s",ptr);を1つ上の中かっこ{}のなかにいれればいけますか? あと初歩的で申し訳ないのですが、このptrというのはデータ・アドレスでいうとアドレスをさしていますよね? なぜ最後のprintf("%s",ptr);はprintf("%s",*ptr);にならないのでしょうか?*ptrはデータなので配列のなかみを表示するとかんがえているのですが・・・

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.2

まずは、その「ビルドエラー」のメッセージを読むこと。 プロフェッショナルでも、そこから始めます。 質問するにしても、エラーメッセージがあるのと無いのとでは、回答する手間が段違いです。 もっとも、このプログラムを実際やってみたところ「ビルドエラー」にはなりません。 実行自体は正常に終わって、結果が期待通りでない、ということになりそうです。 実行時のエラーになる可能性はあります。 > *ptr += 'A'-'a' ; x+=y;は x = x+y ;です。なので *ptr = *ptr + ('A'-'a'); です。*ptr='A'だった場合、この計算がいくつになると思いますか?上の式から括弧をはずしてみましょう。 下から2行目 > printf("%s",ptr); このときにポインタptrがどこを指しているか、よく考えてください > printf("Modified string is <"); > print_char(string); > printf(">\n"); を printf("Modified string is <"); print_char(string); printf(">\n"); printf("Modified string(2) is <%s>". string); とすると、ヒントになるかもしれません

kzmsreo
質問者

お礼

ありがとうございます。 前半は理解しました。 でも、後半がいまいちよくわかりません。 教科書は何度もよんでるのですが、ポインタについてあまりつかみきれてないので・・・ ptrはアドレスを、*ptrはデータをさしているなど、どれがデータどれがアドレスかはわかるのですが・・・

関連するQ&A

  • C言語2次列配列

    2次元配列について、わからなくなってしまいました。 #include "print.h" void main(void) { int i = 0; printf("%s\n", mes[i][i]); } print.hの内容は下記です。 extern char *mes[100][256]; 上の宣言を別のファイルで、内容を書き込んでいます char *mes[100][256] = {"ABCDE","FGHIJ"}; mainのmes[i][i]を表示すると、"ABCDE"がでます。 しかし、mes[i+1][i]としても(NULL)と表示され、 "FGHIJ"が表示されませんでした。 試しに、mes[i][i+1]としたところ、"FGHIJ"が表示されました。 私の認識だと、mes[i+1][i]で"FGHIJ"が表示されるのが正しいと思います。私のソースではなぜ、表示されないのでしょうか。

  • C言語で文字列の出力の問題

    1行目に文字列aを出力し、2行目にaの各文字を2回づつ出力し、3行目にaの格文字の文字コードを出力する関数 void print_string(char a[]) を作成せよ。 この関数を print_string("abcd") で呼び出したときの出力は abcd aabbccdd 97 98 99 100 となる。 という問題なのですが、2行目と3行目をどうしたら文字列aの文字や文字コードを個別に出力できるのかわかりません。 1行目までしかできてないですが、次のが私の作ったプログラムです。 #include <stdio.h> void print_string(char a[]) { printf("%s\n",a); } int main (void) { print_string("abcd"); return(0); } よろしくお願いします。

  • C言語 ソートについて

    #include <stdbool.h> #include <stdio.h> void swap(char *a, char *b) { } bool is_at(char c) { } void justify(char line[], int n) { } int main(void) { char line[] = "a@b@@@c@@d@@@ef@@g"; size_t n = sizeof(line) - 1; justify(line, n); printf("%s\n", line); return 0; } 上の雛形を使って文字列lineに含まれる@以外の文字を文字列の前の方に詰めていくプログラミングを作るという問題を解いていたのですが下のプログラミングまでは出来たのですが最後のjustifyの部分がわかりません 良ければ解答をお願いします #include <stdbool.h> #include <stdio.h> void swap(char *a, char *b) { char temp = *a; *a = *b; *b = temp; } bool is_at(char c) { if(c == '@') { return true; } else { return false; } } void justify(char line[], int n) { for(int i=0;i<n-1;i++) { } } int main(void) { char line[] = "a@b@@@c@@d@@@ef@@g"; size_t n = sizeof(line) - 1; justify(line, n); printf("%s\n", line); return 0; }

  • プログラミングのポインタの所の課題で、途中までやったのですが・・・

    プログラミングのポインタの所の課題で、途中までやったのですが・・・ どうしてもとけません。どなたか解けるかた、ご指導お願いします。。。 課題は以下の通りです。 1.文字配列の先頭文字でソートを行って出力するプログラムを完成させよ。ただし、my_sort_stringsはポインタ配列とその要素数を引数として、登録されている文字配列を昇順に並べ替える関数である。 #include<stdio.h> #include<string.h> void print_strings(char **p, int n); void swap_strings(char **p, int i, int j); int min_index(); void my_sort_strings(); int main() { char*p[100]; char Orange[] = "orange"; char Apple[] = "apple"; char Peach[] = "peach"; char Grape[] = "grape"; char Melon[] = "melon"; int i; p[0] = Orange; p[1] = Apple; p[2] = Peach; p[3] = Grape; p[4] = Melon; print_strings(p, 5); my_sort_strings(); print_strings(p, 5); return 0; } void print_strings(char **s, int n) { int i; printf("-----------begin: print_string ----------\n"); printf("print_string: s's value: %08x\n", s); for(i = 0; i < n; i++) { printf("(s[%d])'s value: %08x\n", i, s[i]); printf("(s[%d])'s address: %08x\n", i, &s[i]); } for(i = 0; i < n; i++) printf("%d: %s\n, i, s[i]"); printf("-----------end: print_strings-----------\n"); } void swap_strings(char **p, int i, int j) { char *tmp; tmp = p[i]; p[i] = p[j]; p[j] = tmp; } int min_index(char **a, int n) { } void my_sort_strings( ) { } 2.課題1を元に文字配列の2文字目以降の順序まで考慮した辞書式順序でソートを行うプログラムを作成せよ。関数名はlexicographic_sortとする。

  • 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を用いずにプログラムする方法を教えてもらえませんか? もしくわ、用いずにプログラムすることは不可能ですか? 教えてください。 よろしくお願いします。

  • プログラミング(配列と関数の引数)

    a : ABCDE a : ABCDEFGH Len : 8 a : FGHIJ a : FGH a : FGH, c : FGH 上記のように表示されるプログラムを作りたいのですが、なかなかできません。下記のようなプログラムを作ったのですがどこが間違っているのかよくわかりません。分かる方、指摘をお願いします。 #include <stdio.h> void my_strcpy(char s[], char t[]); int my_strlen(char s[]); void my_strcat(char s[], char t[]); int main(){ char a[10]; char b[10] = "ABCDE"; char c[] = "FGH"; int len; my_strcpy(a, b); printf("a : %s\n", a); my_strcat(a, c); printf("a : %s\n", a); len = my_strlen(a); printf("Len : %d\n", len); my_strcpy(a, "FGHIJ"); printf("a : %s\n", a); a[3] = '\0'; printf("a : %s\n", a); if(strcmp(a, c) == 0){ printf("a : %s, c : %s\n", a, c); } int i, s, t; my_strcpy(a, b + 2); printf("a : %s\n", a); void my_strcpy(char s[], char t[]){ for (i = 0; t[i] != '\0'; i++){ s[i] = t[i]; } s[i] = '\0'; } int my_strlen(char s[]){ int i; for (i = 0; s[i] != '\0'; i++); return i; } void my_strcat(char s[], char t[]){ int i, j; for (i = 0; s[i] != '\0'; i++); for (j = 0; t[j] != '\0'; i++, j++){ s[i] = t[j]; } s[i] = '\0'; } }

  • C言語のソートについて

    C言語で下記のファイルの中身を昇順と降順で出力しようとしているのですが、ソートが上手くいっていない状況です。 どなたか修正点を教えて頂けないでしょうか? 「ファイルの中身」 2022/11/14 16:19:56 4+4,8.000000 2022/11/14 16:20:14 7+7,14.000000 2022/11/14 16:20:18 8+8,16.000000 2022/11/15 16:19:56 4+4,8.000000 2022/11/14 16:20:14 7+7,14.000000 2022/11/18 16:20:18 8+8,16.000000 2022/11/17 16:19:56 4+4,8.000000 2022/11/14 16:20:14 7+7,14.000000 2022/11/14 16:20:18 8+8,16.000000 「ソースコード」 #include <stdio.h> #include <string.h> #include <stdlib.h> int cmp_u(const void* a, const void* d) { return *(char*)a - *(char*)d; } int cmp_d(const void* a, const void* d) { return *(char*)d - *(char*)a; } int main() { int r,i,n; FILE* fp; char sin[9][1000]; fp = fopen("log.txt", "r"); if (fp == NULL) { printf("ファイルオープン失敗\n"); return -1; } for (i = 0; i < 9; i++) { fscanf(fp, "%s", &(sin[i])); } fclose(fp); printf("ASC or DESC: "); scanf(" %s", &ad); if (strcmp(ad, "ASC") == 0) { qsort(sin, 9, sizeof(char), cmp_u); } else { qsort(sin, 9, sizeof(char), cmp_d); } for (i = 0; i < 9; i++) { printf("%s\n", sin[i]); } return 0; }

  • c言語についてです。

    文字の順番を逆さまにするプログラムなのですが実行してenterキーを押しても何もおこりません。原因がわかる方がいたら教えてほしいです。 初歩的な質問ですみません。 使っているパソコンはMacBookProです。 #include<stdio.h> void reverse(char[],char[]); void divide(char[],char[]); int main(void) { char s[100],t[100]; gets(s); reverse(s,t); divide(t,s); printf("%s %s\n",s,t); return 0; } void reverse(char s[],char t[]) { int i=0,j=0; while(s[i]!=0){ i++; } i--; while(i>=0){ t[j]=s[i]; i--; j++; } t[j]=0; return ; } void divide(char t[],char s[]){ int i=0,j=0; while(t[j]!=' '){ i++; } t[i]=0; i++; while(t[i]!=0){ s[j]=t[i]; j++; i++; } s[j]=0; return ; }

  • c言語において、

    "キーボードから自分の名前と住所を半角英文字で大文字と小文字をランダムに続けて入力し、「自分の名前と住所」と「小文字が何文字あるかと、大文字が何文字あるか」をディスプレィに表示するプログラムを作成しなさい。” とした場合、どのように表示させればよいのでしょうか?ちなみに、 #include<stdio.h> void main(void) { char a[100]; int i=0; printf("自分の名前と住所を半角英小文字で大文字と小文字をランダムに続けて入力して下さい\n"); scanf("%s",a); while(a[i]!=0){ if(a[i]<65,90<a[i]<97,122<a[i]) printf("a[%d]=%c, ",i,a[i]); else if(64<a[i]<91) printf("a[%d]=%c,%c ",i,a[i],a[i]+32); else printf("a[%d]=%c,%c ",i,a[i],a[i]-32); if((i+1)%5==0) printf("\n"); ++i; } } では、うまくいきません。 具体例を書いていただけるとありがたいです。

  • プログラミング(関数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; }