• ベストアンサー

プログラム(初心者)

文字列を入力し中に含まれる空白を削除した文字列を作るプログラムなのですが #include <stdio.h> #include <stdlib.h> int main(void){ char str[100]; int i,j,c; printf("文字列を入力してください\n"); gets(str); i=j=0; do{ c=str[i++]; if(c!= ' ') str[j++]=c; }while(c); printf("空白を削除した文字列は%sです\n",str); return EXIT_SUCCESS; } do文の所何やってるかさっぱりわかりません 教えてください

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

  • ベストアンサー
  • t4t
  • ベストアンサー率55% (47/84)
回答No.1

do{ c=str[i++]; // strから1文字取り出してcに入れる if(c!= ' ') // cが空白でなければ、 str[j++]=c; // strにcを入れる(空白をとばす) }while(c); // strが終わるまで繰り返す です。 もともとの文字列より空白を省いた文字列のほうが短いことを利用したプログラムですね。 str[i]が取り出す位置でstr[j]が文字を入れる位置です。jはiより小さいか、iと同じ値をとります。 " 1"(スペースと1)という文字列があったとき、(つまりstr[0]=' '、str[1]='1'、str[2]='\0') 初回のc=str[i++]で、cに空白が入り、iが一つ進み1になります。 ところがcは空白なので、str[j++]=c;は実行されません。jはそのままです。このときstr[0]=' '、str[1]='1'、str[2]='\0'のままです。 2回目のc=str[i++]で、cに'1'が入り、iが一つ進み2になります。。 cは空白ではないので、str[j++]=c;が実行されます。jはさっき加算されていませんから0のままです。 つまり、このときstr[0]='1'、str[1]='1'、str[2]='\0'となって、jが1に加算されます。 3回目のc=str[i++]で、cに'\0'が入り、iが一つ進みます。 cは空白ではないので、str[j++]=c;が実行されません。jはさっき加算されていますから1です。 つまり、このときstr[0]='1'、str[1]='\0'、str[2]='\0'となって、jが2に加算されます。 ここでcが'\0'つまり0なので、while(c)を抜けます。 その下のprintfの"%s"では、strの'\0'の直前までしか編集されませんから、表示される文字列はstr[0]の'1'のみになります。

minaraiH
質問者

お礼

わかりました。ありがとうございました。

その他の回答 (3)

  • php504
  • ベストアンサー率42% (926/2160)
回答No.4

文字列を "a b" とします str[ 0 ] : 'a' str[ 1 ] : ' ' str[ 2 ] : 'b' str[ 3 ] : 0 になりますね doループの最初は c = str[ 0 ]; // cにstr[ 0 ] ('a')が代入 i++されてi は 1 if ( c != ' ' ) // c('a')は' 'ではないので str[ 0 ] = c; // str[ 0 ] に c ('a')が代入 j++されてj は 1 2回目 c = str[ 1 ]; // cにstr[ 1 ] (' ')が代入 i++されてi は 2 if ( c != ' ' ) // c(' ')は' 'と一致 str[ j++ ] = c; // この行は実行されない j は 1 のまま 3回目 c = str[ 2 ]; // cにstr[ 2 ] ('b')が代入 i++されてi は 3 if ( c != ' ' ) // c('b')は' 'ではないので str[ 1 ] = c; // str[ 1 ] に c ('b')が代入 j++されてj は 2 4回目 c = str[ 3 ]; // cにstr[ 3 ] (0)が代入 i++されてi は 4 if ( c != ' ' ) // c(0)は' 'ではないので str[ 2 ] = c; // str[ 2 ] に c (0)が代入 j++されてj は 3 c が 0 なのでdoループ終了 結果 str[ 0 ] : 'a' str[ 1 ] : 'b' str[ 2 ] : 0 で空白が削除されました

minaraiH
質問者

お礼

わかりました。ありがとうございました。

  • kouji_124
  • ベストアンサー率46% (283/605)
回答No.3

do文が何をやっているかわからないって、答えはご自分で書かれていますよね。 >文字列を入力し中に含まれる空白を削除した文字列を作るプログラム そうです。 doの部分で空白を削除しています。 細かく説明すれば。 >i=j=0; 整数変数の初期化 >do{ ループの開始 >c=str[i++]; 文字列変数「str」の先頭から「i番目」の1文字抽出 >if(c!= ' ') >str[j++]=c; 空白であるか判定 空白だった場合は、文字列変数「str」の「j番目」に書き戻し >}while(c); 文字列変数「str」の先頭から「i番目」の文字がNULL(0x00h)だった場合ループ終了

minaraiH
質問者

お礼

わかりました。ありがとうございました。

回答No.2

落ち着いて分解してみましょう。 c=str[i++]; ↓ c=str[i]; i++; do{  c=str[i];  i++;  if(c!= ' ')  {   str[j]=c;   j++;  } }while(c); if 分の } のあとに printf で str、i、j を表示すると分かりやすいですよ。 動作は単純で、スペースがでなければ次の文字を入れていくものです。

