ページ 11

C++(std::string とconst char*と char*についてとそれらのタイプ変換について)

Posted: 2008年12月10日(水) 16:34
by LaL
どうもこんにちは。いつもお世話になります(_ _)
C++初心者の者です。

宿題や仕事ではないのですが、個人的な実験で、VisualC++でC++のstringからC stringへのタイプ変換をしようといろいろ試みているのですが、うまくいきません。以下のやり方で試してみましたが、どれも駄目でした。
どうすればよいでしょうか…?
また、std::stringとconst char*の違いは何なのでしょうか?以下のコードのエラーを見て頂けるとお分かりになるかと思うのですが、最初に=とc_str()を使ったときには、stringがconst char*型なので、char*型であるC stringには変換できないとエラーが出ました。なので次はconst char*型のパラメータを受け取るstrcpy関数を試してみたのですが、今度は、stringがstd::string型なので、const char*には変換できないというエラーが出ました…。
string cplString = "aaaa";
char* cStr;
cStr =(cplString.c_str());//これだと、cannot convert from 'const char *' to 'char *' というエラー。
strcpy(cStr, cplString);//これは、cannot convert parameter 2 from 'std::string' to 'const char *'というエラー。

上二つが駄目だったので、クラス(あまりよくわかっていないのですが…)を使ってみました。これだけはコンパイルはしたのですが、実行中にstrcpyから先へ進めません…。

class cStrMaker
{
	public:
		cStrMaker::cStrMaker(const char* a)
		{
			strcpy(cStr,a);//bad pointer cStrというエラー。
		}

		cStrMaker::~cStrMaker(void)
		{
		}
	private:
		char* cStr;
};

std::string strStdString ("Hello!");
cStrMaker cString(strStdString.c_str ());

わかりにくい説明ですみません(_ _)
助けてくれる方がいるととても有難いです。

Re:C++(std::string とconst char*と char*についてとそれらのタイプ変換について)

Posted: 2008年12月10日(水) 16:58
by Mist
cStrはポインタで実体がないから、strcpy(cStr,a)なんてすればメモリ破壊しています。

string cplString = "aaaa";
char* cStr;
cStr =(char*)(cplString.c_str());

一応これでいいと思うけど、このあとcStrに何かをしようというのであればその内容によってはかなり危険です。

Re:C++(std::string とconst char*と char*についてとそれらのタイプ変換について)

Posted: 2008年12月10日(水) 17:03
by 御津凪
const char* は、内部の変更が出来ない char* 型です。
つまり、 std::string の c_str() で受け取ったデータはそのまま変更することが出来ない(読み取り専用)ということです。

Mist さんの方法でコンパイルは通りますが、おっしゃっているとおり使い方によっては危険です。

Re:C++(std::string とconst char*と char*についてとそれらのタイプ変換について)

Posted: 2008年12月10日(水) 17:28
by ouh
char* cStr;
について new, delete は使いたくない。
だからといって
char cStr[定数];
というのも嫌。
cStr を変更したときの cplString に対する危険も避けたい。
その逆も避けたい。
ということだとすると、なんか手詰まりなような...

私もいい方法あったら知りたいです。

Re:C++(std::string とconst char*と char*についてとそれらのタイプ変換について)

Posted: 2008年12月10日(水) 17:38
by GPGA
>ouhさん
最初からstd::stringを使えばよいだけでは?

Re:C++(std::string とconst char*と char*についてとそれらのタイプ変換について)

Posted: 2008年12月10日(水) 17:53
by GPGA
string変換先を、生ポインタでやるか、vector使うかくらいしかないですね。
// その1
class cStrMaker
{
public:
	cStrMaker(const char* a) : cStr(NULL) {
		cStr = new char[strlen(a) + 1];
		strcpy(cStr, a);
	}

	~cStrMaker(void) {
		delete[/url] cStr;
	}
private:
	char* cStr;
};

// その2
class cStrMaker
{
public:
	cStrMaker(const char* a) : cStr(strlen(a) + 1) {
		strcpy(&cStr[0], a);
	}

	~cStrMaker(void) {}
private:
	std::vector<char> cStr;
};
 

Re:C++(std::string とconst char*と char*についてとそれらのタイプ変換について)

Posted: 2008年12月10日(水) 18:03
by ななし
std::string から char 配列に変換して、char 配列に手を加えた上で再度 std::string に渡すには、

std::string str("abcde");
char* p = (char*)std::malloc((str.size() + 1) * sizeof(char)); // char 配列の領域を確保
std::strcpy(p, str.c_str()); // std::string の文字列を char 配列にコピー
p[2] = 'z'; // ちょっと書き換える
str = p; // str に変更した文字列を反映
std::free(p); // char 配列の領域を解放

こんな感じでしょうか。
ただ、これをするぐらいなら直接書き換えた方が楽です。

std::string str("abcde");
str[2] = 'z';

