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

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

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

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

Q&A

解決済

3回答

280閲覧

数字文字の扱い方について

kamecha

総合スコア41

C

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

0グッド

0クリップ

投稿2017/12/27 15:17

###前提
書籍で勉強している学生です。
書籍の解答がないため問題のヒントや解説をしていただけると嬉しいです。

###問題
文字列s内のすべての数字文字を削除する関数を作成せよ。

lang

1void del_digit (char s[]) {/* ... */}

例えば、"AB1C9"を受け取ったら、"ABC"に更新する。

###該当のソースコード

lang

1#include <stdio.h> 2#include <ctype.h> 3 4#define NUMBER 100 //要素数の最大値 5 6void del_digit (char s[]) 7{ 8 int i = 0; 9 int OS[NUMBER]; //大文字に変換 10 int KS[NUMBER];  //小文字に変換 11 while(s[i]){ 12 OS[i] = toupper(s[i]); 13 KS[i] = tolower(s[i]); 14 15 if(OS[i] == KS[i]){ 16 s[i] = '\0'; 17 } 18 i++; 19 } 20} 21

###疑問点
削除すると言うことで'\0'を代入したのですが、
実行してみると、"AB1C9"が"AB"となっていました。
これは、削除と言うのでしょうか。
このままだと、文字列とは言えない気がします。

また、よりよい数字文字の判定方法があると思うので教えていただきたいです。

###補足情報
書籍: 新明解C言語 入門編
演習 9-10

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

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

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

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

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

guest

回答3

0

削除するためには、それ以降の文字を全部1つずつ前に詰める(移動させる)必要があります。
s[i] = s[i+1];

また、数字かどうかの判断は、isdigit()を使います。

投稿2017/12/27 15:37

otn

総合スコア84423

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

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

kamecha

2017/12/27 22:33

なるほど、'\0'を代入するのではないのですね。 ところで、isdigit()とは、何ですか? 自作の関数なのですか?
otn

2017/12/27 23:55

日本語本家のマニュアルはここです。 https://linuxjm.osdn.jp/html/LDP_man-pages/man3/isdigit.3.html まあ、関数だと思って使えばいいです。 引数のintがASCII数字なら、非ゼロ(多くの場合1ではない)を返し、そうでなければ0を返します。 if(ch>='0'&&ch<='9')のような比較をするのじゃなくて、文字コードを添え字とする表を引いてチェックします。
kamecha

2017/12/28 13:01

有り難うございます。 isdigitを用いて、実装していきたいと思います。 使用しない場合は、 if(ch >= '0' && ch <= '9' )とすれば良いのですね。 ちなみに、自分が行っていた大文字と小文字を区別する方法は、一般的に行われないのでしょうか。
kamecha

2017/12/28 14:13

今思えば、!や?などの記号は、大文字小文字の区別がないのでこの方法は、使えませんね。
otn

2017/12/28 14:22

そうですね。「数字を削除」じゃなくて「英字以外を削除」になってしまっています。
guest

0

ベストアンサー

削除すると言うことで'\0'を代入したのですが、
実行してみると、"AB1C9"が"AB"となっていました。

文字列の最後には '\0' がある(ヌル文字で終端する、などとも言う)事を思い出してください。例えば、"AB1C9" という文字列は、メモリ上では
'A' 'B' '1' 'C' '9' '\0'

となっています(この文字列の長さは5ですが、'\0' を含めて6文字分・6バイトのメモリを使っていることにも注意)。
そして、'1' の場所に '\0' を代入するとこうなります。
'A' 'B' '\0' 'C' '9' '\0'

'\0' を代入したので、そこで文字列が終わってしまいました、だから "AB" となったのです。

"AB1C9"を受け取ったら、"ABC"に更新する

この場合は 'A' 'B' 'C' '\0' という文字列を作ることが目的です。

手順のひとつは(otnさんの回答のように)数字以降の文字を前に詰める(移動する・コピーする)事です。工夫してください。
もうひとつの手順は、元の文字列はそのままにしておき、結果を格納する文字配列を新たに用意して、そこに一文字ずつコピーしていくことです。勿論、目的の文字列になるように、数字はコピーしない。
どちらもそんなに大きな違いではないので、両方試してみたら良いと思います。いずれにしても(数字以外の)文字をコピーせずには題意を実現できません

お示しになったコードを拝見しました。数字は toupper() しても tolower() しても変化しないから、というアイディアは私に新鮮な気持ちを呼び覚ましてくれました。でも配列を2つも用意する必要はありません。メモリの無駄遣いです。なぜなら、今見ている一文字だけに注目すれば十分だから。貴方のアイディアを活かすなら

int om; //大文字に変換 int km; //小文字に変換 while (s[i]) { om = toupper(s[i]); km = tolower(s[i]); if (om == km) { /* s[i]は数字(とは限らないことに注意) */

で済みます。でもここは、otnさんの回答通り、isdigit()で数字か否かを判断することをお勧めします。omもkmも不要にできます。

投稿2017/12/27 23:59

rubato6809

総合スコア1380

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

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

kamecha

2017/12/28 13:33

自分の考えた方法にも改良すれば、より効率的になることに驚きました。 文字のコピー ← 覚えておきます!
guest

0

'\0'は文字列の終端を表すので、それだと途中で切れちゃいます。
後続する文字で空席を埋めるよなコード書かんといけません。

C

1#include <stdio.h> 2#include <ctype.h> 3 4void del_digit (char s[]) { 5 int in_inx; /* input index */ 6 int out_inx = 0; /* output index */ 7 8 for ( in_inx = 0; s[in_inx] != '\0'; ++in_inx ) { 9 /* 数字じゃなかったら書き込む */ 10 if ( !isdigit(s[in_inx]) ) { 11 s[out_inx++] = s[in_inx]; 12 } 13 } 14 s[out_inx] = '\0'; /* 文字列を終端する */ 15} 16 17 18int main() { 19 char str[] = "AB1C9"; 20 del_digit(str); 21 puts(str); 22 return 0; 23}

投稿2017/12/27 22:42

episteme

総合スコア16614

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

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

kamecha

2017/12/28 13:35

文字列を新たな配列にコピーすると言う方法ですね。 確認用のコードまで有り難うございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問