C++の問題に困っています

このQ&Aのポイント
  • C++の入門書の演習問題に取り組んでいますが、答えがなく悩んでいます。
  • 問題としては、文字列 s に含まれる最も先頭に位置する文字 c へのポインタを返す関数 strchr_ptr を作成することです。
  • コンパイルして実行するとアドレス的な表記がされず、どうすればいいか分かりません。初歩的な質問ですが、教えてください。
回答を見る
  • ベストアンサー

C++の問題で困っています。

C++の問題で困っています。 今,C++の入門書を読んでその中の演習問題に取り組んでいるのですが、この本には答えがついていないみたいなので、問題で悩んでいます。 お力を貸してください。 問題 「文字列 s に含まれる最も先頭に位置する文字 c へのポインタを返す関数 strchr_ptr を作成せよ。型は char * strchr_ptr(const char *s, char c); とする。例えば、文字列 s が "ABSZXYX" で文字 c が 'X' であれば、返却するのは &s[4]である。 なお、文字 c が文字列 s に含まれない場合は NULL を返却すること。 」 です。 僕はこの問題に対して、以下のように答えました。 ヘッダのインクルードなどは省きます。 char *strchr_ptr(const char *s, char c) {         for(int i = 0; s[i]; i++)         if(s[i] == c)             return const_cast<char *>(&s[i]);     return NULL; } int main() {     char s[36] = "ABSZXYX";     cout << strchr_ptr(s, 'X') << "\n";     cout << &s + 4 << "\n"; } と書きました。 cout << &s + 4 << "\n"; はこの上の文で導き出したアドレスがあっているか確かめるものです。 ですが、これをコンパイルして実行すると、 ----------------- XYX 0012FFE0 ----------------- となり、関数側のほうはアドレス的な表記をしてくれません・・。 どうにかして、アドレス表記にしようとあれこれ考えたのですが、どうしても出来ませんでした。 どのようにしたらいいのか教えてください。 初歩的な質問ですが、よろしくお願いします。

  • jaron
  • お礼率80% (28/35)

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

  • ベストアンサー
  • jacta
  • ベストアンサー率26% (845/3158)
回答No.1

>     cout << strchr_ptr(s, 'X') << "\n"; cout << static_cast<void*>(strchr_ptr(s, 'X')) << "\n"; としてください。 >     cout << &s + 4 << "\n"; こちらも間違っています。 cout << static_cast<void*>(s + 4) << "\n"; としてください。

jaron
質問者

お礼

なるほど! こういう時には char へのポインタだと文字列の表示になってしまうから, どの型にでも対応できる void へのポインタにキャストしてから表示するんですね。 まさかこんな所で void へのポインタへ型キャストするなんて思いもしませんでした・・。 ありがとうございました!

その他の回答 (1)

回答No.2

int main() { char s[36] = "ABSZXYX"; cout << static_cast<void*>(strchr_ptr(s, 'X')) << "\n"; cout << static_cast<void*>(s + 4) << "\n"; }

jaron
質問者

お礼

なるほど! 下の方のご回答でも知りましたが、やはりこういうときはvoid型へのポインタに型キャストしてから表示するんですか! 回答ありがとうございました。 下の方とほとんど変わらない説明をしてくださっているのですが、下の方のほうが早かったということで、下の方をベストアンサーに選ばせていただきます。 ごめんなさい。

