need help with C++ using maps to keep track of words in a INPUT file - c++

Let say i have a text file with
today is today but
tomorrow is today tomorrow
then using maps how can i keep track of the words that are repeated? and on which line it repeats?
so far i have each string in the file read in as a temp and it is stored in the following way:
map<string,int> storage;
int count = 1 // for the first line of the file
if(infile.is_open()){
while( !infile.eof() ){
getline(in, line);
istringstream my_string(line);
while(my_string.good()){
string temp;
my_string >> temp;
storage[temp] = count
}
count++;// so that every string read in the next line will be recorded as that line.
}
}
map<string,int>::iterator m;
for(int m = storage.begin(); m!= storage.end(); m++){
out<<m->first<<": "<<"line "<<m->second<<endl;
}
right now the output is just
but: line 1
is: line 2
today: line 2
tomorrow: line 2
But instead..
it should print out(no repeating strings):
today : line 1 occurred 2 times, line 2 occurred 1 time.
is: line 1 occurred 1 time, line 2 occurred 1 time.
but: line 1 occurred 1 time.
tomorrow: line 2 occurred 2 times.
Note: the order of the string does not matter.
Any help would be appreciated. Thanks.

map stores a (key, value) pair with a unique key. Meaning that if you assign to the same key more than once, only the last value that you assigned will be stored.
Sounds like what you want to do is instead of storing the line as the value, you want to store another map of lines->occurances.
So you could make your map like this:
typedef int LineNumber;
typedef int WordHits;
typedef map< LineNumber, WordHits> LineHitsMap;
typedef map< string, LineHitsMap > WordHitsMap;
WordHitsMap storage;
Then to insert:
WordHitsMap::iterator wordIt = storage.find(temp);
if(wordIt != storage.end())
{
LineHitsMap::iterator lineIt = (*wordIt).second.find(count);
if(lineIt != (*wordIt).second.end())
{
(*lineIt).second++;
}
else
{
(*wordIt).second[count] = 1;
}
}
else
{
LineHitsMap lineHitsMap;
lineHitsMap[count] = 1;
storage[temp] = lineHitsMap;
}

you're trying to get 2 items of information out of the collection, when you only store 1 item of information in there.
The easiest way to extend your current implementation is to store a struct instead of an int.
So instead of:
storage[temp] = count
you'd do:
storage[temp].linenumber = count;
storage[temp].wordcount++;
where the map is defined:
struct worddata { int linenumber; int wordcount; };
std::map<string, worddata> storage;
print the results using:
out << m->first << ": " << "line " << m->second.linenumber << " count: " << m->second.wordcount << endl;
edit: use a typedef for the definitions, eg:
typedef MYMAP std::map<std::string, struct worddata>;
MYMAP storage;
then MYMAP::iterator iter;

Your storage data type is insufficient to store all the information you want to report. You could get there by using a vector for count storage but you'd have to do a lot of book-keeping to make sure you actually insert a 0 when a word is not encountered and create the vector with the right size when a new word is encountered. Not a trivial task.
You could switch your count part to a map of numbers, first being line and second being count... That would reduce the complexity of your code but wouldn't exactly be the most efficient method.
At any rate, you can't do what you need to do with just a std::map
Edit: just thought of an alternative version that would be easier to generate but harder to report with: std::vector< std::map<std::string, unsigned int> >. For each new line in a file you'd generate a new map<string,int> and push it onto the vector. You could create a helper type set<string> to contain all the words that appear in a file to use in your reporting.
That's probably how I'd do it anyway except I'd encapsulate all that crap in a class so that I'd just do something like:
my_counter.word_appearance(word,line_no);

Apart from anything else, your loops are all wrong. You should never loop on the eof or good flags, but on the success of the read operation. You want something like:
while( getline(in, line) ){
istringstream my_string(line);
string temp;
while(my_string >> temp ){
// do something with temp
}
}

Related

find map c++ is not finding key already added in the map

