• ベストアンサー

ポインタを用いた文字列操作について…。

C初心者です。 「ある文字列を読み込んだ後、その文字列中にある文字(複数)を指定する。指定した文字を最初の文字列から消す」という関数を作りたいのですが、うまくいきません。 例を挙げると、 文字列 :OshieteGoo 指定文字:to 文字列改:OshitG のような感じにしたいです。 #define NULLC '\0' void strCpy(char *ptr1, char *ptr2, char *cMain) { char *cSub = cMain; /* ポインタバックアップ */ for(;*ptr1!=NULLC;ptr1++){ for(cSub=cMain;*cSub!=NULLC;*cSub++){ if(*ptr1!=*cSub){ *ptr2 = *ptr1; ptr2++; } break; } } *ptr2 = NULLC; return; } 自分なりにこう考えてみたのですが、これを実行すると 文字列 :OshieteGoo 指定文字:to 文字列改:OshitGoo となり、指定文字の2文字目以降がうまく削除できません…。 この問題を解決できるお知恵を拝借させて頂けると幸いです^^;

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

  • ベストアンサー
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.1

> 文字列 :OshieteGoo > 指定文字:to > 文字列改:OshitG んと、この場合 't' と 'o' を消したいのではないですか? なぜ文字列改のほうに 't' が残っていて、'e' が消えているのでしょうか? でまあそれはそれとして、 ptr2 がどういう変化をしているか追いかけてみては? char *src = ptr1; char *dst = cMain; char *delete; for (; *src; src++) { for (delete = ptr2; *delete; delete++) { if (*delete == *src) break; } if (!*delete) *dst++ = *src; } *dst = NULLC;

num_ruke
質問者

お礼

>なぜ文字列改のほうに 't' が残っていて、'e' が消えているのでしょうか? すいません、間違えました。ゴメンナサイ…。 >ptr2 がどういう変化をしているか追いかけてみては? そうですよね。2文字目以降ですもんね。。 もう一度考えてみます。ありがとうございました。

その他の回答 (2)

回答No.3

#include <stdio.h> #include <string.h> void delchars(char *str1, const char *str2, const char *chars) { while(*str1 = *str2){ str1 += (strchr(chars, *str2) == NULL); str2 ++; } } int main(void) { char str1[32]; char *str2 = "OshieteGoo"; char *chars = "to"; puts(str2); puts(chars); delchars(str1, str2, chars); puts(str1); return 0; }

num_ruke
質問者

お礼

回答ありがとうございます! 参考にさせて頂いてもっと精進します;;

  • koko_u_
  • ベストアンサー率18% (459/2509)
回答No.2

まずは関数名と、引き数の名前を「わかる名前」に変更して下さい。 次に元の文字列(例では OshieteGoo)と指定文字列(例では to)は関数によって変更されないので const を付けて下さい。 雰囲気こんなん void strCutCopy(const char* source, char* dest, const char* cut); ある文字が文字列に現われるかどうかは、strchr() などを利用するのがてっとり早いでしょう。

num_ruke
質問者

お礼

>const,strchr() こんなのがあったんですか。。 勉強不足を痛感します;; ありがとうございました!!

