2011-12-03 6 views
20

Sto provando a leggere ogni riga di un file di testo che ogni riga contiene una parola e mettere quelle parole in un vettore. Come potrei fare per farlo?Lettura linea da file di testo e mettere le stringhe in un vettore?

Questo è il mio nuovo codice: penso che ci sia ancora qualcosa di sbagliato in questo.

#include <iostream> 
#include <fstream> 
#include <string> 
#include <vector> 
using namespace std; 

int main() 
{ 
    std::string line; 
    vector<string> DataArray; 
    vector<string> QueryArray; 
    ifstream myfile("OHenry.txt"); 
    ifstream qfile("queries.txt"); 

    if(!myfile) //Always test the file open. 
    { 
     cout<<"Error opening output file"<<endl; 
     system("pause"); 
     return -1; 
    } 
    while (std::getline(qfile, line)) 
    { 
     QueryArray.push_back(line); 
    } 
    if(!qfile) //Always test the file open. 
    { 
     cout<<"Error opening output file"<<endl; 
     system("pause"); 
     return -1; 
    } 

    while (std::getline(qfile, line)) 
    { 
     QueryArray.push_back(line); 
    } 

    cout<<QueryArray[0]<<endl; 
    cout<<DataArray[0]<<endl; 

} 
+2

Qual è il problema con il codice finora? – Mahesh

+0

@Mahesh questo * if (! Myfile) * potrebbe essere il primo problema. (Mi dispiace .. ho bisogno di imparare STL.) – Beginner

+0

@RomanB: Non c'è niente di sbagliato in questa linea. – Puppy

risposta

29

@FailedDev ha, infatti, elencato la forma più semplice. In alternativa, ecco come spesso codice che loop:

std::vector<std::string> myLines; 
std::copy(std::istream_iterator<std::string>(myfile), 
      std::istream_iterator<std::string>(), 
      std::back_inserter(myLines)); 

L'intero programma potrebbe assomigliare a questo:

versione
// Avoid "using namespace std;" at all costs. Prefer typing out "std::" 
// in front of each identifier, but "using std::NAME" isn't (very) dangerous. 
#include <iostream> 
using std::cout; 
using std::cin; 
#include <fstream> 
using std::ifstream; 
#include <string> 
using std::string; 
#include <vector> 
using std::vector; 
#include <iterator> 
using std::istream_iterator; 
#include <algorithm> 
using std::copy; 

int main() 
{ 

    // Store the words from the two files into these two vectors 
    vector<string> DataArray; 
    vector<string> QueryArray; 

    // Create two input streams, opening the named files in the process. 
    // You only need to check for failure if you want to distinguish 
    // between "no file" and "empty file". In this example, the two 
    // situations are equivalent. 
    ifstream myfile("OHenry.txt"); 
    ifstream qfile("queries.txt"); 

    // std::copy(InputIt first, InputIt last, OutputIt out) copies all 
    // of the data in the range [first, last) to the output iterator "out" 
    // istream_iterator() is an input iterator that reads items from the 
    // named file stream 
    // back_inserter() returns an interator that performs "push_back" 
    // on the named vector. 
    copy(istream_iterator<string>(myfile), 
     istream_iterator<string>(), 
     back_inserter(DataArray)); 
    copy(istream_iterator<string>(qfile), 
     istream_iterator<string>(), 
     back_inserter(QueryArray)); 

    try { 
     // use ".at()" and catch the resulting exception if there is any 
     // chance that the index is bogus. Since we are reading external files, 
     // there is every chance that the index is bogus. 
     cout<<QueryArray.at(20)<<"\n"; 
     cout<<DataArray.at(12)<<"\n"; 
    } catch(...) { 
     // deal with error here. Maybe: 
     // the input file doesn't exist 
     // the ifstream creation failed for some other reason 
     // the string reads didn't work 
     cout << "Data Unavailable\n"; 
    } 
} 
+0

cosa include e namespace ho bisogno? – user977154

+1

dolce ha funzionato. Grazie mille. Questo è sicuramente molto più semplice e pulito. – user977154

+0

@ user977154 vedi l'esempio completo sopra –

28

forma più semplice:

std::string line; 
std::vector<std::string> myLines; 
while (std::getline(myfile, line)) 
{ 
    myLines.push_back(line); 
} 

Non c'è bisogno di thingies c folle :)

Edit:

#include <iostream> 
#include <fstream> 
#include <string> 
#include <vector> 

int main() 

{ 
    std::string line; 
    std::vector<std::string> DataArray; 
    std::vector<std::string> QueryArray; 
    std::ifstream myfile("OHenry.txt"); 
    std::ifstream qfile("queries.txt"); 

    if(!myfile) //Always test the file open. 
    { 
     std::cout<<"Error opening output file"<< std::endl; 
     system("pause"); 
     return -1; 
    } 
    while (std::getline(myfile, line)) 
    { 
     DataArray.push_back(line); 
    } 

    if(!qfile) //Always test the file open. 
    { 
     std::cout<<"Error opening output file"<<std::endl; 
     system("pause"); 
     return -1; 
    } 

    while (std::getline(qfile, line)) 
    { 
     QueryArray.push_back(line); 
    } 

    std::cout<<QueryArray[20]<<std::endl; 
    std::cout<<DataArray[12]<<std::endl; 
    return 0; 
} 

parola chiave utilizzando è illegale C++! Non usarlo mai. ok? Buono. Ora confronta ciò che ho scritto con ciò che hai scritto e cerca di scoprire le differenze. Se hai ancora domande torna.

+0

Ho corretto il codice nel mio post, cosa sto facendo di sbagliato ora? perché ho bisogno di lavorare con due file di testo diversi. Grazie mille per l'aiuto, a proposito. – user977154

+0

@ user977154 Non è necessario il ciclo while esterno. Rimuoverla! In entrambi i casi. Sei sicuro che esistano 12 e 20 linee nei tuoi vettori? – FailedDev

+0

Sì, sono positivo, ci sono più di 20 righe piene nei miei file di test. E continuo a ricevere errore dicendo errore aprendo il file di output – user977154

16

più semplice:

std::vector<std::string> lines; 
for (std::string line; std::getline(ifs, line); /**/) 
    lines.push_back(line); 

sto omettendo il include e altro gunk. La mia versione è quasi la stessa di FailedDev ma usando un ciclo 'for' ho inserito la dichiarazione di 'line' nel ciclo. Questo non è solo un trucco per ridurre il numero di linee. Questo riduce l'ambito della linea - scompare dopo il ciclo for. Tutte le variabili dovrebbero avere il più piccolo ambito possibile, quindi quindi è meglio. Per i loop sono fantastici.

+0

Eccellente. È ancora più pulito con 'using namespace std;' così tutto lo 'std ::' può essere rimosso. Manca la dichiarazione "if", dichiarata come: "ifstream ifs (textFilePath, ios :: in);" –