関連するQ&A

  • C++の問題で・・

    C++の問題で・・ 参考書に「簡易的な文字列クラスStringを作成せよ。」という問題があり作りました。 いかにそのコードを示します。今回の質問の内容に関係ないとおもうところや、インクルードなどは省かせていただきます。 環境は Visual studio 2008です。OSはXPです。 class String{     int len; //文字列の長さ     char *s; //文字列の先頭文字へのポインタ public:     String(const char *);     int length()const{return len;} //長さを求める     operator const char * ()const{return s;}     bool operator==(String &a)const{return strcmp(this->s, a);}     char *operator+(String&)const; }; char * String::operator +(String &a)const {     char *memory = new char[this->len + a.len + 1];     memory[0] = '\0';     return strcat(strcat(memory, this->s), a); } String::String(const char *p): s(const_cast<char *>(p)), len(strlen(p)){} String::String(const String &x) {     s = x.s;     len = x.len; } inline std::ostream& operator<<(std::ostream &s, String &x) {     return s << static_cast<const char *>(x); } int main() {     String a("My name is Paul");     String b("My name is Paul");     String c("My name");     String d(" is Paul");     cout << "a = " << a << "\n";     cout << "b = " << b << "\n";     cout << "c = " << c << "\n";     cout << "d = " << d << "\n";     cout << "a == b " << (a == b) << "\n";     cout << "a == c " << (a == c) << "\n";     cout << "c + d = " << (c + d) << "\n"; }     このようなプログラムなのですが、上記の char * String::operator +(String &a)const {     char *memory = new char[this->len + a.len + 1];     memory[0] = '\0';     return strcat(strcat(memory, this->s), a); } ところで、 memory[0] = '\0'; を除くと文字列を出力した結果をみると、先頭にいらない言葉が入っています。 僕の場合は x9My name is Paul と表示されます。文字化け・・ではないのですが、ゴミのようなものが・・ どうしてこのようなことが起こるか、どこでゴミが入ってしまうのか教えてほしいです。 稚拙なプログラムで申し訳ないです。 もし、間違っている場所や、もっと簡単にかけるようなところがあれば、ご指摘いただくとありがたいです。 よろしくお願いします!

  • C++の関数テンプレートで分からないところがあります。

    C++の関数テンプレートで分からないところがあります。 C++の入門書を読んで勉強しているのですが、その演習問題(答えはついてないです)で、以下のような問題がありました。 ----------------------------------------------------- 配列の全要素の最小値を求める関数テンプレートを作成せよ。 teplate <class Type> Type minof(const Type x[], int n); という形で作ること。 なお、最も小さい文字列を求められるようにするために、const char *型に明示的に特殊化したものも合わせて作成すること。 ------------------------------------------------ という問題なのですが、これにたいして僕は以下のように答えました。ヘッダのインクルードなどは省きます。 template<class Type> Type minof(const Type x[], const int n) {     int min = 0;     for(int i = 1; i < n; i++)         if(x[min] < x[i])             min = i;     return x[min]; } template<> const char* minof<const char *>(const char x[][64], const int n) {     int min = 0;     for(int i = 1; i < n; i++)         if(strcmp(x[min], x[i]) < 0)             min = i;     return x[min]; } int main() {     const int n = 5;     int a[n];     char s[n][64];     for(int i = 0; i < n; i++){         cout << i + 1 << "番目---";         cin >> a[i];     }     cout << "文字列\n";     for(int i = 0; i < n; i++){         cout << i + 1 << "番目---";         cin >> s[i];     }     cout << "整数の最小値---" << minof(a, n) << "です\n";     cout << "文字列の最小値---" << minof<const char *>(s, n) << "です\n"; } これをコンパイルすると、エラーで 明示的な特殊化; 'const char *minof<const char*>(const char [][64],const int)' は関数テンプレートの特殊化ではありません と 'minof' : 1 番目の引数を 'char [5][64]' から 'const char *const []' に変換できません。 とでてしまいます。 色々探してみたのですが、解決できませんでした・・。 特に最初のほうのエラーがよくわかりません。ちゃんと特殊化してる気はするのですが・・。 間違っている箇所の正当を載せていただけるとわかりやすくて、ありがたいです。 よろしくお願いします!

  • C言語 ファイルの意味

    C言語 文字列で分からない部分があるのでご教示お願いします。 内容は「文字列の検索」です。 #include<stdio.h> #include<string.h> int main(void) { char word[] = "abcabdabe"; char word2[] = "abd"; char *word3 = "ABD"; char *word4 = NULL; printf("処理前の文字列:%s\n", word); word4 = word; word4 = strchr(word4, *word2); while (word4 != NULL){ printf("'a'が見つかった場所からの文字列: %s<\n", word4); if (strncmp(word4, word2, strlen(word2)) == 0) { strncpy(word4, word3, strlen(word3)); } word4 += 1; word4 = strchr(word4, *word2); } printf("処理後のword4: %s\n", word); return 0; } このプログラムの場合、word3とword4ではなぜ、*word3, *word4とポインタで設定するのでしょうか? また、「word4 = strchr(word4, *word2)」と *word2のようにlここでポインタ指定するのは何故なのでしょうか?

  • C言語 説明文

    C言語(文字列のコピーについて) /* 文字列のコピーを行う関数の実現例 動作原理のコメントを書き入れる */ #include <stdio.h> /*-----文字列のコピー(1)-----*/ char *scpy1 (char *d, const char *s) { int i = 0; while ((d[i] = s[i]) != '\0') { i++; } return(d); } /*-----文字列のコピー(2)-----*/ char *scpy2 (char *d, const char *s) { char *p = d; while ((*d = *s) != '\0') { d++; s++; } return(p); } /*-----文字列のコピー(3)-----*/ char *scpy3 (char *d, const char *s) { char *p = d; while ((*d++ = *s++) != '\0') { ; } return(p); } /*-----文字列のコピー(4)-----*/ char *scpy4 (char *d, const char *s) { char *p = d; while (*d++ = *s++) { ; } return(p); } int main(void) { char astr[] = "ABC"; char bstr[8], cstr[8], dstr[8],estr[8]; scpy1 (bstr, astr); scpy2 (cstr, astr); scpy3 (dstr, astr); scpy4 (estr, astr); printf("astr = %s\n" , astr); printf("bstr = %s\n" , bstr); printf("cstr = %s\n" , cstr); printf("dstr = %s\n" , dstr); printf("estr = %s\n" , estr); return (0); } ----------------------- このプログラムに、この行で何をやっているのかわかるように 一言くらいの説明文を入れる問題です。 ところどころはわかるのですが、わからないところの方が多いです。 プログラムが長くて大変かとは思いますが、どうかよろしくお願いいたします。 このプログラム自体はちゃんとコンパイルでき、実行もできたので おそらく間違いないと思います。

  • 配列の練習問題

    #include<iostream> using namespace std; //count関数の宣言 int count(char str[], char ch); int main() { char str[100]; char ch; cout << "文字列を入力して下さい。\n"; cin >> str; cout << "文字列から探す文字を入力して下さい。\n"; cin >> ch; int c = count(str, ch); cout << str << "の中に" << ch << "は" << c << "個あります。\n"; return 0; } //count関数の定義 int count(char str[], char ch) { int i = 0; int c = 0; while (str[i]) { if (str[i] == ch) c++; i++; } return c; } こんにちは。 この問題の解答のプログラムの意味がイマイチ解らないので良かったら教えて下さい。 確認がてらに質問します。 よろしくお願いします。

  • strchr() の第2引数はなぜ int 型なのでしょうか

    もしかすると、ちょい前の質問(https://okauth.okwave.jp/qa4151232.html)と同じことを聞いているような気もしますが、気にせずポスト。 その質問を読んだ時に strchr() のマニュアルを見たわけなんですが、そのプロトタイプ宣言は char* strchr(const char* s, int c); なんですね。どうして第 2 引数の型が int なのでしょう?「文字」c を検索するんだから普通に考えれば char ではないかと思うのですが、誰か教えて下さい。 ソースはこんな感じだったので、int である必要はないように思えるのですがどうなんでしょうか? 負数を与えたときに「何らかの動作」を期待してのことなのでしょうか? char* strchr(const char* s, int c) {  char ch;  ch = c; /* <= 結局 char 型にしている */  for ( ; ; ++s) {   if ( *s == ch ) {    return (char*)s;   }   if ( *s == '\0' ) {    return NULL;   }  } }

  • C++ 文字列とポインタ、STL::mapについて

    C++でポインタと文字列の受け渡しについて質問です。 MyData::search()は文字列を受け取ってメンバ変数 dict内の ヒットしたデータの グループ(文字列)を返すメンバ関数です。 メンバ変数 dict はSTLのmapを使っています。 void MyData::search( const char* funcbox, const char* result ){ for ( map<const char*, const char*>::iterator itr = dict.begin(); itr != dict.end(); ++itr ){ const char* a_name = itr->first; const char* a_group = itr->second; if ( strstr( a_name, funcbox) ){ result = a_group; return; } } result = NULL; } MyData::dict["yamada"] = "groupA"; const char* res = NULL; MyData::search("yamada", res); cout << " group = " << res << endl; 上のようにアクセスするとメンバ関数内では res == "groupA" となりますが、 関数から出るとresはNULLになってしまいます。 res に関数を抜けた後も消えないアドレスを渡すにはどうすればよいでしょうか?

  • EAccessViolationクラス例外

    WindowsXPでBCB5を使用しています。 柴田望洋氏著、新版明解C++入門編の演習8-14ですが 「文字列sの文字の並びを反転する関数str_rvsを作成せよ。 char* str_rvs(char* s); たとえば、文字列sが"abc"であれば、その文字列を"cba"に更新する。受け取ったsの値をそのまま返却すること。」 と言う問題で、下記の様に作成したんですが、 char* s="a"、または"ab"、または"abc"とすると正常に終了しますが "abcd"とすると、 文字列[abcd]を反転します。 dcba 文字列[dcba]を反転します。 abcd が繰り返された後、「EAccessViolationクラスの例外を生成しました。~」が表示されて停止します。 s="abcde"とすると 文字列[abcde]を反転します。 edcba と1回表示されて、同様のエラーが発生しますが、何が悪いのかわかりません。ご教授願います。 //--------------------- #include <iostream> #include <cstring> using namespace std; char* str_rvs(char* s){ int len=strlen(s); char* tmp; for(int i=0;i<len;i++) *(tmp+i)=*(s+len-1-i); *(tmp+len)=NULL; for(int i=0;i<len;i++) *(s+i)=*(tmp+i); return s; } int main(){ char* s="abcd"; cout << "文字列[" << s << "]を反転します。\n"; cout << str_rvs(s) << '\n'; //getchar(); }

  • C言語のプログラミングでつまずいてます

    ポインタをりようする。string.hとctype.hに含まれる関数は使用しないこと。 以下の実行例のように、文字列を受け取り、アルファベットの大文字を小文字にして表示する関数を作成したいのですが 実行例: Original string is <AbCdE1f2> Modified string is <abcde1f2> #include <stdio.h> #define NUMOFCHAR 10 void print_char(char *ptr); int main(void) { char string[NUMOFCHAR+1]; printf("Input a sentence (# of letters <= %d): ", NUMOFCHAR); fflush(stdout); scanf("%s", string); string[NUMOFCHAR] = '\0'; printf("Original string is <%s>\n", string); printf("Modified string is <"); print_char(string); printf(">\n"); return 0; } void print_char(char *ptr) { int i=0; for(i=0 ; i<NUMOFCHAR+1 ; i++){ if( *ptr>='A' && *ptr<='Z'){ *ptr += 'A'-'a' ; } ptr++ ; } printf("%s",ptr); } よ書いたのですがビルドえらーがおこります。 どこがだめなのかわかりません。。。 C言語に詳しい人でわかるかた、どこがいけないのか、なぜいけないのか、どうすればいいのか詳しくおしえてください。 お願いします

  • 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; }