C++ : Reading file and store data in multi-vector - c++

I am trying to read data file with the this format
T1: I1,I2,I5
T2: I2,I4
T3: I2,I3
T4: I1,I2,I4
T5: I1,I3
T6: I2,I3
T7: I1,I3
T8: I1,I2,I3,I5
T9: I1,I2,I3
I don't want to read the first column T1,T2,T3 ...... , but each line will be a dataset I want to start read after (space ' ' ) and end with each line and how can I separate the data according to (comma ',')
I wrote this code but it didn't work correctly and it reads the first column anyway
string CItem;
// set of elements
set< CItem > CItemSet;
//Transactions
CItemSet CTransaction;
// set of transactions
vector< CTransaction > CTransactionSet;
ifstream inFile(inFileName);
if (!inFile)
{
cout << "Failed to open input file filename:." << inFileName;
}
CTransactionSet transSet;
CTransaction tran;
string txtLine;
// read every line from the stream
while (getline(inFile, txtLine))
{
istringstream txtStream(txtLine);
string txtElement;
// read every element from the line that is seperated by commas
// and put it into the vector or strings
while (getline(txtStream, txtElement, ','))
{
if (txtElement == ": ") break;
else tran.insert(txtElement);
}
transSet.push_back(tran);
}

Since you have
CTransaction tran;
outside the first while loop, items keep getting added to it. Move it inside the while loop.
CTransactionSet transSet;
string txtLine;
// read every line from the stream
while (getline(inFile, txtLine))
{
CTransaction tran;

I solve the problem by doing what you said R Sahu but the most important solution is by using .ignore so we don't read the part before the ' '
CTransactionSet transSet;
string txtLine;
// read every line from the stream
while (getline(inFile, txtLine))
{
istringstream txtStream(txtLine);
txtStream.ignore(txtLine.length(), ' ');
// read every element from the line that is seperated by commas
// and put it into the vector or strings
string txtElement;
CTransaction tran;
while (getline(txtStream, txtElement, ','))
{
tran.insert(txtElement);
}
transSet.push_back(tran);
}

Related

C++, write from file into map

im just new at c++ and I try to read from a file and write the content into a map<string, float>.
But only the first element of my file gets mapped and i cant figuer out why.
The file looks like this:
E:16.93
N:10.53
I:8.02
...
And the code i got for this part so far:
std::map<char, float> frequenciesM;
fstream frequencieFile("frequencies.txt", std::ios::in);
if(!frequencieFile){
cout << "No such File!";
}else{
std::string line;
char ch;
std::string sub;
float fl;
while (std::getline(frequencieFile, line, '\0')) {
ch = line[0];
sub = line.substr(2);
fl = std::stof(sub);
frequenciesM[ch] = fl;
}
}
When i try to print out the size and content of my map, this is what i get:
Size: 1
E: 16.93
Thx for any help and suggestions!
You are telling getline() to read until a '\0' (nul) character is encountered, but there is no such character in your file, so the entire file gets read into the string on the 1st call, and then you extract only the 1st set of values from the string, discarding the rest of the data.
To read the file line-by-line, you need to change the 3rd parameter of getline() to '\n' instead:
while (std::getline(frequencieFile, line, '\n'))
Or, just drop the 3rd parameter entirely since '\n' is the default delimiter:
while (std::getline(frequencieFile, line))

C++ CSV Getline

I have one column of floats in a csv file. No column header.
string val;
vector<float> array;
string file = "C:/path/test.csv";
ifstream csv(file);
if (csv.is_open())
{
string line;
getline(csv, line);
while (!csv.eof())
{
getline(csv, val, '\n');
array.push_back(stof(val));
}
csv.close();
}
I want to push the values in the column to vector array. When I use ',' as a delimiter it pushes the first line to the array but the rest of the column gets stuck together and unpushable. If I use '\n' it doesn't return the first line and I get a stof error.
I tried other answers unsuccessfully. What is the correct way to format this here?
test.csv
Your raw test.csv probably looks like this:
1.41286
1.425
1.49214
...
So there are no comma's, and using , as '(line) separator' would read the whole file and only parse the first float (up to the first \n).
Also, the first line is read but never used:
getline(csv, line); // <- first line never used
while (!csv.eof())
{
getline(csv, val, '\n');
array.push_back(stof(val));
}
Since there is only one field you don't have to use a separator and, as already mentioned in the comments, using while(getline(...)) is the right way to do this:
if (csv.is_open())
{
string line;
while (getline(..))
{
array.push_back(stof(val));
}
csv.close();
}

std::getline not producing correct output (c++)

I'm doing a homework assignment in c++ and I could use a little help. I am not understanding why the following code isn't working as I want it. The object of the function I'm creating is to load a file and parse it into keys and values for a map while skipping blank lines and lines where the first character is a hastag. The file I'm reading from is below.
The problem is that my nextToken variable is not being delimited by the '=' character. I mean, when I cout nextToken, it doesn't equal the string before the '=' character. For example, the first two lines of the data file are
# Sample configuration/initialization file
DetailedLog=1
I thought that the code I have should skip all the lines that begin with a hashtag (but it's only skipping the first line) and that nextToken would equal just DetailedLog (as opposed to DetailedLog=1 or just equal to 1).
In my output, some lines with a hashtag are skipped while some are not and I can't understand where cout is printing from since the cout statement I have should print "nextToken: " and then nextToken, but it's printing nextToken then "nextToken: " then what comes after the '=' character from the data file.
Here's my code:
bool loadFile (string filename){
ifstream forIceCream(filename);
string nextToken;
if (forIceCream.is_open()){
while (getline(forIceCream, nextToken, '=')) {
if (nextToken.empty() || nextToken[0] == '#') {
continue;
}
cout << "nextToken: " << nextToken << endl;
}
}
}
Data file reading from:
# Sample configuration/initialization file
DetailedLog=1
RunStatus=1
StatusPort=6090
StatusRefresh=10
Archive=1
LogFile=/tmp/logfile.txt
Version=0.1
ServerName=Unknown
FileServer=0
# IP addresses
PrimaryIP=192.168.0.13
SecondaryIP=192.168.0.10
# Random comment
If the first two lines of your input file are:
# Sample configuration/initialization file
DetailedLog=1
Then, the call
getline(forIceCream, nextToken, '=')
will read everything up to the first = to nextToken. At the end of the line, the value of nextToken will be:
# Sample configuration/initialization file
DetailedLog
See the documentation of std::getline and pay attention to the first overload.
You need to change your strategy for processing the contents of the file a little bit.
Read the contents of the file line by line.
Process each line as you see fit.
Here's an updated version of your function.
bool loadFile (string filename)
{
ifstream forIceCream(filename);
if (forIceCream.is_open())
{
// Read the file line by line.
string line;
while ( getline(forIceCream, line) )
{
// Discard empty lines and lines starting with #.
if (line.empty() || line[0] == '#')
{
continue;
}
// Now process the line using a istringstream.
std::istringstream str(line);
string nextToken;
if ( getline(str, nextToken, '=') )
{
cout << "nextToken: " << nextToken << endl;
}
}
}
}

Delimiter extracting out a range of data

From textfile(Range.txt),
Range:1:2:3:4:5:6....:n:
There's a list of result, but i only need to extract digit 1 2 3 to the last digit, but sometimes the last digit may varies
so i read in the file, extract out the delimiter and push it into a vector.
ifstream myfile;
myfile.open("Range.txt");
istringstream range(temp);
getline(range, line,':');
test.push_back(line);
How do i capture all the value? I have this and it only capture one digit.
I have this and it only capture one digit
You need to use a loop :-
while (getline(range, line, ':'))
test.push_back(line);
Later using the vector you can process it to get the integers only.
Plase, read that: Parsing and adding string to vector.
You just have to change the delimiter (from whitespace to :).
std::ifstream infile(filename.c_str());
std::string line;
if (infile.is_open())
{
std::cout << "Well done! File opened successfully." << std::endl;
while (std::getline(infile, line, ':'))
{
std::istringstream iss(line);
std::vector<std::string> tokens{std::istream_iterator<std::string>(iss),std::istream_iterator<std::string>()};
// Now, tokens vector stores all data.
// There is an item for each value read from the current line.
}
}

trying to read a text file data into an array to be manipulated then spit back out

My aim is to take the data from the file, split it up and place them into an array for future modification.
The is what the data looks like:
course1-Maths|course1-3215|number-3|professor-Mark
sam|scott|12|H|3.4|1/11/1991|3/15/2012
john|rummer|12|A|3|1/11/1982|7/15/2004
sammy|brown|12|C|2.4|1/11/1991|4/12/2006
end_Roster1|
I want to take maths, 3215, 3 and Mark and put into an array,
then sam scott 12 H 3.4 1/11/1991 3/15/2012.
This is what I have so far:
infile.open("file.txt", fstream::in | fstream::out | fstream::app);
while(!infile.eof())
{
while ( getline(infile, line, '-') )
{
if ( getline(infile, line, '|') )
{
r = new data;
r->setRcourse_name(line);
r->setRcourse_code(3);//error not a string
r->setRcredit(3);//error not a string pre filled
r->setRinstructor(line);
cout << line << endl;
}
}
}
Then I tried to view it nothing is stored.
Firstly line 1 is very different to the remaining lines so you need a different parsing algorithm for them. Something like:
bool first = true;
while(!infile.eof())
{
if (first)
{
// read header line
first = false;
}
else
{
// read lines 2..n
}
}
Reading lines 2..n can be handled by making a stringstream for each line, then passing that in to another getline using '|' as a delimeter, to get each token (sam, scott, 12, H, 3.4, 1/11/1991, 3/15/2012)
if (getline(infile, line, '\n'))
{
stringstream ssline(line);
string token;
while (getline(ssline, token, '|'))
vector.push_back(token);
}
Reading the header line takes the exact same concept one step further where each token is then further parsed with another getline with '-' as a delimiter. You'll ignore each time the first tokens (course1, course1, number, professor) and use the second tokens (Maths, 3215, 3, Mark).
You are completely ignoring the line that you get inside the condition of the nested while loop. You should call getline from a single spot in your while loop, and then examine its content using a sequence of if-then-else conditions.