C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[6]: char型文字列の結合


(過去ログ 55 を表示中)

[トピック内 11 記事 (1 - 11 表示)]  << 0 >>

■30869 / inTopicNo.1)  char型文字列の結合
  
□投稿者/ 凪 (6回)-(2009/01/08(Thu) 14:53:19)

分類:[C/C++] 

WinXP
VC++2003

初心者です。VC++の勉強中です。(いくつも質問立ててすいません)

char型の文字列結合について質問させてください。

vector<char>::iterator a;

a.push_back("A");
a.push_back("B");
a.push_back("C");

というソースがあったとします。
このvector内の内容を表示するにはイテレータを使い

vector<char>::iterator x;

for(x = a.begin(); x != a.end(); x++)
cout << *x << endl;

とすると思います。
ではこのchar達を一つのchar*変数に突っ込んでいく場合はどう実現すればいいのでしょう?

char* XYZ;

for(x = a.begin(); x != a.end(); x++)
strcat(XYZ, *x);

としてもエラーになってしまいます。
char*とchar*の結合はできるのですが、char*とcharの結合ではstrcatの引数に合わない為にエラーとなるようです。
(もしくはcharじゃなくてiteratorだからかな?)

良い方法があったら教えてください。宜しくお願いします。

引用返信 編集キー/
■30872 / inTopicNo.2)  Re[1]: char型文字列の結合
□投稿者/ επιστημη (1492回)-(2009/01/08(Thu) 15:00:41)
επιστημη さんの Web サイト
> vector<char>::iterator a;
> a.push_back("A");
> a.push_back("B");
> a.push_back("C");
> というソースがあったとします。

そんなソースない。正しくは:
 vector<char> a;
 a.push_back('A');
 a.push_back('B');
 a.push_back('C');

> char達を一つのchar*変数に突っ込んでいく場合はどう実現すればいいのでしょう?

#include <vector>
#include <iostream>
#include <algorithm>

using namespace std;

int main() {
  vector<char> a;

  a.push_back('H');
  a.push_back('e');
  a.push_back('l');
  a.push_back('l');
  a.push_back('o');

  char* XYZ = new char[a.size()+1]; // 領域を確保して
  *copy(a.begin(), a.end(), XYZ) = '\0'; // vector<char> からコピー、末尾に'\0'
  
  cout << '[' << XYZ << ']' << endl;
  delete[] XYZ; // 領域解放
}

引用返信 編集キー/
■30874 / inTopicNo.3)  Re[2]: char型文字列の結合
□投稿者/ επιστημη (1493回)-(2009/01/08(Thu) 15:09:19)
επιστημη さんの Web サイト
>char達を一つのchar*変数に突っ込んでいく場合はどう実現すればいいのでしょう?

別解。vectorの各要素はリニアに並んでいることが保証されているから:

#include <vector>
#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

int main() {
  vector<char> a;

  a.push_back('H');
  a.push_back('e');
  a.push_back('l');
  a.push_back('l');
  a.push_back('o');
  a.push_back('\0'); // 終端文字
  
  char* XYZ = new char[a.size()];
  strcpy(XYZ, &a[0]); // a[0] のアドレスが文字列"Hello"の先頭となる。
  cout << '[' << XYZ << ']' << endl;
  delete[] XYZ;
}

引用返信 編集キー/
■30877 / inTopicNo.4)  Re[2]: char型文字列の結合
□投稿者/ 774RR (279回)-(2009/01/08(Thu) 15:23:10)
うーん。
C++ の範囲に留まっている限りにおいては vector + string だけ使えば考える量が減っていいよ。

C のネイティブ char や単純配列を使うのであれば、ポインタと配列の違いを理解しておく必要がある。
string も vector も、ポインタと配列の違いを覆い隠してくれるので便利に使えるんだけどさ。
勝手にリサイズしてくれるし。

> char達を一つのchar*変数に突っ込んでいく場合はどう実現すればいいのでしょう?
char* には char を入れることはできない、と言ったら驚くレベルの人なのかな?

char* が有効な char の配列の先頭要素を指している場合に限り、なおかつ、
入れるべき(複数の) char が、その配列の要素数を超えない限り、にのみ
char* に char を入れることができる、わけなんだ。

その辺の理解は、いつか必ずしなきゃなんないんだけど・・・

