C++ Tokenize part of a String - c++

Trying to tokenize a String in C++ which is read from a file, separated by commas, but I only need the first 3 data of every line.
For example:
The lines look like this:
140,152,2240,1,0,3:0:0:0:
156,72,2691,1,0,1:0:0:0:
356,72,3593,1,0,1:0:0:0:
But I only need the first 3 data of these lines. In this case:
140, 152, 2240156, 72, 2691356, 72, 3593
I'm trying to add these data into a vector I just don't know how to skip reading a line from the file after the first 3 data.
This is my current code: (canPrint is true by default)
ifstream ifs;
ifs.open("E:\\sample.txt");
if (!ifs)
cout << "Error reading file\n";
else
cout << "File loaded\n";
int numlines = 0;
int counter = 0;
string tmp;
while (getline(ifs, tmp))
{
//getline(ifs, tmp); // Saves the line in tmp.
if (canPrint)
{
//getline(ifs, tmp);
numlines++;
// cout << tmp << endl; // Prints our tmp.
vector<string> strings;
vector<customdata> datalist;
istringstream f(tmp);
string s;
while (getline(f, s, ',')) {
cout << s << " ";
strings.push_back(s);
}
cout << "\n";
}

How about checking the size of the vector first? Perhaps something like
while (strings.size() < 3 && getline(f, s, ',')) { ... }

Related

Copying unique string from one list to another list from text file

I've been asked to make a list of data from a text file of words which is equal to a specific length of letters, the user inputs the length wanted and the function would make a list of all the words that have the same length. I tried making it with a list but changed to a vector but I still couldn't manage to make it work. I've been able to load all of the words in the text file into a vector (and also when it was a list) but only inserting the words of a given length caused issues and no words were entered into the vector. Would a map be better?
vector<string> wordListA;
vector<string> wordListB;
int count = 0;
myfile.open(filename); // opening the filename given in command line
if (myfile.is_open()) //testing if the file is opened or not
{
while (getline(myfile, line))
{
string newline;
newline = line;
wordListA.push_back(newline);
}
vector<string>::const_iterator it;
it = wordListA.begin();
for (it; it != wordListA.end(); it++)
{
string c = *it;
if (c.length() == wordLength + 1)
{
wordListB.push_back(c);
count++;
}
}
cout << count << endl;
}
else
{
cout << "Error when opening file: " << filename << endl;
}
myfile.close();
}
I think my method for finding the length is wrong. I tried 4 different methods and none worked! I do think I need to be using a list data structure and not a vector.
previously I tried this which also didn't seem to work:
string newline;
newline= line; //load current line into nl
if (int(newline.length()) == wordLength + 1)
{
wordListA.push_back(newline); //append into list
}
Updated but still doesnt work:
while (getline(myfile, line))
{
string newline;
newline = line;
if (int(newline.length()) == wordlength)
{
wordListA.push_back(newline);
unique++;
}
}
int main()
{
vector<string> wordListA;
int wordLength=3;
string filename;
string line;
cin>>filename;
ifstream myfile;
myfile.open(filename); // opening the filename given in command line
if (myfile.is_open()) //testing if the file is opened or not
{
while (getline(myfile, line))
{
if(line.length()==wordLength)
wordListA.push_back(line);
}
}
else
{
cout << "Error when opening file: " << filename << endl;
}
myfile.close();
//print vector of strings
for(auto i:wordListA)
cout<<i<<endl;
}
wordLength + 1 is not required, its just enough to check if c.length()==wordLength
Also maintaining 2 vector may not be required, as the file is read with getline(), each string length can be checked against the wordLength and then only push_back
when inserting at the end many times, vector is better than list considering the time complexity

How to read a file line by line and separate the lines components?

