Parse from a file, where one of the columns has multiple value - c++

I'm trying to load the information from a text file into a vector. However, one of the columns has multiple values in it, and I'm having problem trying to retrieve the information from there. Below is my snippet code.
The text file will have format like this:
First column will be the name, and second column will be all the classes that he is taking right now. For the second column, I create a vector to hold it, but I don't know how to do a while loop condition for it. Can anyone help me please ?
mtingley |art, music, math, history
while(getline(inUsers, textLine))
{
Student s;
string delimeter;
// put the line into buffer string
istringstream textStream(textLine);
// get userName
textStream >> userName;
// read the buffer string till '|'
getline(textStream, delimeter, '|');
cout << userName << endl;
s.SetUserName(userName);
while() // need condition in this while loop
{
textStream >> subject;
getline(textStream, delimeter, ',');
vCourse.push_back(subject);
}
}

There is a good example here: http://www.daniweb.com/software-development/cpp/threads/53349/getline-with-multiple-delimiters

Related

C++ retrieve numerical values in a line of string

Here is the content of txt file that i've managed read.
X-axis=0-9
y-axis=0-9
location.txt
temp.txt
I'm not sure whether if its possible but after reading the contents of this txt file i'm trying to store just the x and y axis range into 2 variables so that i'll be able to use it for later functions. Any suggestion? And do i need to use vectors? Here is the code for reading of the file.
string configName;
ifstream inFile;
do {
cout << "Please enter config filename: ";
cin >> configName;
inFile.open(configName);
if (inFile.fail()){
cerr << "Error finding file, please re-enter again." << endl;
}
} while (inFile.fail());
string content;
string tempStr;
while (getline(inFile, content)){
if (content[0] && content[1] == '/') continue;
cout << endl << content << endl;
depends on the style of your file, if you are always sure that the style will remain unchanged, u can read the file character by character and implement pattern recognition stuff like
if (tempstr == "y-axis=")
and then convert the appropriate substring to integer using functions like
std::stoi
and store it
I'm going to assume you already have the whole contents of the .txt file in a single string somewhere. In that case, your next task should be to split the string. Personally, yes, I would recommend using vectors. Say you wanted to split that string by newlines. A function like this:
#include <string>
#include <vector>
std::vector<std::string> split(std::string str)
{
std::vector<std::string> ret;
int cur_pos = 0;
int next_delim = str.find("\n");
while (next_delim != -1) {
ret.push_back(str.substr(cur_pos, next_delim - cur_pos));
cur_pos = next_delim + 1;
next_delim = str.find("\n", cur_pos);
}
return ret;
}
Will split an input string by newlines. From there, you can begin parsing the strings in that vector. They key functions you'll want to look at are std::string's substr() and find() methods. A quick google search should get you to the relevant documentation, but here you are, just in case:
http://www.cplusplus.com/reference/string/string/substr/
http://www.cplusplus.com/reference/string/string/find/
Now, say you have the string "X-axis=0-9" in vec[0]. Then, what you can do is do a find for = and then get the substrings before and after that index. The stuff before will be "X-axis" and the stuff after will be "0-9". This will allow you to figure that the "0-9" should be ascribed to whatever "X-axis" is. From there, I think you can figure it out, but I hope this gives you a good idea as to where to start!
std::string::find() can be used to search for a character in a string;
std::string::substr() can be used to extract part of a string into another new sub-string;
std::atoi() can be used to convert a string into an integer.
So then, these three functions will allow you to do some processing on content, specifically: (1) search content for the start/stop delimiters of the first value (= and -) and the second value (- and string::npos), (2) extract them into temporary sub-strings, and then (3) convert the sub-strings to ints. Which is what you want.

Reading In Formatted Data with Multiple Delimiters C++

I'm trying to read in data from command prompt with multiple delimiters, for example:
data 1, data2, data3.
I'd like the code to read in the data before the first comma, the data after that and before the second comma, and finally the data after that but before the period. I have been using this:
getline(cin, VAR, ',');
cin.get();
getline(cin, VAR2, ' ');
getline(cin, VAR3, ',');
cin.get();
getline(cin, VAR4, '.');
And it does what I want, provided the information is entered correctly. However, how can I check and see if the information wasn't? Because if the user doesn't enter two commas and a period, the program gets stuck as I'm assuming the cin stream gets broken after not finding the delimiter as specified in the getline() read. I've tried this:
if (cin.fail()) {
cout << "failure" << endl;
}
After a getline, but it never runs if the delimiter isn't input. What's the best way to do this, check for errors and see if data wasn't entered in the desired format?
You have to parse the input yourself.
For starters, your input does not consist of "data with multiple delimiters". Your input consists of a single line of text, that was entered, according to your description, at a command prompt of some kind.
If so, then the line of text should be read with a single std::getline() library function, since, by default, std::getline() uses \n as a default delimiter.
std::string str;
std::getline(std::cin, str);
Now, you've read your input into str. Now that this task is complete you can get down to business verifying whether str contains properly formatted input with the appropriate delimiters, or not.
To do that, you will use the rich set of methods that are available from your std::string object. For example one such method, find(), searches the string for a particular character, such as your first comma:
auto n=str.find(',');
The full documentation for find(), whose description you will find in your C++ book, will explain how to determine whether find() actually found the comma, or not. Based on that your program can either take the appropriate action (if the comma was not found) or use the substr() method, on this str, to extract the part of the string before the comma. That would be your first VAR. Then, use substr() again to extract the rest of the entered text, after the first comma.
You will also find a complete description of substr() in your C++ book.
After using substr() to extract the rest of the entered text, after the first comma, you will simply repeat the same overall process for extracting data2, and the following item of input, this time using a period.
And, at each step of the way you will have all the information your program will need to determine whether or not your input was formatted correctly.
You could read in the entire line into a std::string, then use std::istringstream to parse the string:
#include <iostream>
#include <string>
#include <sstream>
#include <cstdlib>
int main(void)
{
const std::string input_text = "data1, data2, data3\n";
std::istringstream input_stream(input_text);
std::string data1;
std::string data2;
std::string data3;
std::getline(input_stream, data1, ',');
std::getline(input_stream, data2, ',');
std::getline(input_stream, data3, ',');
std::cout << "data1: " << data1 << '\n';
std::cout << "data2: " << data2 << '\n';
std::cout << "data3: " << data3 << '\n';
return EXIT_SUCCESS;
}
If the std::getline fails, that means there is an error in the data.

(C++) - Associating strings with values read in from a file

I am trying to get a value associate with a string inside a file called invoice1.txt
invoice1.txt
hammer#10.00
saw#20.00
So for example, when I lookup "hammer" I would like the expression to evaluate to 10.00.
My code so far
string search;
ifstream inFile;
string line;
double price;
inFile.open("invoice1.txt");
if(!inFile)
{
cout << "Unable to open file" << endl;
return 0;
}
else
{
int pos;
while(inFile.good())
{
getline(inFile,line);
pos=line.find(search);
if(pos!=string::npos)
{
cout<<"The item "<<search<<" costs: "// code to get the price
}
}
}
system("pause");
This is the output I am aiming for:
The item hammer costs: 10.00
The summerise, my question is:
How can I associate values with one another that are read in from a file, so I can get a price for an item without having to reparse the file and find it again?
This is what std::map is for.
What you want to do is break your problem down into multiple stages. Here is a simple set of steps that should help you (there are better ways, but I'm trying to keep things simple here).
I've added some lines to explain how to use std::map, in case you're not familiar.
Read the file line by line.
For each line that is read in, get the value after the '#' character.
Add the value to the map, using the string before '#' as the key...
priceMap[key] = price; // for example, this might evaluate to: myMap["hammer"] = 10.00
When you want to use the value, simple give the map you're key.
std::cout << priceMap["hammer"];
What do you search in line from file? You have to search for character # and split your string into two parts.
getline(inFile,line);
pos=line.find('#');
if(pos!=string::npos)
cout<<"The item "<<line.substr(0,pos)<<" costs: " << line.substr(pos+1,line.size()-1) << endl;// code to get the price
You can save item name and price in different variables if you want. If you want to do something more with a string, read this for further instructions.

How can I separate user inputted string and store it into an array

I was wondering if you could help me and figure this out without using something like strtok. This assignment is meant for me to build something that will accept input and direct the user to the right area. I want to get something like....
Help Copy
and it stores it as
array[1] = Help
array[2] = Copy.
I tried to do something like cin>>arr[1]; and cin>>arr[2] but at the same time what if the user enters copy then I am not sure how to do it cause if I put just one cin then what if the user puts help copy.
Basically I am not sure how to accept any size input and store anything they put in as elements in an array.
I would try something like cin.get or getline but they don't seem to really help me and my cin idea was not helpful at all.
This is what I have so far.
int main()
{
string user;
cout<<"Hello there, what is your desired username?"<<endl;
cin >> user;
system("cls");
cout<<"Hello, " << user << "! How are you doing?"<<endl<<endl;
cout<< user << ": ";
return 0;
}
You can do it like this:
Read the entire line using getline
Make an input string stream from that line
Read the content of that string stream into a vector<string>. It will grow automatically to accommodate as many inputs as the user enters
Examine the size of the resultant vector to see how many entries the end-user made
Here is how you can do it in code:
// Prepare the buffer for the line the user enters
string buf;
// This buffer will grow automatically to accommodate the entire line
getline(cin, buf);
// Make a string-based stream from the line entered by the user
istringstream iss(buf);
// Prepare a vector of strings to split the input
vector<string> vs;
// We could use a loop, but using an iterator is more idiomatic to C++
istream_iterator<string> iit(iss);
// back_inserter will add the items one by one to the vector vs
copy(iit, istream_iterator<string>(), back_inserter(vs));
Here is a demo on ideone.
std::vector<std::string> myInputs;
std::cout << "Enter parameters: ";
std::copy(std::istream_iterator<std::string>(std::cin), std::isteram_iterator<std::string>(), std::back_inserter(myInputs));
// do something with the values in myInputs
If the user presses Enter in between each input, this will go until they cease the input (Crtl-D on Windows). If you want them to put all the parameters on a single line, you can read the input into a single string and then split the string up by spaces (or whatever delimiter you wish to use).

search for specific row c++ tab delmited

AccountNumber Type Amount
15 checking 52.42
23 savings 51.51
11 checking 12.21
is my tab delmited file
i would like to be able to search for rows by the account number. say if i put in 23, i want to get that specific row. how would id do that?
also more advance, if i wanted to change a specific value, say amount 51.51 in account 23. how do i fetch that value and replace it with a new value?
so far im just reading in row by row
string line;
ifstream is("account.txt");
if (is.is_open())
{
while (std::getline(is, line)) // read one line at a time
{
string value;
string parseline;
std::istringstream iss(line);
getline(line, parseline);
cout << parseline << endl; // do something with the value
while (iss >> value) // read one value at at time from the line
{
//cout << line << " "; // do something with the value
}
}
is.close();
}
else
cout << "File cant be opened" << endl;
return 0;
Given that each line is of variable length there is no way to index to particular row without first parsing the entire file.
But I suspect your program will want to manipulate random rows and columns. So I'd start by parsing out the entire file. Put each row into its own data structure in an array, then index that row in the array.
You can use "strtok" to split the input up into rows, and then strtok again to split each row into fields.
If I were to do this, I would first write a few functions that parse the entire file and store the data in an appropriate data structure (such as an array or std::map). Then I would use the data structure for the required operations (such as searching or editing). Finally, I would write the data structure back to a file if there are any modifications.