Insert object in c++ list - c++

I have the follow program in c++. The objective is receive some logs (that came from filedata variable), parse the logs, and save them to object list.
The part to do the parse its working good. But i have a problem when i iterate the parsed vector and try to save some elements to the list. I can get the elements (for example: elements.at(0) i get the first column (timestamp) but when i save to my list, we save two times the log (in this case the filedata only have two logs), but we save two time the SAME log.
My cpp program:
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <iterator>
#include <list>
class UserLogRecord
{
public:
std::string timestamp;
std::string id;
std::string name;
std::string data;
};
std::vector<std::string> explode(std::string const & s, char delim)
{
std::vector<std::string> result;
std::istringstream iss(s); // sequence of characters
for (std::string token; std::getline(iss, token, delim); )
{
result.push_back(std::move(token)); //transfer token to vector
}
return result;
}
int main()
{
const char* filedata =
"1496843100;2017-06-07 13:45:00;000002D8;2600;user1\n"
"9999999999;2017-06-07 13:45:00;000002D9;2800;user2";
std::vector<std::string> lines = explode(filedata,'\n');
std::list<UserLogRecord* > userLogRecords;
UserLogRecord* userLogRecord = new UserLogRecord;
//vector
for(int i = 0; i < lines.size(); i++)
{
std::vector<std::string> elements = explode(lines[i], ';');
userLogRecord->timestamp = elements.at(0);
userLogRecord->id = elements.at(2);
userLogRecord->name = elements.at(4);
userLogRecord->data = elements.at(3);
userLogRecords.push_back(userLogRecord);
}
//list of logs
std::list<UserLogRecord* >::const_iterator itLog = userLogRecords.begin();
while (itLog != userLogRecords.end())
{
std::cout << '\n' + (*itLog)->timestamp + '\n';
std::cout << (*itLog)->id + '\n';
std::cout << (*itLog)->name + '\n';
std::cout << (*itLog)->data + '\n';
++itLog;
}
return 0;
}
Output (when iterate the list):
9999999999
000002D9
user2
2800
9999999999
000002D9
user2
2800
Expected output:
1496843100
000002D8
user1
2600
9999999999
000002D9
user2
2800
My program save two logs (this part is 'good', i only have two logs) but its save always the same (curiously it is the last log)

You are only using one UserLogRecord and simply modifying the data instead of adding a new element in the list.
std::list::push_back is adding a copy of a pointer to UserLogRecord which remains the same for all the iterations of the loop. The same pointer is pushed multiple times in the list and therefore all elements have the same data.
The following code would fix the issue. A new UserLogRecord is created for each iteration. You must however remember to free the allocated memory with delete when you don't need it anymore.
//vector
for(int i = 0; i < lines.size(); i++)
{
UserLogRecord* userLogRecord = new UserLogRecord;
std::vector<std::string> elements = explode(lines[i], ';');
userLogRecord->timestamp = elements.at(0);
userLogRecord->id = elements.at(2);
userLogRecord->name = elements.at(4);
userLogRecord->data = elements.at(3);
userLogRecords.push_back(userLogRecord);
}

Related

How to find the index of element (and a few other things)

I was writing a code that would substitute some random 17 character strings into a single alphabet, and I can't find a way. Basically, what I'm trying to do is this:
char strings[] = {
"L-nIbhm5<z:92~+,x",
"9bC5f0q#qA(RKZ>|r",
"9bC5f0q#qA(RKZ>|r",
"k=5,ln(08IAl(gGAK",
"|N,8]dGu)'^MaYpu[",
"!&,Y*nz8C*,J}{+d]",
"Us9%^%?n5!~e##*+#",
"zF8,1KV#¥]$k?|9R#",
"0B4>=nioEjp>4rhgi",
}
char alphabet[]{
"a","b","c","d","e","f","g","h","i",
}
replace(std::string str){
/**get str and then see the index of the corresponding string in strings[], and replace the string with alphabet[index number], while deleting the original string part that was replaced**/
int main(){
cin >> std::string replace;
replace(replace);
example input: L-nIbhm5<z:92~+,x9bC5f0q#qA(RKZ>|r9bC5f0q#qA(RKZ>|r
expected output: abc
EDIT:
New Code
Changes from the original code
It also has a bigger array than the simplified version(previous code). It displays the structure of the full program.(where the strings are routed to and why)
Basically What it's doing
getting input from user, put it in the input variable, input goes through algorithm() function untouched, and then goes to the replace function and is replaced. It then the replaced string gets returned back through the original route to the main function, where it is displayed.
I've kept the arrays a string type because the const char* gave me a segmentation error.
std::string Subs[53]=
{
"LQlMv]G5^^1kcm?fk",
"7W^S;/vB(6%I|w[fl",
"<w7>4f//Z55ZxK'z.",
"_W5g(lu<pTu3^_A7n",
"OfLm%8:EF}0V1?BSS",
"|+E6t,AZ~XewXP17T",
"L-nIbhm5<z:92~+,x",
"L-nIbhm5<z:92~+,x",
"9bC5f0q#qA(RKZ>|r",
"9bC5f0q#qA(RKZ>|r",
"k=5,ln(08IAl(gGAK",
"|N,8]dGu)'^MaYpu[",
"!&,Y*nz8C*,J}{+d]",
"Us9%^%?n5!~e##*+#",
"zF8,1KV#¥]$k?|9R#",
"0B4>=nioEjp>4rhgi",
"EG#0[W9.N4i~E<f3x",
"(0Pwkk&IPchJHs.7A",
"7XgmQ6fW<|J+NY[m0",
".g4CwX/DU!!~!zbtZ",
"+_U'qn_/9Fo|gT/!n",
"=0s(mYh&F%y=MBS5(",
"cg71(}bo+Q5P8F[T6",
"lc|a\%5.9pOpooU+QR",
"E_(3A:o+.]qL3MYA6",
"H#O'X_RiVS#8l0bKD",
"Y1gbGD`~8d>HSWN35",
"LQlMv]G5^^1kcm?fk",
"T4}gI;`BFVfhw=-sf",
"6BHMA0IRix]/=(jht",
"yS$=#Jdpp?P2k6SMQ",
"t1~|kkh+>4d>}OQ`a",
"2Y-\\CU\"944yBluWD5",
"'M\\ZbIX5{`Xd;qi!o",
"?N+RtVqj_r(C5##0\"",
"2;*Livh?V$X/8z#Md",
")IN|7FOs2l-mAM[d#",
"(~f268J},xXrK'Rp'",
"&r/qf9fFHnzV!RzH/",
"}naDRH4p$NI2a).t,",
"{8DM+7!.Mge|~fnO|",
")r[#nI0YDH>6cE38p",
"(0Pwkk&IPchJHs.7A",
")r[#nI0YDH>6cE38p",
"8M-=cQFQ,pPo7eu=p",
"0PHw=/|(tZ1}FHm/'",
"[su`'0Oybc.\"-/W5)",
"1uHl[IC7Sr#NUJV;I",
"8z8%,jK0CDOkJz8I?",
"3Ao2yXDN%YzpE&Suy",
"zNs`7E'e/$i8VqaUL",
"bzHmA^K2>7`UZ?!AO",
};
std::string Alphabet[53] =
{
" ","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","r","w","x","y","z",
"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z",
};
std::string replace(std::string rep) {
int len = sizeof(Subs)/sizeof(Subs[0]);
std::stringstream ss1;
for(int i = 0; i < len; i++) {
if (rep.find(Subs[i]) != std::string::npos) {
ss1 << Subs[i];
}
}
std::string input = ss1.str();
return input;
}
std::string algorithm(std::string input)
{
//some other algorithms come here(not relative to this question)
input = replace(input);
return input;
}
int main(void){
int ed;
std::cin >> ed;
if(ed == 1){
//different function(not relative to the question)
}
else if(ed == 0){
std::string input;
std::cin >> input;
input = algorithm(input);
std::cout << input << std::endl;
}
else{
std::cout << "1 or 0" << std::endl;
main();
}
return 0;
}
example input: L-nIbhm5<z:92~+,x9bC5f0q#qA(RKZ>|r9bC5f0q#qA(RKZ>|r
expected output: abc
actual output: L-nIbhm5<z:92~+,xL-nIbhm5<z:92~+,x9bC5f0q#qA(RKZ>|r9bC5f0q#qA(RKZ>|r
Sorry it's become long.
There are few mistakes in above code :
char array initialization is not correct.
method body for main and replace method is not closed.
Currently by default return type of replace method is int.
There is string#find method which can be helpful here.
I have tried to make those fixes and here is updated code in C++17 :
#include <iostream>
#include <sstream>
using namespace std;
const char *strings[9] = {
"L-nIbhm5<z:92~+,x",
"9bC5f0q#qA(RKZ>|r",
"9bC5f0q#qA(RKZ>|r",
"k=5,ln(08IAl(gGAK",
"|N,8]dGu)'^MaYpu[",
"!&,Y*nz8C*,J}{+d]",
"Us9%^%?n5!~e##*+#",
"zF8,1KV#¥]$k?|9R#",
"0B4>=nioEjp>4rhgi"
};
const char *alphabet[9] = {
"a","b","c","d","e","f","g","h","i"
};
void replace(std::string rep) {
int len = sizeof(strings)/sizeof(strings[0]);
std::stringstream ss1;
for(int i = 0; i < len; i++) {
if (rep.find(strings[i]) != std::string::npos) {
ss1 << alphabet[i];
}
}
std::cout << ss1.str();
}
int main(){
std::string rep;
cin >> rep;
replace(rep);
}
For reference : https://onlinegdb.com/Bd9DXSPAa
Note - Above code is just for reference, please make sure to add all test cases handling.
I made a c++17 version for your code.
Replacing 'c' style arrays and pointers with C++ style containers, iterators.
And using std::string::replace function. Use the standardlibrary if you can,
its tested and well documented.
#include <algorithm>
#include <iostream>
#include <regex>
#include <string>
#include <vector>
// std::vector/std::array instead of 'c' style arrays.
// allows us to us range based for loops later.
std::vector<std::string> strings =
{
"L-nIbhm5<z:92~+,x",
"9bC5f0q#qA(RKZ>|r",
"k=5,ln(08IAl(gGAK",
"|N,8]dGu)'^MaYpu[",
"!&,Y*nz8C*,J}{+d]",
"Us9%^%?n5!~e##*+#",
//"zF8,1KV#¥]$k?|9R#", // <<== I commented out this line, ¥ is not a valid charcter in my environment
"0B4>=nioEjp>4rhgi"
};
// a string is already an array of characters.
std::string alphabet{ "abcdefghijkl" };
std::string replace_with_alphabet(const std::string& input)
{
std::string retval{ input };
std::size_t index{ 0 };
// range based for, it will keep the order of the vector.
for (const auto& str : strings)
{
// look if you can find any of the predefined strings
// in the input strings.
const size_t pos = retval.find(str, 0);
// if found
if (pos != std::string::npos)
{
// get the next character from the alphabet
std::string replacement{ alphabet[index++] };
// use std::string::replace for replacing the substring
const size_t len = str.length();
retval.replace(pos, len, replacement, 0);
}
}
return retval;
};
/**get str and then see the index of the corresponding string in strings[], and replace the string with alphabet[index number], while deleting the original string part that was replaced**/
int main()
{
auto output = replace_with_alphabet("L-nIbhm5<z:92~+,x9bC5f0q#qA(RKZ>|rk=5,ln(08IAl(gGAK");
std::cout << output << std::endl;
}

How to split a sentence of any length into words and store them into variables c++

I need some help on making a function to split sentence into words and this function should work on sentence with different lengths.
Here is the sample code:
void spilt_sentence(string sentence)
{}
int main()
{
std::string sentence1= "Hello everyone";
std::string sentence2= "Hello I am doing stuff";
split_sentence(sentence1);
split_sentence(sentence2);
return 0;
}
I saw someone use std::istringstream to get every words before each space but I don't really know how it works. It gives me error when I put std::istringstream ss(sentence); in the code. Also, I am using c++98 and I compile my program with cygwin. Any leads? Thank you.
Edit: The function will create a number of variables depending on how many words are there in the sentence.
Edit: I am actually working on a LinkedList program and what I am trying to do here is split sentence into words and then generate new nodes containing each word.
Here is the actual code (note: I modified it a little bit so it's not exactly the same as my actual one. Also I am not using struct for Node) and let's say sentence 1 is "Hello everyone" and sentence 2 is "Hello I am doing stuff".
The expected output will be:
linkedlist1:
"hello"<->"everyone"
linkedlist2:
"hello"<->"I"<->"am"<->"doing"<->"stuff"
inside LinkedList.cpp:
void LinkedList::add(std::string sentence)
{
//breaks down the sentence into words
std::istringstream ss(sentence);
do
{
std::string word;
ss >> word;
//store them in nodes in a linkedlist
Node* new_tail = new Node(word);
if (size == 0)
{
head = new_tail;
tail = new_tail;
}
else
{
new_tail->set_previous(tail);
tail->set_next(new_tail);
tail = new_tail;
}
new_tail = NULL;
size++;
}
while(ss);
}
[FIXED]An error message pop up when I compile it, saying std::istringstream ss has default settings but the type is incomplete. What should I do?
error
Here is the function using streams, this function will work only for vectors, you can't use this function for arrays, but if you want to, you can modify it for you.
Here is the code and usage example
#include <string>
#include <sstream>
#include <algorithm>
#include <iterator>
#include <iostream>
using namespace std;
void split_sentence(const string& str, vector<string>& cont)
{
istringstream iss(str);
copy(istream_iterator<string>(iss),
istream_iterator<string>(),
back_inserter(cont));
//checking for punctuation marks and if found, we remove them from the word
for(int i = 0, sz = cont.size(); i < sz; i++){
string word = cont.at(i);
for(int j = 0, len = word.length(); j < len; j++){
if(ispunct(word[j])){
cont.at(i) = word.substr(0, word.length() - 1);
}
}
}
}
int main(){
string sentence = "this is a test sentence for stackoverflow!";
vector<string> words;
split_sentence(sentence, words);
for(int i = 0, sz = words.size(); i < sz; i++){
cout<<words.at(i) << endl;
}
return 0;
}
And this is the output
this
is
a
test
sentence
for
stackoverflow
if you also want to print punctuation marks then remove double for loop in fucntion.

Returning Employee and Salary when Given a Location Substring

I am given two files one with the name of person and the location that they are from (Evan Lloyd|Brownsville) and one with the name and salary (Evan Lloyd|58697) (the line number that you find the employee on in the first file is not necessarily the line number that find the employee on in the second). The user inputs a location (whole or part). For example if they input "ville" or "Ville" it should include all of the employees in Brownsville, Clarksville, Greenville, etc. I am supposed to join the the name and salary and return them if they are in the city searched for i.e. "ville" or "Ville."
I have no errors or warnings when compiling, but I get a segmentation fault for all input.
#include <fstream>
#include <iostream>
//#include <vector>
#include <string>
#include <bits/stdc++.h>
using namespace std;
int main() {
string str;
cout << "Enter the location: ";
cin >> str;
ifstream addresses;
addresses.open("personnel_addresses.txt");
multimap<string, string> name_address;
ifstream salaries;
salaries.open("personnel_salaries.txt");
multimap<string, string> name_salary;
while(!addresses.eof() && !salaries.eof()) {
string tmpstr;
getline(addresses, tmpstr);
int pos = tmpstr.find("|");
string name2address = tmpstr.substr(0, pos - 1);
string address = tmpstr.substr(pos + 1);
name_address.insert({address, name2address});
getline(salaries, tmpstr);
pos = tmpstr.find("|");
string name2employee = tmpstr.substr(0, pos - 1);
string salary = tmpstr.substr(pos + 1);
name_salary.insert({name2employee, salary});
}
// do{
vector<string> employees;
for(auto n = name_address.find(str); n != name_address.end(); n++) {
employees.emplace_back(n->second);
}
for(int i = 0; i < sizeof(employees); i++) {
string x = employees[i];
// if (name_salary.find(employees[i]))
cout << employees[i] << ":" << name_salary.find(x)->second << "\n";
}
//}while(name_address.end());
addresses.close();
salaries.close();
return 0;
}
Someone recommended that I alter the code by populating a set full of the cities in the while loop and iterating over the set immediately after declaring vectoremployees instead the code that directly below it by the following code
for(string const& search : cities)
{
if(find(search.begin(), search.end(), str) != std::string::npos)
{
string y = search;
employees.emplace_back(y);
, but there is something wrong with syntax where I am trying to iterate over the set.
EDIT: My problem was simple and was fixed with using .begin() and .end() to iterate over the multimap name_address and finding each name with .substr(). Also my while loop was incorrect. I should have read each file separate from each other. I did not use vectors in my solution.
while(getline(addresses, tmpstr1))
{
int pos = tmpstr1.find("|");
string name2address = tmpstr1.substr(0, pos);
string address = tmpstr1.substr(pos+1);
name_address.insert({address, name2address});
}
while(getline(salaries, tmpstr2))
{
int pos = tmpstr2.find("|");
string name2employee = tmpstr2.substr(0, pos);
string salary = tmpstr2.substr(pos+1);
name_salary.insert({name2employee, salary});
}
for(auto it = name_address.begin(); it != name_address.end(); ++it)
{
for(int i = 0; i < it->first.length(); ++i)
{
string tmpstr3 = it->first.substr(0 + i, str.length());
if(str == tmpstr3)
{
employees.insert(it->second);
break;
}
}
}
A segmentation fault generally occurs when you are trying to access memory in some capacity, but have no permission to that location in memory. I notice that in one of your final for-loops, you say for(int i = 0; i < sizeof(employees); i++), but I believe that the function sizeof(object) reports the number of bytes in memory its parameter is consuming. It seems like that is not what you intended, and the number of bytes will most likely be much larger than the number of employees you are tracking. Thus, the body of your for-loop will try to access memory it is not allowed to and then cue a segmentation fault.
Another quick couple notes:
Are you guaranteed that both of your input files will contain information about the same number of employees? If not, you will quit reading in from both files as soon as you made it to the end of one of them because of your looping condition.
In most cases, I believe ifstream::eof() is pretty dangerous because it only indicates whether you have attempted to read past the end of a file. This usually means that you will perform more operations than you intended to. See here if you want more information from more knowledgeable people than I.

C++ std::sort function gets not finished?

im currently setting up the highscore-part for a game and I have a very weird problem because of the weird behaviour of the std::sort function.
Im doing the whole thing in RAD Studio 10.2 (Embarcadero IDE) in C++.
So he is my code:
std::string Line;
int count = 0;
int i = 0;
ifstream File("Highscore.txt");
if(File.is_open())
{
while(getline(File, Line))
{
count += 1;
}
File.close();
}
ifstream ReadFile("Highscore.txt");
if(ReadFile.is_open())
{
string *scores = NULL;
scores = new string[count];
while(getline(ReadFile, Line))
{
scores[i] = Line;
i += 1;
}
ReadFile.close();
std::sort(scores, (scores+count));
UnicodeString Uscores1 = scores[0].c_str();
UnicodeString Uscores2 = scores[1].c_str();
UnicodeString Uscores3 = scores[2].c_str();
UnicodeString Uscores4 = scores[3].c_str();
UnicodeString Uscores5 = scores[4].c_str();
LScore1->Caption = Uscores1;
LScore2->Caption = Uscores2;
LScore3->Caption = Uscores3;
LScore4->Caption = Uscores4;
LScore5->Caption = Uscores5;
}
I get no errors from the compiler/linker and everything work should fine.
The string array gets filled correctly and so on.
But its not sorting.
To show the problem to you I made a screenshot - on the left you can see the txtfile with the scores; on the right you can see the output after the sorting algorithm:
My question now is why this is happening?
Thanks for you help
Welcome to C++. Since you want to list numbers by rank, read them as int not string. Forget about operator new. You will not need it for years, if ever. Use standard containers like std::vector, which take care of the memory allocation and de-allocation transparently.
#include <iostream>
#include <vector>
#include <fstream>
#include <algorithm>
int main() {
using namespace std;
vector<int> scores;
{
ifstream inp("Highscore.txt");
int next;
while (inp >> next) {
scores.push_back(next);
}
}
sort(scores.begin(), scores.end());
for (auto s : scores) {
cout << s << '\n';
}
return 0;
}
How about something like:
int i = 0;
int * scoresInteger = NULL;
scoresInteger = new int[count];
for(i = 0; i < count; i++)
{
scoresInteger[i] = std::stoi(scores[i]);
}
std::sort(scoresInteger, scoresInteger + count);
If you need to, you can convert the integers back into strings using targetStrings[i] = std::to_string(scoresInteger[i]).
string * targetScores = NULL;
targetScores = new std::string[count];
for(i = 0; i < count; i++)
{
targetScores[i] = std::to_string(scoresInteger[i]);
}
delete [] scoresInteger;
scoresInteger = NULL;
Don't forget to delete [] targetScores later.
My question now is why this is happening?
Because your scores are compared as strings and not as ints. Because of that "3" is greater that "25"
std::cout << std::boolalpha << (std::string("3") > std::string("25")) << std::endl; // true
Luckily you can pass a custom comparator (or lambda) to the std::sort to make it behave just as you want:
#include <iostream>
#include <string>
#include <algorithm>
int main()
{
const int count = 5;
std::string scores[count] = { "35","25","3","4","5" };
// TWEAKED SORT
std::sort(scores, scores + count, [](std::string const &s1, std::string const &s2)
{
return std::stoi(s2) < std::stoi(s1);
});
// TEST
for (auto const &s : scores)
{
std::cout << s << std::endl;
}
}
The compared strings in the above example are converted to ints and then compared, resulting in the desired sorting order.
35
25
5
4
3
Please note that I do not agree with the rest of your code and I think you should rethink the implementation, as it would be much easier, safer and more efficient to use std::vector<std::string> for your task.

C++ - Storing user input string separated by commas into vector

I have a code written that performs this task to a certain extent. But, I would like to how to alter my code so that I can store as many string inputs the user wants to enters into the vector.
Here is my code:
#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
int main ()
{
string input = "";
cout << "Input: ";
cin >> input;
string a,b;
for(int i = 0; i<input.size(); i++)
{
if(input.at(i)==','){
a=input.substr(0,i);
b=input.substr(i+1);
}
}
vector<string> objects;
objects.push_back(a);
objects.push_back(b);
for (int k = 0; k < 2; k++) {
cout << objects[k] << endl;
}
return 0;
}
So far, it can only recognize and store two inputs separated by commas. I am very new to coding so could someone show me a way to make this into a loop and take in as many inputs as the user enters?
Thank you.
There are much simpler approaches to parse an input string using stringstreams:
string a;
vector<string> objects;
for(stringstream sst(input); getline(sst, a, ','); ) // that's all !
objects.push_back(a);
copy (objects.begin(), objects.end(), ostream_iterator<string>(cout," ; ")); // display all
Online demo
You need to change your code in order to work for any number of user input.
The logic is to push every sub string between the commas into vector.
vector<string> objects;
for(int i = 0,j=0; i<input.size(); i++)
{
if(input.at(i)==',' || input.at(i)=='\0'){
objects.push_back(input.substr(j,i-j)); //pushing the sub string
j=i+1;
}
}
In order to print the vector first you have to find the size of the vector,then simply iterate over to print it.
//display
int l=objects.size();
for (int k = 0; k < l; k++) {
cout << objects[k] << endl;
}
Note: If you want your code to work for strings with spaces in between , for example: a ,b ,c ,d then use getline(cin,input); to take input from user.
You can see running code here or as a github gist.
// Example program
#include <iostream>
#include <string>
#include <vector>
#include <string>
void ParseCSV(
std::vector< std::string >& output,
const std::string& csv )
{
int q = 0;
int p = csv.find(",");
while( p != -1 )
{
output.push_back( csv.substr(q,p-q) );
q = p+2;
p = csv.find(",",q);
}
// The terminating comma of the CSV is missing
// so we need to check if there is
// one more value to be appended
p = csv.find_last_of(",");
if( p != -1 )
{
output.push_back( csv.substr( p+2 ) );
}
else
{
// there was no comma
// this could be because the list is empty
// it could also be because there is just one element in the list
if( csv.length() > 1 )
output.push_back( csv );
}
}
int main()
{
std::string test("this is my list, a, b, c, d, end of line");
std::vector< std::string > split;
ParseCSV( split, test );
for( auto& s : split )
std::cout << s << std::endl;
}
As suggested by Christophe, using stringstream is much better. No special case handling needed! I use a while loop - it seems clearer what is happening.
void ParseCSV2(
std::vector< std::string >& output,
const std::string& csv )
{
std::stringstream sst(csv);
std::string a;
while( getline( sst, a, ',' ) )
output.push_back(a);
}