void testfunc() {
  char* p; // char* だけ作った
  // *p='A'; // ここでこれはだめ! p はまだ有効な char 配列を指していない
  char a[1000]; // 有効な char 配列を作った
  p=a; // p は a の先頭を指すようにした
  *p='A'; // OK
}

引用返信 編集キー/
■30878 / inTopicNo.5)  Re[3]: char型文字列の結合
□投稿者/ 凪 (7回)-(2009/01/08(Thu) 15:27:42)
No30874 (επιστημη さん) に返信

ご回答有難うございます。

上手く回ってくれました。

お手数ですがちょっと確認させてください。

一つ目の解法の解釈ですが、

■*copy(a.begin(), a.end(), XYZ) = '\0';
 *copyは「aの最初から最後までをXYZに複写したモノ」で、これの終端にポインタがあると考え「='\0'」で「終端 = '\0'」で「終端の値」として'\0'を入れている、で合ってますか?

引用返信 編集キー/
■30880 / inTopicNo.6)  Re[4]: char型文字列の結合
□投稿者/ επιστημη (1494回)-(2009/01/08(Thu) 15:37:00)
επιστημη さんの Web サイト
2009/01/08(Thu) 15:39:20 編集(投稿者)

> ■*copy(a.begin(), a.end(), XYZ) = '\0';
>  *copyは「aの最初から最後までをXYZに複写したモノ」で、これの終端にポインタがあると考え「='\0'」で「終端 = '\0'」で「終端の値」として'\0'を入れている、で合ってますか?

そーです。copyの戻り値がコピー先の末端となります。


引用返信 編集キー/
■30881 / inTopicNo.7)  Re[4]: char型文字列の結合
□投稿者/ .SHO (523回)-(2009/01/08(Thu) 15:37:01)
No30878 (凪 さん) に返信

> ■*copy(a.begin(), a.end(), XYZ) = '\0';
>  *copyは「aの最初から最後までをXYZに複写したモノ」で、これの終端にポインタがあると考え「='\0'」で「終端 = '\0'」で「終端の値」として'\0'を入れている、で合ってますか?

copy関数の戻り値が、終端へのポインタってことだと思います。

引用返信 編集キー/
■30884 / inTopicNo.8)  Re[5]: char型文字列の結合
□投稿者/ επιστημη (1495回)-(2009/01/08(Thu) 15:56:57)
επιστημη さんの Web サイト
ご参考。ぶっちゃけ string がいっちゃん楽です。

#include <vector>
#include <iostream>
#include <algorithm>
#include <string>

using namespace std;

int main() {
  vector<char> a;

  a.push_back('H');
  a.push_back('e');
  a.push_back('l');
  a.push_back('l');
  a.push_back('o');
  
  string XYZ(a.begin(), a.end()); // こんだけ。
  cout << '[' << XYZ << ']' << endl;
}

引用返信 編集キー/
■30891 / inTopicNo.9)  Re[5]: char型文字列の結合
□投稿者/ επιστημη (1496回)-(2009/01/08(Thu) 17:07:10)
επιστημη さんの Web サイト
No30881 (.SHO さん) に返信
> copy関数の戻り値が、終端へのポインタってことだと思います。

"最後にコピーしたとこの次を指すイテレータ"を返します。
copyに引き渡したコピー先イテレータが char*だったので、
copyから戻ってくるのもchar*:
「終端記号を打ち込むべき位置を表すポインタ」
てことになるですね。

引用返信 編集キー/
■30892 / inTopicNo.10)  Re[6]: char型文字列の結合
□投稿者/ 凪 (8回)-(2009/01/08(Thu) 17:24:41)
No30884 (επιστημη さん) に返信

大変参考になりました。

一朝一夕で理解はできなそうですが、ちょっと気合入れて勉強したいと思います。

お忙しい中色々と有難うございました。
またよろしくお願いします。

.SHOさんも有難うございました^^
解決済み
引用返信 編集キー/
■30894 / inTopicNo.11)  Re[3]: char型文字列の結合
□投稿者/ 凪 (9回)-(2009/01/08(Thu) 17:26:31)
No30877 (774RR さん) に返信

わざわざ例まで出していただき大変わかりやすかったです。

どうもありがとうございました。

またよろしくお願いします^^
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -