みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

C言語の問題があと少しでわからないのですが

学校の課題に取り組んで分からないことろが出てきました。問題は以下のものです。

問題13
任意の文字列を(str)を入力して、削除文字を入力させ、strから削除文字を削除して表示しなさい。

出力例:str = abcd 削除文字:c →結果:abd


というものです。

途中まで自分で考え
-------------------------------------------------------------------------------------------------------------------

#include <stdio.h>

void rmv(char *str, char c);

int main(void) {

char str[80];
int c;

printf("文字列入力 : ");
fgets(str, 80, stdin);
printf("削除文字入力 : ");
c = getchar();

void rmv(str, (char)c);

printf("削除後文字列 : %s", str);

return 0;
}

void rmv(char *str, char c) {

while(*str) {

if(*str == c) {
while(*str) {
*str = *(str + 1);
++str;
}
}
++str;
}
*str = '\0';
}
---------------------------------------------------------------------------------------------------------

としましたが削除文字判定と文字つめのループ用に同じポインタを使っているので文字が一文字しか消えないと言われました。

解決方法にrmv関数内で別のポインタを用意し、if文内でコピー(例 p =str;)し次のwhile文内でこのポインタを用いて判定するというヒントを貰いましたが。自分で組んでいて上手く動きません。

どのように処理をしていけばいいでしょうか。

超初心者なので説明も付けていただくと有難いです。

投稿日時 - 2011-03-05 16:37:48

QNo.6570344

すぐに回答ほしいです

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

混乱するかも知れませんが、別の考え方を・・・。
この関数は、同一の領域に削除文字を作成する仕様ですが、

”これがもし、別の領域に文字列を作成(コピー)する”

という仕様だったら、どうしますか?
char* src <- 元の文字列のポインタ
char* dst <- 作成先のポインタ
char c <- 削除する文字

たぶん、
src から一文字読んで、cと一致しないなら、dst にその文字をいれる。
(c と一致した場合は、無視する)

というのを繰り返せばよいと思うのですが?
(”同一領域に作成”に仕様を変更することもこの場合は、容易です。)

投稿日時 - 2011-03-06 10:27:44

ANo.4

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(4)

ANo.3

>解決方法にrmv関数内で別のポインタを用意し、if文内でコピー(例 p =str;)し次のwhile文内でこのポインタを用いて判定するというヒントを貰いましたが。自分で組んでいて上手く動きません

削除文字:■
検索対象文字列:□□□■□□■□□
とします。

左から順番に1つずつ検索を行い、左から4番目の■を見つけた際に5番目以降の文字を1つずつ左に詰めております。
ただし、その詰める作業を行う際に
・何文字目まで検索していたかという情報を持っているポインタ(ここでは4番目まで)
を右に1つずつずらして利用しています。
そのため、文字を詰め終わった後に、上記のポインタは
□□□□□■□□
の一番右側を指しており、文字列が終わった!と判断され処理が終了してしまっています。

それを防ぐためには、文字を詰め終わった後に
・文字を詰める前に何番目まで検索していたか
という情報が必要になります。

つまり
1.検索対象が見つかったら、現在のポインタを他のポインタに入れておく
2.今まで通り文字を詰める
3.文字が詰め終わったら、1で情報を入れておいたポインタを使い、再度検索を開始する

という流れになると思います。

投稿日時 - 2011-03-06 05:41:59

>mv関数内で別のポインタを用意し、if文内でコピー(例 p =str;)し次のwhile文内でこのポインタを用いて判定するというヒントを貰いましたが。

これをそのまま、コーディングすればいいんじゃないですか?


void rmv(char *str, char c) {

 char *p2;  // 別のポインタを用意
 while(*str) {

  if(*str == c) {
   p2=str; // ポインタをコピーして
   while(*p2) { // このポインタを用いて判定する
    *p2 = *(p2 + 1); // もちろん、コピーもこのポインタを用いる。
    p2++;
   }
  }
  ++str; //そうすれば、以降の文字列の続きが判定できる。
 }
 *str = '\0';
}

投稿日時 - 2011-03-05 18:05:50

ANo.1

とりあえず、ヒントをもらって試行錯誤しているコードを書いて、何をしようとしてそう書いているのか説明していただけないでしょうか。

うまくいかないコードを他人に説明しているうちにどうすればいいか閃くのはけっこうよくあることですし、あなたがどこで詰まっているかが説明を聞けばよく分かります。

投稿日時 - 2011-03-05 17:20:36

あなたにオススメの質問