関連するQ&A

  • charのポインタについて

    同じような質問ばっかりたて続けにしてしまってすみません・・ あの,以下のような例の時↓ ------ { char array[7]; char *ptr; strcpy(array, "abcdef"); ptr = &(array[0]); printf(" array = %s\n ptr = %s\n", array, ptr); } ------ これを実行したら、 array = abcdef ptr = abcdef となりますが、ポインタとして宣言してるptrから文字列を得たい時は *ptr と書くんではないのでしょうか? %s のように出力形式のところを指定をするだけで 文字列で表示してくれるのはなぜですか? 上の例のように書くのが正しいのでしょうか

  • 文字列の受け渡し

    先ほど質問したものですが、お願いします。 関数で戻り値として、文字列を扱う場合、 char* sendstr(void){ char* mychar="HELLO!!\n"; return mychar; } ならうまくいきますが、 char* sendstr(void){ char mychar[]="HELLO!!\n"; return mychar; } だと、うまくいきません。 配列の場合、mycharで、ポインタと なると、思うのですが。 後者の方が、分かりやすそうですが、 だめなのでしょうか。 (char*は文字型のポインタで、文字列 へのポインタになるのでしょうか)。

  • 二次元文字列をポインタで操作するには

    お世話になります、フジと申します。今回皆様にお聞きしたいことは、かなり基本的な部分なのですがどうしても理解できず質問させて頂きます。 まず以下のようなプログラムを作成しました。 char *data[10]; void func(char* d) { static int i=0; data[i] = d; i++; } int main(void) { int i = 0; char a[10]; while(1){ if(i>2)break; if(i==0) strcpy(a,"Hello"); if(i==1) strcpy(a,"Morning"); if(i==2) strcpy(a,"Night"); func(a); i++; } i = 0; while(1){ if(i>2)break; printf("data is %s\n",data[i]); i++; } return 0; } すると出力されるdata[]の値は全て"Night"になります。これはポインタを使っているから当たり前だと思います。 これをどうにしかして上のようにポインタを用いて, data is Hello data is Morning data is Evening と出力させることが出来ないでしょうか? 大変基本的な部分とは思いますが、宜しくお願い致します。

  • ポインタについて

    #include<stdio.h> int main(void) { char str[10]; char *ptr = str; printf("文字列を入力してください。\n"); scanf("%s",ptr); printf("文字列は%sです。",str); return 0; } 上記のプログラムのscanf("%s",ptr);の ptrに&をつけるとなぜ先頭の4文字は入力しても 表示されなくなってしまうのでしょうか? よろしくお願いします。

  • 文字列ポインタの配列の扱い方

    毎度お世話になります。 構造体のメンバが、文字列ポインタの配列だった場合、それに文字列をコピーすることは可能なのでしょうか? とりあえず下記のように書いてみたのですが、実行エラーで終了してしまいます。 typedef struct data{ char name[30]; int age; char *ss[2]; }DATA; int main() { DATA dt[3] = {{"AA",10}, //ssも初期化出来るのか? {"BB",15}, {"CC",20}}; int i,j; for(i=0;i<3;i++){ for(j=0;j<2;j++) strcpy(dt[i].ss[j],"なし"); //それとも、ここでstrcpyで文字列を入れるのか? } よろしくお願いします。

  • C言語 文字列操作

    トリム関数とリムーブ関数を作成してみました。改良点はありますでしょうか? ~~~~以下ソース~~~~ #include <stdio.h> #include <stdlib.h> #include <string.h> char *Trim(char *str); char *Remove(char *str, char *rmv); void main(void) {  char str[10], rmv[10], *p;  int c;  /* " abcd "をトリムする */  strcpy(str, " abcd ");  printf("トリム前 |%s|\n", str);  p = Trim(str);  printf("トリム後 |%s|\n", str);  /* 指定文字列を削除する */  printf("削除する文字列を入力してください :");  scanf("%s", rmv);  Remove(str, rmv);  printf("削除後 |%s|\n", str);  exit(0); } char *Trim(char *str) {  char space[] = " ";  char null[] = "";  int index = 0;  while(1){   if(strcmp(&(str[index]), null) == 0){    index--;    if(strncmp(&(str[index]), space, 1) == 0){     strcpy(&(str[index]), &(str[index]) + 1);    }else{     break;    }   }else{    if(strncmp(&(str[index]), space, 1) == 0 && index == 0){     strcpy(&(str[index]), &(str[index]) + 1);    }else{     index++;    }   }  }  return str; } char *Remove(char *str, char *rmv) {  int c, size, i;  char *p;  c = '\0';  p = strchr(rmv, c);  size = p - rmv;  for(i = 0; i < size; i++){   c = (int)rmv[i];   p = strchr(str, c);   if (p != NULL) {    strcpy(&(str[p-str]), p + 1);   }   else{    printf("""%c""は見つかりませんでした\n", c);   }  }  return str; }

  • 文字列内の数字削除

    C言語の質問です。文字列str中の数字文字を削除する関数をポインタを使って作りたいのですが、どう作ったらいいかわかりません。方向性だけでも教えてくれませんか。 ちなみにヒントとして以下の部分は与えられてました。よろしくお願いします。 void del_digit(char *str) { char *ptr = str; while(*str){

  • 文字列の連結するプログラム

    独学でプログラミングをやっているんですが2つ文字列を1つにする方法がよくわかりません。(1)のプログラムは(b+3)のところは文字の長さを指定しているからだめで(2)はstrcpyやstrcatなどのコマンドを使わずにやるそうです。While分とかでやるんでしょうか?教えてください。 (1) #include <stdio.h> int main (void){ char spelA[] = "abc"; char spelB[] = "def"; char spelC[20]; int a,b; spel[6]=0; for(a=0;spel[a]!=0;a++){ spelC[i] = spelA[i]; }; for(b=0;spelB[b]!=0;b++){ spelC[b+3] = spelB[b]; }; printf("%s\n",spelC); return(0); }; (2) #include <stdio.h> #include <string.h> int main (void){ char spelA[] = "abc"; char spelB[] = "def"; char spelC[20]; strcpy(spelC,spelA); strcat(spelC,spelB); printf("%s\n",spelC); return(0); }

  • ポインタ演算がうまくできません

    以下のソースを実行すると、直値でアドレスをしていするのは うまくアセンブラに展開され、意図するアドレスを取り出す ことが出来るのですが、変数でアドレス演算させると意図する アドレスが取得できません。  何か記述がおかしいのでしょうか? ご存知の方宜しくお願い致します。 char const test_tbl[] = { -3, -2, -1, 0, 1, 2, 3, 4, 5}; unsigned char *ptr; unsigned char work; #define STA_OFFSET (&test_tbl[3]) void main( void) { // 適切なポインタが取得できる ptr = (STA_OFFSET + 3); // ポインタが取得できない。 work = 3 ptr = (STA_OFFSET + work); }

  • ポインタ配列の動的確保

    ポインタの配列の動的確保について教えてください。 入力した数値をポインタ配列に入れるプログラムです。 下記のように書いてみました。(見づらくてごめんなさい) #include<stdio.h> #include<stdlib.h> #define kensu 3 main() { char abc[kensu+1]={'A','B','C','\0'}; char *ptr[kensu]; int i; printf("3つの整数を入力して下さい。\n"); for(i=0;i<kensu;i++){ ptr[i]=(char*)malloc(sizeof(char)*10); if(ptr[i]==NULL){ printf("メモリの取得に失敗しました"); exit(1); } printf("整数%c:",abc[i]); fgets(ptr[i],10,stdin); if(ptr[i][strlen(ptr[i])-1]=='\n') ptr[i][strlen(ptr[i])-1]='\0'; } for(i=0;i<kensu;i++) free(ptr[i]); } ちゃんと動いているようです。 しかし、ポインタ配列の動的確保をネットで調べてみると、ポインタのポインタ(?)を使って、下記のように2度mallocしています。 #include <stdio.h> #include <stdlib.h> #define N 3 int main(void) { char** arr; int i,j; arr = (char**)malloc(N * sizeof(char*)); /* ポインタ配列を確保 */ /* 配列の要素それぞれにつき、メモリ領域を確保 */ for(i=0;i<N;i++) arr[i] = (char*)malloc(N * sizeof(char));   ・・・ ポインタの配列を宣言して、配列の各要素に動的確保するのと ポインタのポインタを宣言し、ポインタ配列を動的確保して、再度配列の要素に動的確保するのとでは、何か違いがあるのでしょうか? ポインタのポインタを宣言し、ポインタ配列を確保する必要性が良く分かっていないのです。 ネット等で調べて見たのですが、理解力がないのかよく分かりませんでした。 どうか教えてください。

専門家に質問してみよう