minaraiH
質問者

お礼

わかりました。ありがとうございました。

関連するQ&A

  • どこがちがうのでしょうか?

    以下の二つのプログラムはユーザーが文字を入力し、80文字以下なら ピリオドを追加して表示するというものです。上はうまくいきますが、下はうまくいきません。なぜでしょうか? #include<string.h> #include<stdlib.h> int main() { char str[80]; int i; printf("文字列を入力してください。\n"); gets(str); if(strlen(str)<80) { for(i=strlen(str);i<79;i++) strcat(str,"."); } printf("%s",str); } #include<stdio.h> #include<string.h> #include<stdlib.h> int main() { char str[80]; int i; printf("文字列を入力してください。\n"); gets(str); if(strlen(str)<80) { for(i=strlen(str)+1;i<79;i++) str[i] = "."; } printf("%s",str); }

  • プログラムの添削

    以下のようなプログラムを作りました.よりよい書き方,アドバイスなどお願いします. /*文字列の入力を繰り返し受け取るプログラムを作成しなさい.*/ #include<stdio.h> #include<string.h> int main(void) { char bigstr[101],str[31]; printf("文字列の入力を繰り返し受け取るプログラムです.\n"); strcpy(str,""); strcpy(bigstr,""); for(;;) { printf("文字列を入力してください.\n"); gets(str); if(strlen(str)>30) { printf("入力できる文字数の上限(20字)を超えました.\n"); return 0; } else if(strcmp(str,"quit")) { strcat(bigstr,str); if(strlen(bigstr)>100) { printf("入力できる文字数の上限(合計100字)を超えました.\n"); return 0; } } else break; } printf("%s\n",bigstr); return 0; }

  • プログラムのことで

    次のプログラムの変数の説明と処理の流れを素人でも理解できるように説明してもらえないでしょうか。 #include <stdio.h> #define MAX 128 int str_comp(char nx[], char ny[]){ int i, j, k=0; for(i=0; i<=MAX; i++){ if( nx[i]=='\0' ){ return 0; } else if( nx[i]==ny[0] ){ for( j=0; nx[i]==ny[j]; j++ ){ i++; } if( ny[j]=='\0' ){ return 1; } } } } int main(void) { char namex[MAX}; char namey[MAX}; int n; int i; printf("文字列x(64文字まで)? "); scanf("%s",namex); printf("文字列y(64文字まで)? "); scanf("%s",namey); n=str_comp(namex,namey); if(n==1){ printf("'%s'に'%s'は含まれます\n",namex,namey); } else if(n==0){ printf("'%s'に'%s'は含まれません\n",namex,namey); } return 0; } 実効結果 文字列x(64文字まで)? Katatsumuri  文字列y(64文字まで)? ta 'Katatsumuri'に'ta'は含まれます. エラーは出ないはずです。 よろしくお願いします。

  • 結果が不安定なプログラム

    配列に入れられた文字列を、別の配列に逆にして入れ、表示するというプログラムを作っています。 #include<stdio.h> #include<string.h> #include<stdlib.h> void main() {   char str1[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ", str2[] = "";   int i = 0, len = strlen(str1);   char *p1 = str1 + len - 1, *p2 = str2;   while(*(p1 - i) != str1[0] - 1) *(p2 + i) = *(p1 - i++);   printf("str1 = %s\n",p1 = str1);   printf("str2 = %s\n",p2); } 実行結果: str1 = ABCDEFGHIJKLMNOPQRSTUVWXYZ str2 = ZYXWVUTSRQPONMLKJIHGFEDCBA と出るのですが、この文字列を例えば"TANGOHYOJI"とかに変えてみると、実行は出来るんですがprintfの部分が表示されません。 また表示できても、文字が違う文字になって表示されたりします。 あと、この場合に使われている<stdlib.h>はどういった役割を果たしているのでしょうか?これがないとこのプログラムは動かなかったのですが・・。 どうかよろしくお願いします。

  • C言語プログラミング 初心者

    現在2つの文字列を比較するstrcmp()関数と同じ動作をするプログラムを制作しています。 もちろん、strcmp()は一切用いません。 何とか作ってみたものの、文字列が等しいときなどにはうまく作動しません。 分かる方アドバイスお願いします。 以下のプログラムでは2つの50文字以下の文字列を入力することを想定しています。 #include<stdio.h> int main(void) { char str1[50],str2[50]; int a,b,i; printf("第1の文字列を入力してください: "); gets(str1); printf("第2の文字列を入力してください: "); gets(str2); /*文字列の長さを確認します*/ for(a = 0;str[a];a++) ; for(b = 0;str2[b];b++) ; printf("%s ha %d mozinonagasadesu\n",str1,a); printf("%s ha %d mozinonagasadesu\n",str2,b); /*文字列を比較します*/ for(i = 0;;i++){ if(str1[i] > str2[i]) printf("%s は %s より大きい\n"str1,str2); else if(str1[i] < str2[i]) printf("%s は %s より小さい\n"str1,str2); if(str1[i] > str2[i] || str1[i] <str2[i]) break; } for(i=0;str1[i] && str2[i];i++) if(str1[i] == str2[i] ) printf("文字列は等しい\n"); /*上のプログラミングだとstr1がaab、str2がaacのときも文字列が等しいと表示してしまうので、ぴったり等しいときのみ表示するにはどのように条件付けしたらよいでしょうか?*/ return 0; } ちなみにstr1[0]=a ,str1[1]=b, str2[0]=a, str[1]=b, str[2]=cが格納されていた場合、str1 < str2になると思うのですが正しいでしょうか? もし正しければこの場合str1[2]にはヌル文字が入っており、それがstr2[2]のcと比較されたためなのでしょうか? いろいろと質問してしまいましたが、分かる方解答お願いします。

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

  • 初心者です。教えてください、お願いします。

    「キーボードから2つの文字を入力し、それぞれ変数h,iに格納する。変数h,iをh,iの順、i,hの順に表示するプログラムを作成せよ。」という課題なのですがうまくできません。どこが間違っているか教えてもらえないでしょうか? #include<stdio.h> int main(void) { char h,i; printf("1つ目の文字を入力してください。\n"); scanf("%c",&h); printf("2つ目の文字を入力してください。\n"); scanf("%c",&i); printf("%c %c\n",h,i); printf("%c %c\n",i,h); return 0; } 実行結果が1文字めを入力すると2文字目の入力にならずに終了してしまいます。 ***実行結果*** 1つ目の文字を入力してください。 a 2つ目の文字を入力してください。 a a ********** おねがいします。

  • 作ったプログラミングC何だけど、評価していただけませんが?不足があれば、教えてください!

    文字列「abc」の各アルファベットを1文字ずらすと文字列「bcd 」になり、 文字列「nisidate」の各アルファベットを2文字ずらすと文字 列「pkukfcvg」となる。さらに、 文字列「kibishii」の各アルファベットを2文字ずらすと文字 列「mkdkujkk」となる。 このような、任意の文字列の各要素を任意の文字数ずらすプロ グラムを作成する、なお、zを1文字ずらしたとき のアルファベットはaとする。 #include <stdio.h> #include <string.h> int main(void) { char str[27]="abcdefghijklmnopqrstuvwxyz",str1[50], str2[50]; int x,i,j,len; printf("文字列を入力---> "); scanf("%s", str1); printf("何文字ずらすかを入力---> "); scanf("%d",&x); len=strlen(str1); for(i=0;i<len;i++) { for(j=0;j<27;j++) { if(str1[i]=='z') { str2[i]=str[x-1]; } if(!(str1[i]=='z')) { if(str1[i]==str[j]) { str2[i]=str[j+x]; } } } } printf("%d文字ずらした文字列は%sです\n", x, str2); return 0; } よろしくお願いします!!

  • C言語 文字列の操作

    文字Cが含まれる個数を求めたいです #include <stdio.h> int str_chnum(const char str[],int c) { int i; int count=0; for(i=0;str[i]!="\0";i++) if (str[i]==c) count++; return(count); } int main(void) { char st[100]; printf("検索文字列を入力してください:"); scanf("%s",st) ; printf("検索文字列数は%uです。\n",st,int str_chnum(const str[],int c)); return(0); } コンパイルできません。なぜですか?printfの行がたぶん間違っていると思うんですが。。。

  • 文字列で表現された時刻の変形

    文字列で表現された時刻の変形 13:23:23のような時刻を秒単位で表したいと思っています。そこで以下のように #include <stdio.h> int main() { char str[9]; int i; int j; scanf("%s",str); for(i=0;i<9;i++) printf("%c\n",str[i]); return 0; } 時刻を文字列の配列に置き換えることまでは考えつきましたが、この先に進めません。 どうしたらよいでしょうか?なお特別なライブラリなどは使用はできません。 よろしくお願い致します。

専門家に質問してみよう