windows Vista sp1, Visual C++ 2008でC++の勉強をしています。
Vectorへのポインタが入ったvectorを使うプログラムを書いているのですがうまくいかず、困っています。
どういうプログラムかというと、
入力ファイルの">"という記号を区切りとして、その間にある各行をひとまとめのグループとしてvectorにいれます。
さらに各vectorのポインタをべつのvectorに入れます。 最終的に区切りの数だけvectorができ、入力ファイルを読み終わった後に
すべてのvectorを"各グループのポインタが入ったvector"からループ処理ですべて出力する、というものです。
/入力ファイル input.txt/
>
human
cat
dog
>
beetle
dragonfly
spider
>
salmon
saury
catfish
>
vector1には human cat dog
vector2にはbeetle dragonfly spider
vector3にはsalmon saury catfish
が入り、 別のvectorにそれぞれのvectorのポインタをいれ、 最後にこのvectorをつかって全ファイル内容を出力するというものです。
具体的に書くと、
">"の区切りごとの各行のstringを入れるvectorとしてeach_vector。 each_vectorのポインタを入れるvectorをvector_of_ptr_each_vectorとします。
">"を認識するごとに new で each_vectorの領域を確保し、そのポインタをvector_of_ptr_each_vectorに追加していき、">"のない行のstringを each_vectorに入れます。
ファイルの読み込みが終わった後でvector_of_ptr_each_vectorからイテレータを使って各vector(each_vector)の全要素をそれぞれ出力する、というものです。
以下のようにコードを書きました。
#include <fstream>
#include <string>
#include <vector>
#include <iostream>
using namespace std;
int main( )
{
ifstream ifs("input.txt");
string buf;
std::vector<string> each_vector;
std::vector<std::vector<string> *> vector_of_ptr_each_vector;
while(ifs && getline(ifs, buf)) {
if(buf[0] == '>'){
std::vector<string>* ptr_eachvector ;
ptr_eachvector = new std::vector<string>;
each_vector = *ptr_eachvector ;
vector_of_ptr_each_vector.push_back(ptr_eachvector) ;
}
each_vector.push_back(buf) ;
}
printf("\n output from vector of ptr of vector\n");
std::vector<std::vector<string> *>::iterator it_b = vector_of_ptr_each_vector.begin();
while( it_b != vector_of_ptr_each_vector.end() )
{
std::vector<string>::iterator it_c = it_b->begin(); //エラー1
while( it_c != it_b->end() ) //エラー2
{
cout << *it_c << endl;
++it_c;
}
++it_b;
}
return 0;
}
ですが、エラーでビルドされず、
std::vector<string>::iterator it_c = it_b->begin(); の行に関して
error C2839: invalid return type 'std::vector<_Ty> **' for overloaded 'operator ->'
error C2039: 'begin' : is not a member of 'std::_Vector_iterator<_Ty,_Alloc>'
while( it_c != it_b->end() ) の行に関して
error C2839: invalid return type 'std::vector<_Ty> **' for overloaded 'operator ->'
1> with
1> [
1> _Ty=std::string
1> ]
error C2039: 'end' : is not a member of 'std::_Vector_iterator<_Ty,_Alloc>'
1> with
1> [
1> _Ty=std::vector<std::string> ,
1> _Alloc=std::allocator<std::vector<std::string> >
1> ]
fatal error C1903: unable to recover from previous error(s); stopping compilation
というようなエラーが出ます。
vectorのポインタを入れたvectorの扱い、特にイテレータに関して問題があると思うのですが原因が分かりません。
また、new でのeach_vectorの領域確保の方法も怪しいという感じがします。
解決策、アドバイスありましたらよろしくお願いします。
No.5ベストアンサー
- 回答日時:
#include <fstream>
#include <string>
#include <vector>
#include <iostream>
using namespace std;
int main() {
ifstream ifs("input.txt");
string buf;
std::vector<std::vector<string> *> vector_of_ptr_each_vector;
while(ifs && getline(ifs, buf)) {
std::vector<string>* ptr_eachvector ;
if(buf[0] == '>'){
ptr_eachvector = new std::vector<string>;
vector_of_ptr_each_vector.push_back(ptr_eachvector) ;
} else {
ptr_eachvector->push_back(buf) ;
}
}
cout << "\n output from vector of ptr of vector\n";
std::vector<std::vector<string> *>::iterator it_b = vector_of_ptr_each_vector.begin();
while( it_b != vector_of_ptr_each_vector.end() ) {
std::vector<string>::iterator it_c = (*it_b)->begin();
while( it_c != (*it_b)->end() ) {
cout << '[' << *it_c << "] ";
++it_c;
}
cout << endl;
++it_b;
}
return 0;
}
具体的なコードを書いていただいて、非常にありがたいです。
ですが、Debug Errorで
Run-time Check Failure #3 - the variable 'ptr_eachvector' is being used without being initialized.
となってしまうようです。
VC++環境特異的な問題でしょうか??
No.7
- 回答日時:
少し、手直しをして、サンプル作ってみました。
----------------------------------------------------------------------
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
// using namespace std;
int main()
{
std::ifstream ifs("input.txt");
std::string buf;
// std::vector<string> each_vector;
// std::vector<std::vector<string> *> vector_of_ptr_each_vector;
std::vector< std::vector<std::string> > vector_of_string_vector;
std::vector<std::string> string_vector;
bool boFirstuse = true;
while (ifs && std::getline(ifs, buf))
{
if ((buf[0] == '>'))
{
// std::vector<string>* ptr_eachvector ;
// ptr_eachvector = new std::vector<string>;
// each_vector = *ptr_eachvector ;
// vector_of_ptr_each_vector.push_back(ptr_eachvector) ;
if (!boFirstuse)
{
vector_of_string_vector.push_back(string_vector);
}
else
{
boFirstuse = false;
}
string_vector.clear();
// }
// each_vector.push_back(buf) ;
}
else
{
string_vector.push_back(std::string(buf));
}
}
printf("\n output from vector of ptr of vector\n");
// std::vector<std::vector<string> *>::iterator it_b = vector_of_ptr_each_vector.begin();
// while( it_b != vector_of_ptr_each_vector.end() )
// {
// std::vector<string>::iterator it_c = (*it_b)->begin();
// while( it_c != (*it_b)->end() )
// {
// cout << *it_c << endl;
// ++it_c;
// }
//
// ++it_b;
// }
std::vector< std::vector<std::string> >::iterator ite_a = vector_of_string_vector.begin();
int i = 0;
while (ite_a != vector_of_string_vector.end())
{
std::cout << "vector[" << i << "]:" << std::endl;
std::vector<std::string>::iterator ite_b = ite_a->begin();
while (ite_b != ite_a->end())
{
std::cout << *ite_b << std::endl;
ite_b++;
}
ite_a++;
i++;
}
return 0;
}
----------------------------------------------------------------------
> each_vectorの定義とnewに関して全く理解不足だったようです。もしよろしければ 正解のコード または参考になるサイトなど教えていただけないでしょうか。
> vector の使い方を解説したウェブサイトなら、検索すれば
いくつか見つかると思いますが、たぶん、vectorの使い方がわからないと言う
事でもないでしょうしね・・・
アルゴリズムとデータ構造から見直す習慣を付けると良いのではないでしょうか。
コードを書いていただきありがとうございました。
こちらの環境で正しく動きました。
また
bool boFirstuse = true;
の使い方なども非常に参考になりました。
No.6
- 回答日時:
ptr_eachvector の定義位置が間違ってる気がする>#5.
あと, 最後のブロックが入らない気がする (これは元のコードも同じかな).
たぶん, 最初の while ループ (+ 関連する変数の定義) は
string buf;
std::vector<std::vector<string> *> vector_of_ptr_each_vector;
std::vector<string>* ptr_eachvector = 0;
while(ifs && getline(ifs, buf)) {
if(buf[0] == '>'){
if (ptr_eachvector) {
vector_of_ptr_each_vector.push_back(ptr_eachvector) ;
}
ptr_eachvector = new std::vector<string>;
} else if (ptr_eachvector) {
ptr_eachvector->push_back(buf) ;
}
}
if (ptr_eachvector) {
vector_of_ptr_each_vector.push_back(ptr_eachvector) ;
}
という感じになる, かな.
いくつかの仮定ができればもうちょっと簡単になるけど....
No.4
- 回答日時:
> ですが、、そのあとイテレータを使って
> cout << *it_c << endl;
> としているのですが、何も出力されません。
何も出力されない理由としては、何も*it_cに入っていないからなのですが、
問題は、データをvectorに入れている次のコードにあります。
(問題のコード)
----------------------------------------------------------------------
15: while(ifs && getline(ifs, buf)) {
16:
17: if(buf[0] == '>'){
18: std::vector<string>* ptr_eachvector ;
19: ptr_eachvector = new std::vector<string>;
20: each_vector = *ptr_eachvector ;
21:
22: vector_of_ptr_each_vector.push_back(ptr_eachvector) ;
23: }
24:
25: each_vector.push_back(buf) ;
26: }
----------------------------------------------------------------------
vectorコンテナの特徴をよく理解して、トレースすれば、明かなのですが、
----------------------------------------------------------------------
15: while(ifs && getline(ifs, buf)) {
16:
17: if(buf[0] == '>'){
18: std::vector<string>* ptr_eachvector ;
19: ptr_eachvector = new std::vector<string>; // 空のvector<string>を作成している
20: each_vector = *ptr_eachvector ; // 空のvector<string>をeach_vector に複製している。(ここで、each_vectorは空になる)
21:
22: vector_of_ptr_each_vector.push_back(ptr_eachvector) ; // vector_of_ptr_each_vectorに空のvector<string>を追加
23: }
24:
25: each_vector.push_back(buf) ; // 空のeach_vectorにbufを追加。
26: }
----------------------------------------------------------------------
と言う感じの動作になります。
>each_vector = *ptr_eachvector ; // 空のvector<string>をeach_vector に複製している。(ここで、each_vectorは空になる)
その部分は自分でも怪しいと思っていた部分でした。
ここが問題のようですね。
each_vectorの定義とnewに関して全く理解不足だったようです。もしよろしければ 正解のコード または参考になるサイトなど教えていただけないでしょうか。
No.2
- 回答日時:
std::vector<std::vector<string> *>::iterator it_b = vector_of_ptr_each_vector.begin();
while( it_b != vector_of_ptr_each_vector.end() ) {
std::vector<string>::iterator it_c = (*it_b)->begin();
while( it_c != (*it_b)->end() ) {
cout << *it_c << endl;
++it_c;
}
++it_b;
}
具体的なコードありがとうございます。
エラーは出なくなりました。
しかし、 cout << *it_c << endl; の部分による出力がなにもされません。これはeach_vectorを作るあたりに問題があるのでしょうか???
No.1
- 回答日時:
まずは、コンパイルエラーの対応から、
// std::vector<string>::iterator it_c = it_b->begin(); //エラー1
std::vector<string>::iterator it_c = (*it_b)->begin(); //エラー1
// while( it_c != *it_b->end() ) //エラー2
while( it_c != (*it_b)->end() ) //エラー2
(*it_b) が「std::vector<string> *」
ですから、
it_b->begin()では、std::vector<string>のイテレータは取れません。
他にも、あやしいコーディングがあるような気がしますが、
各個、対応してみてください。
ありがとうございます。
(*it_b)->begin();
かっこで囲まなければいけなかったのですね。
おかげでエラーは出なくなりました。
ですが、、そのあとイテレータを使って
cout << *it_c << endl;
としているのですが、何も出力されません。
これはまた別の原因がありそうです。。。。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# このプログラミング誰か教えてください 9 2022/04/22 18:50
- C言語・C++・C# このプログラミング誰か教えてください。 2 2022/04/22 18:48
- ガスコンロ・IHクッキングヒーター・給湯器 コンテンツブロッカーについて 2 2023/05/17 09:43
- フリーソフト Vector フリーソフト 卓上カレンダー Windows10での作動は? 2 2022/06/11 19:03
- その他(言語学・言語) 「ベクトル」ってなんか抵抗ありませんか?「ヴェクトル」のほうがよくありませんか? 9 2023/01/01 10:50
- ブルーレイ・プレーヤー・レコーダー BD-REについて教えてください。 3 2022/11/10 23:28
- 画像編集・動画編集・音楽編集 PhotoScape という画像加工ソフトについて教えてください 3 2023/08/23 21:22
- C言語・C++・C# C++初心者です stirng 2 2022/09/20 20:43
- C言語・C++・C# C++プログラミングコードにポリモーフィズムを取り入れ方を教えてください。 2 2023/06/09 11:17
- 数学 面素ベクトルについて質問です 位置ベクトル r↑=(x,y,f(x,y)) とすると ds↑=(∂r 2 2023/03/21 17:17
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
空ENTERの判別
-
switch文のエラーについて
-
名前空間でビルドエラー(LNK20...
-
C++での <iostream.h>と<iostre...
-
C言語のポインターで詰まっている
-
c++で、cvMatからvectorへの変...
-
セグメンテーションフォルトが...
-
構造体に決められた文字列を入...
-
VC++で文字列から任意の文字を...
-
string型のフォーマット書式指...
-
VS2019でofstreamが未定義になる
-
2重の(?)の#include
-
指定した文字を削除したい
-
[Win + Eclipse + GCC]socketク...
-
c++のvirtual関数および継承に...
-
vectorの中にmap
-
構造体配列のvectorへの変換と...
-
なぜ、C++の標準ヘッダをインク...
-
VHDLのsignedとunsignedの違いは?
-
enumの値から定義名を文字列化...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
enumの値から定義名を文字列化...
-
VC++で文字列から任意の文字を...
-
C言語 ストリームについて。
-
switch文のエラーについて
-
string型のフォーマット書式指...
-
構文エラーが出ているのですが...
-
空ENTERの判別
-
gccでコンパイル時のエラー
-
なぜ、C++の標準ヘッダをインク...
-
リモートデスクトップの接続元I...
-
JPEGやPNGが読めるLoadImage関数
-
mapの初期化
-
snprintfが使用できない。
-
atlbase.h と afxwin.hの同時定義
-
C言語のエラーを修正したい
-
CSting を TCHAR [] に変換した...
-
#include "fstream.h"
-
構造体配列のvectorへの変換と...
-
【C++】ヘッダ内でstringを格納...
-
CStringとString
おすすめ情報