2009-09-25 14 views
16

Comment puis-je lire les données à partir d'un fichier si mon dossier est comme celui-ci avec des valeurs séparées par des virgulesComment lire-écrire dans/à partir du fichier texte avec des valeurs séparées par des virgules

1, 2, 3, 4, 5\n 
6, 7, 8, 9, 10\n 
\n 

et après avoir lu le fichier, je veux pour écrire les données dans un autre fichier comme le même format ci-dessus.

Je peux obtenir le nombre total de lignes, en utilisant

string line; 
while(!file.eof()){ 
     getline(file,line); 
     numlines++; 
    } 
    numline--; // remove the last empty line 

mais comment puis-je savoir le nombre total de chiffres dans une rangée/ligne ?? J'ai aussi un vecteur d'ints pour stocker les données. Donc, je veux lire la première ligne et ensuite compter le nombre total d'éléments dans cette ligne, ici 5 (1,2,3,4,5) et les stocker dans array/vector, et lire la ligne suivante et les stocker dans vecteur encore et ainsi de suite jusqu'à ce que j'atteigne EOF.

Ensuite, je veux écrire les données dans un fichier, encore une fois, je suppose que cela fera le travail d'écriture des données dans un fichier,

numOfCols=1; 
for(int i = 0; i < vector.size(); i++) 
{ 
    file << vector.at(i); 
    if((numOfCols<5) file << ",";//print comma (,) 
    if((i+1)%5==0) 
    { 
        file << endl;//print newline after 5th value 
        numOfCols=1;//start from column 1 again, for the next line 
    } 
    numOfCols++; 
} 
file << endl;// last new line 

Donc, mon principal problème est de savoir comment lire les données à partir du fichier avec des valeurs séparées par des virgules ??

Merci

Répondre

24

Étape 1: Ne faites pas ceci:

while(!file.eof()) 
{ 
    getline(file,line); 
    numlines++; 
} 
numline--; 

Le EOF n'est pas vrai jusqu'à ce que vous essayez de lire devant elle. Le modèle standard est la suivante:

while(getline(file,line)) 
{ 
    ++numline; 
} 

Notez également que std :: getline() peut éventuellement prendre un troisième paramètre. C'est le personnage à percer. Par défaut, il s'agit de la terminaison de ligne, mais vous pouvez spécifier une virgule.

while(getline(file,line)) 
{ 
    std::stringstream linestream(line); 
    std::string   value; 

    while(getline(linestream,value,',')) 
    { 
     std::cout << "Value(" << value << ")\n"; 
    } 
    std::cout << "Line Finished" << std::endl; 

} 

Si vous stockez toutes les valeurs dans un seul vecteur, imprimez-les en utilisant une largeur fixe. Alors je ferais quelque chose comme ça.

struct LineWriter 
{ 
     LineWriter(std::ostream& str,int size) 
       :m_str(str) 
       ,m_size(size) 
       ,m_current(0) 
     {} 

     // The std::copy() does assignement to an iterator. 
     // This looks like this (*result) = <value>; 
     // So overide the operator * and the operator = to 
     LineWriter& operator*() {return *this;} 
     void operator=(int val) 
     { 
       ++m_current; 
       m_str << val << (((m_current % m_size) == 0)?"\n":","); 
     } 

     // std::copy() increments the iterator. But this is not usfull here 
     // so just implement too empty methods to handle the increment. 
     void operator++()  {} 
     void operator++(int) {} 

     // Local data. 
     std::ostream&   m_str; 
     int const    m_size; 
     int      m_current; 
}; 

void printCommaSepFixedSizeLinesFromVector(std::vector const& data,int linesize) 
{ 
    std::copy(data.begin(),data.end(),LineWriter(std::cout,linesize)); 
} 
+0

Qu'est-ce que cela fait? std :: stringstream lignestream (ligne); – Curious

+0

Il crée un objet de flux de chaîne. Il agit comme un flux, comme std :: cin, std :: cout ou un flux de fichier std :: fstream, mais utilise une chaîne comme source des données. Donc, en effet, c'est un flux d'une seule ligne. –

+0

Lorsque j'essaie de compiler, j'obtiens cette erreur, la variable 'std :: stringstream linestream 'a un initialiseur mais un type incomplet. J'ai inclus tous les en-têtes requis. – Curious

0

Essayez la stringstream Classe:

#include <sstream> 

Juste au cas où, consultez la rubrique "Le C++ Programming Language Special Edition" de la page 641 Stroustrup exemple.

Cela fonctionne pour moi et j'ai eu un sacré temps à essayer de comprendre celui-ci.

5

Ici, je poste le code pour la lecture CSV ainsi que le code d'écriture. J'ai vérifié son fonctionnement bien.

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

void readCSV(istream &input, vector< vector<string> > &output) 
{ 
    string csvLine; 
    // read every line from the stream 
    while(getline(input, csvLine)) 
    { 
      istringstream csvStream(csvLine); 
      vector<string> csvColumn; 
      string csvElement; 
      // read every element from the line that is seperated by commas 
      // and put it into the vector or strings 
      while(getline(csvStream, csvElement, ',')) 
      { 
        csvColumn.push_back(csvElement); 
      } 
      output.push_back(csvColumn); 
    } 
} 

int main() 
{ 
    ofstream myfile; 
    string a; 
    fstream file("b.csv", ios::in); 
    myfile.open ("ab.csv"); 
    if(!file.is_open()) 
    { 
      cout << "File not found!\n"; 
      return 1; 
    } 
    // typedef to save typing for the following object 
    typedef vector< vector<string> > csvVector; 
    csvVector csvData; 

    readCSV(file, csvData); 
    // print out read data to prove reading worked 
    for(csvVector::iterator i = csvData.begin(); i != csvData.end(); ++i) 
    { 
      for(vector<string>::iterator j = i->begin(); j != i->end(); ++j) 
      { 
      a=*j; 
        cout << a << " "; 
      myfile <<a<<","; 

} 
myfile <<"\n"; 
cout << "\n"; 
} 
myfile.close(); 
system("pause"); 

} 
Questions connexes