The map cidades starts empty.
Consider the txt file as:
" city1, city2 "
It should add the city with a random number, which is count, when the city is not in the map
Here is the code:
int i,cont = 0; // i is used as a flag and count do add a key reference when I add a new element in the map
string line; // used to get everything untill the comma
map<string,int> cidades; // map of cities and their references .. like cidades<"Silicon Valley", 1>
ifstream arquivoTexto ("text.txt");
if (arquivoTexto.is_open()) { // open file
while (getline (arquivoTexto,line)){ // while EOF is false
stringstream element(line); i = 1; // i is always 1 when checking a new line
while(getline(element, line, ',')){ // line is the string untill the comma
if(i == 1) { // i = 1 means the current line is the city one
std::map<std::string, int>::iterator it = cidades.find(line); // try to find the current city in the map
if(cidades.empty()){ // insert first time because map is empty
cidades.insert(pair<string,int>(line,cont));
}
else if(it == cidades.end()){ // insert because is not in the map
cidades.insert(pair<string,int>(line,cont));
c1 = cont;
}else{ // get the key because is already in the map
c1 = cidades.at(line);
}
} else if( i == 2) {
// line is holding city 2, do the same above
}
cont++; i++; // increase i to tell we are working with the next string after the comma
}
But when I put the same code out of the conditionals above.. it works
string a = "teste"; // taken from the txt and added into the map
std::map<std::string, int>::iterator it = cidades.find(a);
cout << "ele: " << it->first << " chave: " << it->second;
it prints teste and the key... but when I try to print inside the if I got segmentation fault(core dumped).
Edit:
My program can't find a key that's already in the map.
when I compare the iterator in the if statement it looks like none key is in the map( even when the key is already on it,then it add the same key again with another integer reference). So now I'm trying to figure out another way to look for keys in the map,any good ideas?
It might be because line isnt found, in which case it would be set to map::end, and I think that basically means its set to 'NULL' or some invalid location which means you shouldn't dereference it i.e: it->first (hence the segmentation fault) (technically what happens if you dereference the iterator returned from find when it doesn't find anything, is undefined behaviour, i.e. don't do it.),
http://www.cplusplus.com/reference/map/map/find/
Don't do the cout there, do it in the 'else' below, where you know it is pointing to a valid item.

Logic for reading rows and columns from a text file (textparser) C++

I'm really stuck with this problem I'm having for reading rows and columns from a text file. We're using text files that our prof gave us. I have the functionality running so when the user in puts "numrows (file)" the number of rows in that file prints out.
However, every time I enter the text files, it's giving me 19 for both. The first text file only has 4 rows and the other one has 7. I know my logic is wrong, but I have no idea how to fix it.
Here's what I have for the numrows function:
int numrows(string line) {
ifstream ifs;
int i;
int row = 0;
int array [10] = {0};
while (ifs.good()) {
while (getline(ifs, line)) {
istringstream stream(line);
row = 0;
while(stream >>i) {
array[row] = i;
row++;
}
}
}
}
and here's the numcols:
int numcols(string line) {
int col = 0;
int i;
int arrayA[10] = {0};
ifstream ifs;
while (ifs.good()) {
istringstream streamA(line);
col = 0;
while (streamA >>i){
arrayA[col] = i;
col++;
}
}
}
edit: #chris yes, I wasn't sure what value to return as well. Here's my main:
int main() {
string fname, line;
ifstream ifs;
cout << "---- Enter a file name : ";
while (getline(cin, fname)) { // Ctrl-Z/D to quit!
// tries to open the file whose name is in string fname
ifs.open(fname.c_str());
if(fname.substr(0,8)=="numrows ") {
line.clear();
for (int i = 8; i<fname.length(); i++) {
line = line+fname[i];
}
cout << numrows (line) << endl;
ifs.close();
}
}
return 0;
}
This problem can be more easily solved by opening the text file as an ifstream, and then using std::get to process your input.
You can try for comparison against '\n' as the end of line character, and implement a pair of counters, one for columns on a line, the other for lines.
If you have variable length columns, you might want to store the values of (numColumns in a line) in a std::vector<int>, using myVector.push_back(numColumns) or similar.
Both links are to the cplusplus.com/reference section, which can provide a large amount of information about C++ and the STL.
Edited-in overview of possible workflow
You want one program, which will take a filename, and an 'operation', in this case "numrows" or "numcols". As such, your first steps are to find out the filename, and operation.
Your current implementation of this (in your question, after editing) won't work. Using cin should however be fine. Place this earlier in your main(), before opening a file.
Use substr like you have, or alternatively, search for a space character. Assume that the input after this is your filename, and the input in the first section is your operation. Store these values.
After this, try to open your file. If the file opens successfully, continue. If it won't open, then complain to the user for a bad input, and go back to the beginning, and ask again.
Once you have your file successfully open, check which type of calculation you want to run. Counting a number of rows is fairly easy - you can go through the file one character at a time, and count the number that are equal to '\n', the line-end character. Some files might use carriage-returns, line-feeds, etc - these have different characters, but are both a) unlikely to be what you have and b) easily looked up!
A number of columns is more complicated, because your rows might not all have the same number of columns. If your input is 1 25 21 abs 3k, do you want the value to be 5? If so, you can count the number of space characters on the line and add one. If instead, you want a value of 14 (each character and each space), then just count the characters based on the number of times you call get() before reaching a '\n' character. The use of a vector as explained below to store these values might be of interest.
Having calculated these two values (or value and set of values), you can output based on the value of your 'operation' variable. For example,
if (storedOperationName == "numcols") {
cout<< "The number of values in each column is " << numColsVal << endl;
}
If you have a vector of column values, you could output all of them, using
for (int pos = 0; pos < numColsVal.size(); pos++) {
cout<< numColsVal[pos] << " ";
}
Following all of this, you can return a value from your main() of 0, or you can just end the program (C++ now considers no return value from main to a be a return of 0), or you can ask for another filename, and repeat until some other method is used to end the program.
Further details
std::get() with no arguments will return the next character of an ifstream, using the example code format
std::ifstream myFileStream;
myFileStream.open("myFileName.txt");
nextCharacter = myFileStream.get(); // You should, before this, implement a loop.
// A possible loop condition might include something like `while myFileStream.good()`
// See the linked page on std::get()
if (nextCharacter == '\n')
{ // You have a line break here }
You could use this type of structure, along with a pair of counters as described earlier, to count the number of characters on a line, and the number of lines before the EOF (end of file).
If you want to store the number of characters on a line, for each line, you could use
std::vector<int> charPerLine;
int numberOfCharactersOnThisLine = 0;
while (...)
{
numberOfCharactersOnThisLine = 0
// Other parts of the loop here, including a numberOfCharactersOnThisLine++; statement
if (endOfLineCondition)
{
charPerLine.push_back(numberOfCharactersOnThisLine); // This stores the value in the vector
}
}
You should #include <vector> and either specific std:: before, or use a using namespace std; statement near the top. People will advise against using namespaces like this, but it can be convenient (which is also a good reason to avoid it, sort of!)

Reading a truth table in from plain text, translating it to a map<int,list<int>> in C++

I'm writing a file parser for standard C++ (no third-parties like Boost, unfortunately)...
I'm dealing with a situation where I have a plain-text file formatted like this:
1 ..header line 1, unimportant
2 ..header line 2, unimportant
3 ..header line 3, unimportant
4 1 0 0 0 0 0 0 1
5 2 0 1 0 2 1 0 0
...skipping ahead
14 11 1 0 0 0 0 1 1
15 12 0 0 1 0 0 1 2
16 13 2 0 0 0 1 0 0
...etc
(Note: The first column, 1 - 16, are line numbers. The skip ahead is meant to represent the gap of 8 spaces from the start of each line gets shorter as the second column, 1- 13, gets longer and longer numbers.
This text file denotes a truth table whereby items must be grouped by the columns, and each group will be composed of corresponding numbers from the first column. For instance, by the end of parsing this example, a map of type <int, list<int>> should look like (assuming there are no truths between lines 6 and 13):
[1: {11, 13}]
[2: {5, 15}]
[3: {12}]
[4: {5}]
[5: {5,16}]
[6: {14,15}]
[7: {4,14,15}]
In general, the number of columns in the text file can change, meaning the number of groups will change, so this must be accounted for. The number of rows is also variable, but will both will always start at 1 and the columns will not be numbered (but we can do that ourselves).
Now, were I to do this in Java I'd have a working solution rather quickly. However, I've never done work in C++ and am having trouble figuring out how to perform the operations properly, between its different structures and syntax. Despite scouring and finding lots of good guides, my lack of C++ foundation makes it hard to understand even the syntax differences that, I speculate, must be very basic.
Still, I've designed procedure, and it should work according to the following pseudocode:
//Begin Parse
//Create filereader "strmFileIn"
//To get past the first three lines, which will always be needless header info
string dummyLine;
for (i = 1; i <= 3; i++)
getline(strmFileIn, strDummyLine);
//Read first line to get count of how many groups are present
//(Copied from internet: gets the first line and puts the cursor back at its start)
int startPos = strmFileIn.tellg();
string strFirstLine;
getline(strmFileIn, strFirstLine);
strmFileIn.seekg(startPos, std::ios_base::beg);
//Tokenize strFirstLine into Array<int> tempArray
int numGroups = tempArray.size() - 1 //accounting for the row-header column, 1 - 13
//Create map (going to use java syntax, sorry)
Map<int,list<int>> myMap = new Map<int,list<int>>;
//Populate map with ints and empty lists (java again, sorry)
for (int i = 1; i <= numGroups; i++)
myMap.put(i, new List<int>);
//Iterate over lines in the file and appropriately populate the map's lists
while (fileIn != eof)
{
string fileInLine;
getline(strmFileIn, fileInLine);
//Tokenize fileInLine into Array<int> tempFileInArray
int intElemID = tempFileInArray[0];
//Remove element [0] from tempFileInArray (will be the row number, 1 - 13
//Iterate over remaining items in tempFileInArray, affect myMap where necessary
for (int i = 1; int i <= groupNum; i++)
if (tempFileInArray[i] != 0) //is not a strict truth-table, as any nonzero will be a truth
myMap.get[i].add(intElemID);
}
//Remove any entries in myMap with empty lists
//Kill strmFileIn for memory's sake
//End Parse
As you can see, my code is a broken mix of pseudocode and comparable Java I've already figured out. I just don't know how to turn this into C++; even with similar data structures, the syntax is a little daunting to someone with no experience. Is anyone here willing to help me out with it?
I really appreciate any insight.
Your code seems overly complicated, so lets do this one step at a time. Additionally, neither your code nor file format show how many bool columns should exist on each row, so I've ignored that part for this answer.
But first, a tip: In C++, the containers you care about 99.99% of the time are std::unordered_map, std::vector, and in very rare cases, std::map, boost::stable_vector and std::deque. In your case, you have rows with sequential indices, and the data for each row appears to be better stored as a vector of booleans. However, we'll do it your way, with the replacement of std::vector instead of std::list, and std::unordered_map instead of std::map.
This major data structures are mostly obvious:
std::unordered_map<int,std::vector<int>> myMap;
std::ifstream strmFileIn("input_file.txt");
Next your code reads in the first line, then ignores it entirely. I have no idea why, so I'll skip over that. Then, we parse out the lines one by one:
std::string full_current_line;
//for as long as we can read more lines, read them in
while(std::getline(strmFileIn, full_current_line)
{
//make the line into a stream so that we can parse data out
std::stringstream cur_line_stream(full_current_line);
//read in the line identifier
int identifier = 0;
cur_line_stream >> identifier;
//if that failed, abort.
if (!cur_line_stream)
{
//invalid identifer!
std::cerr << "identifier is invalid!\n"; //report
strmFileIn.setstate(std::ios::failbit); //failed to parse the data
break; //do not continue this loop
}
After that, we parse out the data for each row, which is surprisingly simple:
int column = 0;
int is_true = false;
//for each number remaining in the row...
while(cur_line_stream >> is_true)
{
//hooray we read a column!
++column;
if (is_true ==0)
{
//if it's zero, skip it
}
else if (is_true == 1)
{
//get the data for this column, and add this row's identifier
//myMap[column] will create a new empty entry if it didn't exist yet
//NOTE: This syntax only creates when used with map and unordered_map.
// This syntax does NOT create for vector and deque.
//once we have the vector, we push_back the new identifier into it.
myMap[column].push_back(identifier);
}
else
{
//invalid data!
std::cerr << is_true << " is invalid! found on row " << identifier << '\n';
cur_line_stream.setstate(std::ios::failbit); //failed to parse the data
strmFileIn.setstate(std::ios::failbit); //failed to parse the data
break; //do not continue this loop
}
}
}
If you know that groupNum contained the number of bools, you could replace that second while with something more like you already have:
for (int i = 1; int i <= groupNum; i++)
{
cur_line_stream >> is_true;
//if that failed, abort
if (!cur_line_stream)
{
//invalid data!
std::cerr << "data could not be read on row " << identifier << '\n';
cur_line_stream.setstate(std::ios::failbit); //failed to parse the data
strmFileIn.setstate(std::ios::failbit); //failed to parse the data
break; //do not continue this loop
}
else if (is_true == 0)
{
//if it's zero, skip it
}
etc etc etc
Work the other way. Code only in C++ (not in Java and don't think in Java), but start by parsing a small chunk of your syntax. First, code the lexer. Test it. Then code the parser, probably a recursive descent parser, and test it on short simple subelements of your language. Perhaps you'll need some small look-ahead (an easy task, use a std::list<Token>) Keep going up.
Start by formalizing, with pencil and paper, your input language. Could you for instance write a simple BNF grammar for it? (your question does not explain what is the input, it just gives an example)
In C++ parlance: to parse a map<int,list<int>> you certainly need to be able to parse int and list<int>. So write first the parsers for these.
As commented by Mooing Duck, your input language (which you did not define, just gave an example) seems simple enough to avoid most of this. But still, the idea is the same, think directly in C++ and start by reading a simple subpart of the input. Test your code. When that works, increase the part that is accepted. Repeat all this.
Here's a very simple solution that uses nothing but C++ and standard libraries. It just reads line by line and pulls each element out of the line with stream extraction using operator>>.
#include <iostream>
#include <fstream>
#include <sstream>
#include <map>
#include <list>
int main(int argc, char* argv[])
{
// Parse command line
if( argc != 2 )
return 1;
std::fstream fin(argv[1]);
if( !fin.good() )
{
std::cerr << "Error opening file for reading: " << argv[1] << std::endl;
return 1;
}
// Skip first three lines
std::string line;
for( int i=0; i<3; ++i )
{
std::getline(fin, line);
}
// Read each line
std::map<int, std::list<int> > hits;
while( std::getline(fin, line) )
{
// Extract each element from the line
std::stringstream sstr(line);
// Read line number from first column
int linenum = 0;
sstr >> linenum;
// Interpret remaining columns as truth values
bool truth;
int col=1;
while( sstr >> truth )
{
// Store position in map if true
if( truth )
{
hits[col].push_back(linenum);
}
col++;
}
}
// Print results
std::map<int, std::list<int> >::const_iterator col_iter;
for( col_iter = hits.begin(); col_iter != hits.end(); ++col_iter )
{
std::cout << "[" << col_iter->first << ": {";
std::list<int>::const_iterator line_iter;
for( line_iter = col_iter->second.begin(); line_iter != col_iter->second.end(); ++line_iter )
{
std::cout << *line_iter << " ";
}
std::cout << "} ]" << std::endl;
}
return 0;
}

C++ std::bad_alloc error

I'm working on a C++ program (C++ 98). It reads a text file with lots of lines (10000 lines). These are tab separated values and then I parse it into Vector of Vector objects. However It seems to work for some files (Smaller) but One of my files gives me the following error (this file has 10000 lines and it's 90MB). I'm guessing this is a memory related issue?
Can you please help me?
Error
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Abort
Code
void AppManager::go(string customerFile) {
vector<vector<string> > vals = fileReader(customerFile);
for (unsigned int i = 0; i < vals.size();i++){
cout << "New One\n\n";
for (unsigned int j = 0; j < vals[i].size(); j++){
cout << vals[i][j] << endl;
}
cout << "End New One\n\n";
}
}
vector<vector<string> > AppManager::fileReader(string fileName) {
string line;
vector<vector<string> > values;
ifstream inputFile(fileName.c_str());
if (inputFile.is_open()) {
while (getline(inputFile,line)) {
std::istringstream iss(line);
std::string val;
vector<string> tmp;
while(std::getline(iss, val, '\t')) {
tmp.push_back(val);
}
values.push_back(tmp);
}
inputFile.close();
}
else {
throw string("Error reading the file '" + fileName + "'");
}
return values;
}
There's nothing wrong with your code, you're simply running on a platform likely with small memory limits, likely an old compiler and likely an old C++ library. It all conspires against you. You'll have to micro-optimize :(
Here's what you can do, starting with lowest hanging fruit first:
Do a dry run through the file, just counting the lines. Then values.resize(numberOfLines) , seek to the beginning and only then read the values. Of course you won't be using values.push_back anymore, merely values[lineNumber] = tmp. Resizing the values vector as you add to it may more than double the amount of memory your process needs on a temporary basis.
At the end of the line, do tmp.resize(tmp.size() - it'll shrink the vector to just fit the data.
You can reduce overheads in the existing code by storing all the values in one vector.
If each line has a different number of elements, but you access them sequentially later on, you can store an empty string as an internal delimiter, it may have lower overhead than the vector.
If each line has same number of values, then splitting them by lines adds unnecessary overhead - you know the index of the first value in each line, it's simply lineNumber * valuesPerLine, where first line has number 0.
Memory-map the file. Store the beginning and end of each word in a structure element of a vector, perhaps with a line number as well if you need it split up in lines.

reading file and split the line in c++

I have the following code that read input from txt file as follow
Paris,Juli,5,3,6
Paris,John,24,2
Canberra,John,4,3
London,Mary,29,4,1,2
my code is to load the data into map then I want to print the map content to make sure that it has been inserted correctly, I check the vaue of m as it is used during splitting the line. However, during the execution I get this as continues 0s which means it is never enter the while loop. I have used this part of code before and it works. I could not find where I've made the mistake.
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <vector>
#include<map>
using namespace std;
struct info {
string Name;
int places;// i will use the binary value to identfy the visited places example 29 is 100101
// this means he visited three places (London,LA,Rome)
vector<int> times; // will represent the visiting time,e.g. 1,2,5 means london 1 time, LA
// twice and Rome five times
};
map<string,vector<info> > log;
map<string,vector<info> >::iterator i;
fstream out;
int main() {
out.open("log.txt", std::ios::in | std::ios::out | std::ios::app);
string line;
char* pt;
string temp[19];
// for each line in the file
while (!out.eof())
{
getline(out,line);//read line from the file
pt=strtok(&line[0],"," );//split the line
int m=0;
while (pt != NULL)
{
temp[m++] = pt; // save the line info to the array
cout<<m<<" ";
pt = strtok (NULL, ",");
}
cout<<m<<" "; // during the execution I get this as continues 0s which means it is never enter the while loop
info tmp;
// read the other data
tmp.Name=temp[1];
tmp.places=atoi(temp[2].c_str());
for ( int i=3;i<=m;i++)
{
tmp.times.push_back(atoi(temp[i].c_str()));
}
// create a new object
log[temp[0]].push_back(tmp);
}
vector<int>::iterator j;
for(i=log.begin();i!=log.end();i++) {
cout<< "From "<< i->first<<" city people who travels: "<<endl;
for (size_t tt = 0; tt < (i->second).size(); tt++) {
cout<< (i->second[tt]).Name<< " went to distnations "<< (i->second)[tt].places<<" \nwith the folloing number of visiting time ";
for (j=((i->second[tt]).times).begin();j!= ((i->second[tt]).times).end();j++)
cout<<*j<<" ";
}
}
system("PAUSE");
return 0;
}
This is an error
// for each line in the file
while (!out.eof())
{
getline(out,line);//read line from the file
should be
// for each line in the file
while (getline(out,line))
{
I find it frankly incredible how often this error is repeated. eof does not do what you think it does. It tests if the last read failed because of end of file. You are using it to try and predict whether the next read will fail. It simply doesn't work like that.
This line is an error
pt=strtok(&line[0],"," );//split the line
strtok works on C strings, there's no guarantee it will work on std::string.
But neither of these are likely to be your real error. I would suggest opening the file with ios::in only. After all you only want to read from it.
Your fstream should not open in app mode. That will seek the file to the end of file. Delete std::ios::app from it.
You can't tokenize an std::string using strtok. Use getline instead:
std::string str("some,comma,separated,data");
std::string token;
while (getline(str, token, ',')) {
cout << "Token: " << token << end;
}
At each iteration, token contains the next parsed token from str.
This is wrong temp[m++] = pt; // save the line info to the array
Switch to something like this, instead of "temp"
std::vector<std::string> vTemp;
pt=strtok(&line[0],"," );//split the line
while (pt != NULL)
{
vTemp.push_back(pt); // save the line info to the array
pt = strtok (NULL, ",");
}
Also consider using something like this to do the split.
std::vector<std::string> SplitString(const std::string &strInput, char cDelimiter)
{
std::vector<std::string> vRetValue;
std::stringstream ss(strInput);
string strItem;
while(std::getline(ss, strItem, cDelimiter))
{
// Skip Empty
if(strItem.size()==0)
continue;
vRetValue.push_back(strItem);
}
return vRetValue;
}
#halfelf really great solution for my simple error, it works but the problem is now when I print the data I got this
From Paris city people who travels:
Juli went to distnations 5
with the folloing number of visiting time 3 6 0
John went to distnations 24
with the folloing number of visiting time 2 6
From Canberra city people who travels:
Johnwent to distnations 4
with the folloing number of visiting time 3 6
From London city people who travels:
Mary went to distnations 29
with the folloing number of visiting time 4 1 2 0
This is not correct as 6 is added to John from Canberra and Paris and 0 is added to Juli and Mary.
any idea of where I get it wrong ,, its about the times vector , its seems that I need to reset the value for each line or clear the content after the insertion. what about the extra 0?