2011-10-30 43 views
2

私のCMPTクラスのラボ割り当てに問題があります... 2つの単語と1つの文字列を持つテキストファイルを読み込もうとしています1行につき番号を付けることができます。ファイルは誰でも作成できます。C++の構造体に単語ごとに.txtファイルを読み込む

の例では、私は、各行別の「学生」を行う必要があり

Xiao Wang 135798642 
Lucie Chan 122344566 
Rich Morlan 123456789 
Amir Khan 975312468 
Pierre Guertin 533665789 
Marie Tye 987654321 

あるので、私はそうするように構造体を使用して考えていたが、私は私が必要とすることを行う方法がわかりません最初と最後とID番号は別々にする必要があります。

struct Student{ 
    string firstName; 
    string secondName; 
    string idNumber; 
}; 

個別に各単語を読み込むために行わ試行のすべてが失敗した(全体ではなく、ラインを読み終わった)と私は穏やかに不満を取得しています。

@Sylenceの助けを借りて、私は各行ごとに別々に読むことができました。私はまだ空白で行を分割する方法と混同されています。 ifstreamに分割機能はありますか? シリレンス、 'パーツ'は配列になりますか?あなたが[]でインデックスを持っているのを見ました。 students.add(stud)はどういうことをしていますか? 私のコードは、これまでのところです:

int getFileInfo() 
{ 
    Student stdnt; 
    ifstream stdntFile; 
    string fileName; 
    char buffer[256]; 
    cout<<"Please enter the filename of the file"; 
    cin>>filename; 
    stdntFile.open(fileName.c_str()); 
    while(!stdFile.eof()) 
    { 
     stdFile.getLine(buffer,100); 
    } 
    return 0; 
} 

このgetFileInfoの私の修正と最終版()、データを読み込むための簡単かつ迅速な方法のために、Shahbazあなたに感謝です。

void getFileInfo() 
{ 
    int failed=0; 
    ifstream fin; 
    string fileName; 
    vector<Student> students; // A place to store the list of students 

Student s;     // A place to store data of one student 
cout<<"Please enter the filename of the student grades (ex. filename_1.txt)."<<endl; 
do{ 
    if(failed>=1) 
     cout<<"Please enter a correct filename."<<endl; 
    cin>>fileName; 
fin.open(fileName.c_str());// Open the file 
failed++; 
}while(!fin.good()); 
while (fin >> s.firstName >> s.lastName >> s.stdNumber) 
    students.push_back(s); 
fin.close(); 
cout<<students.max_size()<<endl<< students.size()<<endl<<students.capacity()<<endl; 


return; 
} 

ここで混乱しているのは、入力されたデータにアクセスする方法です。私はそれがベクターに入れられたことは知っていますが、ベクトルの個々のスペースにアクセスするにはどうすればいいのですか? Visual Studioが何を出力するかわからないので、ベクトルの場所を調べようとするとエラーが発生します。

+0

申し訳ありませんが、txtファイルへのリンクが機能しませんでした。 – b3orion

+4

あなたは何をしようとしましたか?一緒にお手伝いできるよう努力してください。 – Bart

+0

申し訳ありません..クイック返信いただきありがとうございます。私はこれまでのことを喜んで紹介しますが、このコメントボックスにコードの書式を設定する方法を理解することはできません。私はちょうどそれのまわりにアポストロフィや[コード]か何かを置くのですか?無能になって申し訳ありません。 – b3orion

答えて

2

他の回答は良いですが、少し複雑に見えます。あなたは、するだけでそれを行うことができます:istreamが失敗した場合、そのようなファイルが終了したときのように、istreamオブジェクト(fin)はfalseに評価すること

vector<Student> students; // A place to store the list of students 

Student s;     // A place to store data of one student 

ifstream fin("filename"); // Open the file 

while (fin >> s.firstName >> s.secondName >> s.idNumber) 
    students.push_back(s); 

注意を。したがって、ファイルが終了するとwhile (fin >> ....)が停止します。

P.S.ファイルが開かれているかどうかを確認することを忘れないでください。

+0

ファイル内の行のリスト全体についてこれを繰り返すにはどうすればいいでしょうか?そして、繰り返しごとに新しい生徒の構造体を作る方法を教えてください。 ? – b3orion

+0

ニースのソリューション:) @ b3orionあなたが与えたデータのコピーをベクトルが使用するので、各繰り返しのために新しいオブジェクトを作成する必要はありません。 – Sylence

+0

さて、毎回新しい生徒を作る必要はありませんが、ループの場合はwhileループを使用しますか?私はちょうど各繰り返しを使用する行をどのように伝えるのか混乱しています。現在のように、ループなしでは、ファイルの最後の行だけが読み込まれます。 – b3orion

0

単純に行全体を読み取ってから、文字列をスペースに分割して値を割り当てます構造体のオブジェクトに追加します。

擬似コード:

while(!eof) 
    line = readline() 
    parts = line.split(' ') 

    Student stud = new Student() 
    stud.firstName = parts[0] 
    stud.secondName = parts[1] 
    stud.idNumber = parts[2] 

    students.add(stud)  
end while 
+0

これは実際にはすべて間違っています(非常に多くの点で)。修正してください、または私はdownvoteします。 –

+1

私は '擬似コード'を書いた理由があります... – Sylence

+0

私は疑似コードに問題はありません。しかし、いくつかの重要なルールを破っています。 1)しばらくの間、eofをテストしないでください(すべての言語に適用されます(EOFが過去のEOFを読み取るまで発生しないため、余分な時間が入力されます)。 C++の質問に答える。 3)スペースで分割することは、多くの言語でOKですが、実際にC++で間違ったパスを導きます。 –

1

学生のためのストリームリーダー定義:今、あなたはファイルを含め、任意のストリームからオブジェクトをストリームすることができるはず

std::istream& operator>>(std::istream& stream, Student& data) 
{ 
    std::string line; 
    std::getline(stream, line); 

    std::stringstream linestream(line); 
    linestream >> data.firstName >> data.secondName >> data.idNumber; 

    return stream; 
} 

を:

int main() 
{ 
    std::ifstream file("data"); 
    Student   student1; 

    file >> student1; // Read 1 student; 

    // Or Copy a file of students into a vector 
    std::vector<Student> studentVector; 
    std::copy(std::istream_iterator<Student>(file), 
       std::istream_iterator<Student>(), 
       std::back_inserter(studentVector) 
      ); 
} 
+0

これはどのように機能しますか?コードにいくつかのコメントを追加できますか? – b3orion

+0

これは宿題なので、あなたが自分のために細部を明らかにした方が良いと思います。この情報を@Shahbazの回答と組み合わせると、必要なすべての詳細が得られるはずです。 –

+0

しかし、@ShahbazというコードはすでにStudentに読み込まれたテキストを入力していませんか?なぜ私はストリームリーダーが必要ですか?私はどのようにstrcutの各学生にアクセスするかについて混乱している。どのように個々の生徒を選択してベクターに入れたらいいですか... – b3orion

関連する問題