I am new to C++ (I usually use Java) and am trying to make a k-ary heap. I want to insert values from a file into the heap; however, I am at a loss with the code for the things I want to do.
I wanted to use .nextLine and .hasNextLine like I would in Java with a scanner, but I am not sure those are applicable to C++. Also, in the file the items are listed as such: "IN 890", "IN 9228", "EX", "IN 847", etc. The "IN" portion tells me to insert and the "EX" portion is for my extract_min. I don't know how to separate the string and integer in C++ so I can insert just the number though.
int main(){
BinaryMinHeap h;
string str ("IN");
string str ("EX");
int sum = 0;
int x;
ifstream inFile;
inFile.open("test.txt");
if (!inFile) {
cout << "Unable to open file";
exit(1); // terminate with error
}
while (inFile >> x) {
sum = sum + x;
if(str.find(nextLin) == true //if "IN" is in line)
{
h.insertKey(nextLin); //insert the number
}
else //if "EX" is in line perform extract min
}
inFile.close();
cout << "Sum = " << sum << endl;
}
The result should just add the number into the heap or extract the min.
Look at the various std::istream implementations - std::ifstream, std::istringstream, etc. You can call std::getline() in a loop to read a std::ifstream line by line, using std::istringstream to parse each line. For example:
int main() {
BinaryMinHeap h;
string line, item;
int x sum = 0;
ifstream inFile;
inFile.open("test.txt");
if (!inFile) {
cout << "Unable to open file";
return 1; // terminate with error
}
while (getline(inFile, line)) {
istringstream iss(line);
iss >> item;
if (item == "IN") {
iss >> x;
sum += x;
h.insertKey(x);
}
else if (item == "EX") {
// perform extract min
}
}
inFile.close();
cout << "Sum = " << sum << endl;
return 0;
}

C++ Read file into vectors

I'm having trouble figuring out how to read a file line by line into different data type vectors. Is there a way to do this with inFile >> ? My code is below. Thanks in advance!
void fileOpen()
{
fstream inFile;
inFile.open(userFile);
// Check if file open successful -- if so, process
if (!inFile.is_open()) {cout << "File could not be opened.";}
else
{
cout << "File is open.\n";
string firstLine;
string line;
vector<char> printMethod;
vector<string> shirtColor;
vector<string> orderID;
vector<string> region;
vector<int> charCount;
vector<int> numMedium;
vector<int> numLarge;
vector<int> numXL;
getline(inFile, firstLine); // get column headings out of the way
cout << firstLine << endl << endl;
while(inFile.good()) // while we are not at the end of the file, process
{
while(getline(inFile, line)) // get each line of the file separately
{
for (int i = 1; i < 50; i++)
{
inFile >> date >> printMethod.at(i);
cout << date << printMethod.at(i) << endl;
}
}
}
}
}
Before you use vector.at(i) in your case you should be sure that your vector is long enough cause at will generate out of range exception. As I can see from your code your vector printMethod contains no more than 50 elements so you can resize vector printMethod before use e.g.
vector<char> printMethod(50);
or
vector<char> printMethod;
printMethod.resize(50);
If you're planning to use a variable number of elements more than 50 you should use push_back method like #Phil1970 recommended e.g.
char other_data;
inFile >> date >> other_data;
printMethod.push_back(other_data);

c++ counting how many words in line

I'm using this code to count lines of the text, but I need to count also words and show to console how many words is in each row.
int main(int argc, char *argv[]){
ifstream f1("text.txt"); ;
char c;
string b;
int numchars[10] = {}, numlines = 0;
f1.get(c);
while (f1) {
while (f1 && c != '\n') {
// here I want to count how many words is in row
}
cout<<"in row: "<< numlines + 1 <<"words: "<< numchars[numlines] << endl;
numlines = numlines + 1;
f1.get(c);
}
f1.close();
system("PAUSE");
return EXIT_SUCCESS;
}
To count the number of lines and number of words you could try and brake it down to two simple tasks: first read each line from the text using getline() and , secondly, extract each word from a line using stringstream, after each successful (read line or extract word) action you could increment two variables that represent the number of lines and words.
The above could be implement like so:
ifstream f1("text.txt");
// check if file is successfully opened
if (!f1) cerr << "Can't open input file.";
string line;
int line_count = 0
string word;
int word_count = 0;
// read file line by line
while (getline(f1, line)) {
// count line
++line_count;
stringstream ss(line);
// extract all words from line
while (ss >> word) {
// count word
++word_count;
}
}
// print result
cout << "Total Lines: " << line_count <<" Total Words: "<< word_count << endl;

ifstream does not return the correct int value

I want to make a factory class which creates and loads objects in from a file;
however when I try to read in a int from the file it appears to return a incorrect number.
std::ifstream input;
input.open("input.txt");
if (!input.is_open()){
exit(-1);
}
int number;
input >> number;
cout << number;
input.close();
When I enter a number in the input.txt file it shows: -858993460.
Changing the number doesn’t make a difference and when I use cin instead of ifstream it works like it should. I'm probably just missing something really stupid, but I can't figure it out.
Edit: Using getLine() works like it should. I guess there is a problem using >>.
Here is another solution to open a file a read it line by line:
string line;
ifstream myfile("input.txt");
if (myfile.is_open())
{
while ( getline (myfile,line) )
{
cout << line << '\n'; // Use this to verify that the number is outputed
// Here you can transform your line into an int:
// number = std::stoi(line);
}
// myfile.close(); Use this if you want to handle the errors
}
else cout << "Unable to open file";
If you don't want to read line by line, just remove the while
...
getline(myfile,line);
number = std::stoi(line);
...
Read multiple numbers in one line
Image that your input file is like this:
1, 2.3, 123, 11
1, 2
0.9, 90
Then, you can use this piece of code to read all the numbers:
string line;
ifstream myfile("input.txt");
string delimiter = ", ";
if (myfile.is_open())
{
while ( getline (myfile,line) )
{
cout << "Reading a new line: " << endl;
size_t pos = 0;
string token;
while ((pos = line.find(delimiter)) != string::npos) {
token = line.substr(0, pos);
cout << token << endl; // Instead of cout, you can transform it into an int
line.erase(0, pos + delimiter.length());
}
}
}
else cout << "Unable to open file";
The output will be:
Reading a new line:
1
2.3
123
11
Reading a new line:
1
2
Reading a new line:
0.9
90
New solution that may work =)
I didn't test this, but it works apparently:
std::ifstream input;
double val1, val2, val3;
input.open ("input.txt", std::ifstream::in);
if (input >> val1 >> val2 >> val3) {
cout << val1 << ", " << val2 << ", " << val3 << endl;
}
else
{
std::cerr << "Failed to read values from the file!\n";
throw std::runtime_error("Invalid input file");
}
To check the IO, see http://kayari.org/cxx/yunocheckio.html