ちなみに cStrMaker で実行時エラーになるのは、cStrMaker::cStr のポインタの指す先が存在していないからです。
malloc なり new なりで cStr の指す先を確保してやるべきでしょう。

Re:C++(std::string とconst char*と char*についてとそれらのタイプ変換について)

Posted: 2008年12月10日(水) 18:12
by LaL
返信皆さん親切なアドバイスありがとうございます(_ _)

>Mistさん。 Mistさんのキャストに、constキャストをつけて、cStr =const_cast<char*>(cplString.c_str()) のように実行してみたのですが、それだと少しは危険度が下がりますでしょうか?実はそもそも、何がどう危険なのかが知識不足の私にはよくわかっていないのですが…(汗)ダウンキャストの危険性という記事は読んできたのですが、stringをC stringに型変更するときの危険性というのが、まだよくわからないのです。

>御津凪さん。 なるほど、です。std::stringは値を変えられるので、const char*ではないのですね。私はc_strという関数についてよく理解していなかったようです。c_strはC string型を返すのではないのですね。

>ouhさん。newを使うというのは、こういうことなのでしょうか?みつけて来ました…cplusplus.comからのコピーです。
char * cstr, *p;

  string str ("Please split this phrase into tokens");

  cstr = new char [str.size()+1];
  strcpy (cstr, str.c_str());
これだと、安全なのですか?

Re:C++(std::string とconst char*と char*についてとそれらのタイプ変換について)

Posted: 2008年12月10日(水) 18:13
by ouh
>GPGAさん

> 最初からstd::stringを使えばよいだけでは?
そうですよね。私もそうします。
でもスレ主さんは char* にしたいということだったものですから。
スレ主さんが new とかしたくないって言ったわけじゃないけど、
なんとなくそういうことかな?って。new 使ったり、char cStr[定数]
もありなら簡単だから質問しに来てないんじゃないかな、と思った
わけです。で、だとしたら手詰まりじゃなかな、と思いました。

※これは言い訳してるのであってGPGAさんに反論しようというつもり
ではないです。お気を悪くされたらすみません。

Re:C++(std::string とconst char*と char*についてとそれらのタイプ変換について)

Posted: 2008年12月10日(水) 18:21
by non
中身を変更しないのなら、constにすればいいと思うのですが。。。
const char* cStr;
cStr =(cplString.c_str());

char*で指して、どうしても変更したいのでしょうか。

Re:C++(std::string とconst char*と char*についてとそれらのタイプ変換について)

Posted: 2008年12月10日(水) 18:29
by LaL
>GPGAさん。

コードを書いてくださってありがとうございます(_ _)私はまだまだ初心者なので、コードをきちんと理解する為にあちこち検索してシンタックスの意味を調べたりして、ちょっと時間はかかりますが、お手本のサンプルコードがあると学びやすいです。感謝です。

>ななしさん。

丁寧な解説とコードをありがとうございます(_ _)なるほど、です。そういう風にすると、string型とC string型を、双方向で交換できるのですね。コードの中でまだよくわからないところもあるので、ちょっと調べてみます。

Re:C++(std::string とconst char*と char*についてとそれらのタイプ変換について)

Posted: 2008年12月10日(水) 18:30
by ouh
LaLさんへ

>ouhさん。newを使うというのは、こういうことなのでしょうか?
ちゃんと delete [/url] をするのを忘れなければそれでOKだと思います。

最初から str のあり得るサイズがあらかじめわかっているなら
char cstr[定数];
strcpy(cstr, str.c_str());
でもいいですしね。

ところで、std::string の文字列のコピーを char* に欲しい、と
いう解釈いいですか?
もしかして私は全くお門違いの解釈で書き込みをしているんでしょう
か?そうだとしたら本当にすみません。私のことは無視してください。

Re:C++(std::string とconst char*と char*についてとそれらのタイプ変換について)

Posted: 2008年12月10日(水) 18:34
by LaL
>ouhさん。

どうも私の質問が妙なもののせいで、すみません(_ _)
newを使えば簡単、というのもまだよくわからないくらい初心者なので…。
申し訳ないです。

>nonさん。

なるほど、です。変更しないのなら、そういうやり方もあるのですね。
一応、変更したいと思ってコードをいじくってはいたのですが、皆さんに教えてもらってやり方がわかって来ました。

Re:C++(std::string とconst char*と char*についてとそれらのタイプ変換について)

Posted: 2008年12月10日(水) 18:36
by LaL
>ouhさん。

ouhさんの解釈は全くその通りです。
いろいろありがとうございます。こちらこそすみません。

Re:C++(std::string とconst char*と char*についてとそれらのタイプ変換について)

Posted: 2008年12月10日(水) 18:44
by LaL
皆さん、本当にありがとうございました(_ _)
この件については、後は何とか自分で調べていけばわかりそうです。