Comment lire les données d'un fichier si mon fichier est comme ça 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 réécrire les données dans un autre fichier au même format que 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 ligne/ligne ??
J'ai également un vecteur d'entiers pour stocker les données. Donc, je veux lire la première ligne, puis compter le nombre total d'éléments dans cette ligne, ici 5 (1,2,3,4,5) et les stocker dans le tableau/vecteur, et lire la ligne suivante et les stocker dans le vecteur encore et ainsi de suite jusqu'à ce que j'atteigne l'EOF.
Ensuite, je veux écrire les données dans un fichier, encore une fois, je suppose que cela fera le travail d'écrire 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 du fichier avec des valeurs séparées par des virgules ??
Merci
Étape 1: ne faites pas cela:
while(!file.eof())
{
getline(file,line);
numlines++;
}
numline--;
Le EOF n'est pas vrai tant que vous n'avez pas essayé de le lire. Le modèle standard est:
while(getline(file,line))
{
++numline;
}
Notez également que std::getline()
peut éventuellement prendre un troisième paramètre. C'est le personnage sur lequel se briser. Par défaut, c'est le terminateur 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 à l'aide d'une largeur fixe. Ensuite, 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));
}
ici, je publie le code pour lire et écrire du code CSV. J'ai vérifié son bon fonctionnement.
#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");
}
Essayez la classe stringstream :
#include <sstream>
Au cas où, recherchez l'exemple de la page 641 de "The C++ Programming Language Special Edition" de Stroustrup.
Cela fonctionne pour moi et j'ai eu beaucoup de temps à essayer de comprendre celui-ci.