質問: 1); } i++; } return 0; } int main (void) { char w[50]; int j; printf("文字列を入力してください"); scanf("%s", w); del_digit(w); printf("%s\n", w); return 0; } ```
回答: どういう手順(ロジック)で処理しようとしているか、考えを整理してみましょう 恐らくやりたいこと以上に難しく考えているのではないでしょうか コードからは ・文字列の先頭から順に文字の終わりが出るまで処理を繰り返す ・判定文字が数字だったら、次の文字が数字であるかも判定する ・文字を前に詰める(実質的な文字削除) ・次の文字も数字だったらもう一度前に詰める ・今回判定位置の文字と次の文字のどちらも数字以外であれば、さらに次の文字の処理へ進む ということをしようとしているように読み取れます ・・・ なんだか少しややこしいうえに、1文字だけだったり、数字だけだったりの場合など いろいろうまくいかないケースがありそうです やりたいことは ・入力文字列から数字を抜き出した文字列を出力する ですね シンプルに手順を考えてみましょう ・文字列の先頭から順に文字の終わりが出るまで処理を繰り返す ・処理対象文字が数字だったら、次文字から後ろの文字を1つずつ前に詰める なんだか、これだけでうまくいきそうですね コードを見てみましょう ``` while (s[i]) { if (s[i] - '0' < 10) { // ←数字かどうかを判定(1) if (s[i+1] - '0' < 10) flag = 1; //←次の文字が数字かどうかを判定(2) do { j = i; while (s[j]) {; //←前詰処理(実質的に数字を削除)(3) s[j] = s[j+1]; j++; } if ((s[i+1] - '0' > 10) && (s[i] - '0' > 10)) flag = 0; //←次の文字と今回文字が数字以外なら前詰処理を抜ける(4) } while(flag == 1); } i++; } ``` (1) と (3) は必要な処理ですが、(2) と (4) はいかがでしょう?本当に必要でしょうか? 外してみるとこんな感じになります ``` while (s[i]) { if (s[i] - '0' < 10) { // ←数字かどうかを判定(1) j = i; while (s[j]) {; //←前詰処理(実質的に数字を削除)(3) s[j] = s[j+1]; j++; } } else{ //←前詰後は i の位置に入った次の文字を数字かどうか判定したいので i++ しないための else i++; } } ``` いかがでしょうか なお、もっと効率的でスマートなやり方については他の方の回答が大変参考になります それぞれにどのような考え方で処理しているか読み解くと勉強になると思います 以上ご参考まで