質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

4回答

13131閲覧

文字列中任意の文字を削除

ShunyaKogure

総合スコア7

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2017/01/07 04:49

C言語を使って入力された文字列の中から数字のみを削除する、というプログラムを書こうとしてるのですが、数字が連続するとちゃんと動きません。どのように直せば良いのでしょうか?

C

1#include <stdio.h> 2 3int del_digit(char s[]) { 4 int j, i = 0; 5 int flag = 0; 6 7 while (s[i]) { 8 if (s[i] - '0' < 10) { 9 if (s[i+1] - '0' < 10) flag = 1; 10 do { 11 j = i; 12 while (s[j]) { 13 s[j] = s[j+1]; 14 j++; 15 } 16 if ((s[i+1] - '0' > 10) && (s[i] - '0' > 10)) flag = 0; 17 } while(flag == 1); 18 } 19 i++; 20 } 21 return 0; 22} 23 24int main (void) { 25 char w[50]; 26 int j; 27 28 printf("文字列を入力してください"); 29 scanf("%s", w); 30 31 del_digit(w); 32 33 printf("%s\n", w); 34 return 0; 35}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

ベストアンサー

どういう手順(ロジック)で処理しようとしているか、考えを整理してみましょう
恐らくやりたいこと以上に難しく考えているのではないでしょうか

コードからは
・文字列の先頭から順に文字の終わりが出るまで処理を繰り返す
・判定文字が数字だったら、次の文字が数字であるかも判定する
・文字を前に詰める(実質的な文字削除)
・次の文字も数字だったらもう一度前に詰める
・今回判定位置の文字と次の文字のどちらも数字以外であれば、さらに次の文字の処理へ進む
ということをしようとしているように読み取れます
・・・
なんだか少しややこしいうえに、1文字だけだったり、数字だけだったりの場合など
いろいろうまくいかないケースがありそうです

やりたいことは
・入力文字列から数字を抜き出した文字列を出力する
ですね

シンプルに手順を考えてみましょう

・文字列の先頭から順に文字の終わりが出るまで処理を繰り返す
・処理対象文字が数字だったら、次文字から後ろの文字を1つずつ前に詰める

なんだか、これだけでうまくいきそうですね

コードを見てみましょう

c

1while (s[i]) { 2 if (s[i] - '0' < 10) { // ←数字かどうかを判定(1) 3 if (s[i+1] - '0' < 10) flag = 1; //←次の文字が数字かどうかを判定(2) 4 do { 5 j = i; 6 while (s[j]) {; //←前詰処理(実質的に数字を削除)(3) 7 s[j] = s[j+1]; 8 j++; 9 } 10 if ((s[i+1] - '0' > 10) && (s[i] - '0' > 10)) flag = 0; //←次の文字と今回文字が数字以外なら前詰処理を抜ける(4) 11 } while(flag == 1); 12 } 13 i++; 14} 15

(1) と (3) は必要な処理ですが、(2) と (4) はいかがでしょう?本当に必要でしょうか?

外してみるとこんな感じになります

c

1while (s[i]) { 2 if (s[i] - '0' < 10) { // ←数字かどうかを判定(1) 3 j = i; 4 while (s[j]) {; //←前詰処理(実質的に数字を削除)(3) 5 s[j] = s[j+1]; 6 j++; 7 } 8 } 9 else{ //←前詰後は i の位置に入った次の文字を数字かどうか判定したいので i++ しないための else 10 i++; 11 } 12} 13

いかがでしょうか

なお、もっと効率的でスマートなやり方については他の方の回答が大変参考になります
それぞれにどのような考え方で処理しているか読み解くと勉強になると思います

以上ご参考まで

投稿2017/01/07 07:17

takito

総合スコア3111

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

c

1//#include <ctype.h>を要する 2void del_digit(char s[]) 3{ 4 int si, pi, len = strlen(s); 5 char* p = (char*)malloc(sizeof(char) * (1 + len) ); 6 7 for(si = pi = 0; si < len; si++){ 8 if(!isdigit(s[si]) ){ 9 p[pi++] = s[si]; 10 } 11 } 12 p[pi] = '\0'; 13 strcpy(s, p); 14 free(p); 15}

私ならこう作ります。動作未確認

投稿2017/01/07 05:36

編集2017/01/07 05:39
HogeAnimalLover

総合スコア4830

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

c

1void del_digit(char *s) { 2 char c; 3 char *p = s; 4 5 while ((c = *s++)) 6 if (c < '0' || '9' < c) 7 *p++ = c; 8 *p = '\0'; 9} 10

動きに若干の無駄がある。

投稿2017/01/07 07:04

ikedas

総合スコア4333

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

数字を削除するのであれば、(ご指摘を受け、jの初期化を入れました、ありがとうございます)

c

1#include <stdio.h> 2 3char *del_digit(char s[]) { 4 int i,j; 5 for (i=j=0; s[i]; i++) { 6 if (s[i] - '0' >= 10) { 7 s[j]=s[i]; 8 j++; 9 } 10 } 11 s[j]=s[i]; 12 return s; 13} 14 15int main (void) { 16 char w[50]; 17 18 printf("文字列を入力してください\n"); 19 scanf("%s", w); 20 21 printf("%s\n", del_digit(w)); 22 return 0; 23}

投稿2017/01/07 07:02

編集2017/01/08 03:07
A.Ichi

総合スコア4070

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ikedas

2017/01/07 07:36

jを初期化していないようです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問