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();
}
No.5ベストアンサー
- 回答日時:
> 文字列のコピーを作りたかったので、char* tmp="";等と初期化してやってみてどうしてもうまく行きませんでした
ANo.4 でも書きましたが,この場合 tmp (が指している先)を書き換えてはいけません。
(const char* tmp=""; とすべき)
コピー元の文字列(終端のナル文字含む)を格納するのに十分なサイズのコピー先を自分で用意してやる必要があります。
const char *src = "abcd"; // コピー元
char dst[256]; // コピー先
strcpy(dst, src); // src (が指している先にある文字列)を dst にコピー
度々の回答ありがとうございます。
>ANo.4 でも書きましたが,この場合 tmp (が指している先)を書き換えてはいけません。
>(const char* tmp=""; とすべき)
char dst[256];
strcpy(dst, src);
とすると正常に目的の結果が得られました。
ポインタはこういうものだと理解しておきます。
No.4
- 回答日時:
他にもまずいところがあって,
char* s="abcd";
と宣言した場合,s の内容を書き換えてはいけません。
char s[] = "abcd";
なら OK。
# 文字列の先頭と末尾から,文字単位で入れ替えていけば,
# 文字列のコピーを作らなくても大丈夫ですよ。
ありがとうございます。
文字列のコピーを作りたかったので、char* tmp="";等と初期化してやってみてどうしてもうまく行きませんでしたが、おっしゃられる通り
char tmp;
for(int i=0;i<=(len/2-1);i++){
tmp=*(s+i);
*(s+i)=*(s+len-1-i);
*(s+len-1-i)=tmp;
}
として、文字単位で入れ替えてみると正常に終了しました。
No.3
- 回答日時:
tmpが参照するべき実体がありません。
実体がないので
> *(tmp+i)=*(s+len-1-i);
は「どことも知れないメモリ」にアクセスしようとします。結果としてOS側で不正なメモリアクセスを検知して例外を送出します。
あと、どうでもいい部類には入りますが、
> *(tmp+len)=NULL;
「ヌルポインタ(NULL)」と「ヌル文字('\0')」は(C++の範疇では)同じ値を示しますが、概念としては別モノです。
文字列終端のヌル文字の代用にNULLを使うのは避けた方がいいでしょう。
ありがとうございます。
>>「ヌルポインタ(NULL)」と「ヌル文字('\0')」は(C++の範疇では)同じ値を示しますが、
>>概念としては別モノです。
>>文字列終端のヌル文字の代用にNULLを使うのは避けた方がいいでしょう。
まだポインタの概念を良く理解してない為、参考にさせていただきます。
No.2
- 回答日時:
# ご参考: C++なんだからそんなものわざわざ自作せんでも...
#include <iostream>
#include <cstring>
#include <algorithm> // 追加
using namespace std;
char* str_rvs(char* s){
std::reverse(s, s+strlen(s)); // これでオシマイ
return s;
}
int main(){
char s[] = "abcd";
cout << "文字列[" << s << "]を反転します。\n";
cout << str_rvs(s) << '\n';
}
ありがとうございます。
勉強中なのでrevrese()は知りませんでしたが、うまく行きました。
revrese()無しでもやってみます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# str[j++]の意味 2 2022/08/30 16:20
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# C++のcinの動作 5 2023/02/26 00:13
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# sprintf()の使い方について 1 2022/08/17 16:16
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
char*を初期化したいのですが
-
csvファイルをfscanfで読み込む...
-
strcatの逆をしたい
-
char型の文字列をウィンドウに...
-
C言語にて構造体のメンバがNULL...
-
const char* s1とただのchar s1...
-
fgetc( )の戻り値はなぜ整数??
-
文字列置換のアルゴリズムを教...
-
文字列のコピーについて
-
C言語のchar型配列を計算させる...
-
可変長構造体をファイルから読...
-
CStringからchar*への型変換に...
-
構造体・ビットフィールドのvol...
-
コマンドライン引数
-
文字列の比較
-
char型にint型の数値を代入する。
-
C++言語で文字列を出力するには...
-
C言語のプログラムについてです
-
C++17で、unsigned char * 配列...
-
苦しんでCを読んでchar型は文字...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語のintとcharの違いってな...
-
char*を初期化したいのですが
-
C言語にて構造体のメンバがNULL...
-
CStringからchar*への型変換に...
-
strcat関数を自作したいです
-
new charとnew char[N]の違いは?
-
csvファイルをfscanfで読み込む...
-
char型にint型の数値を代入する。
-
動的メモリの初期化方法について。
-
C言語で文字列をかえす正しい書...
-
char 文字列型 の表現範囲が-12...
-
文字列str内の全ての数字を...
-
DWORDとcharの変換
-
fstream型オブジェクトを関数の...
-
C言語のプログラムについてです
-
小数点入りの文字列をfloat型に...
-
szとlpszの違い
-
const char* s1とただのchar s1...
-
文字列内の数字削除
-
c言語でポインタ変数を用いた配...
おすすめ情報