Create a vector of strings from file c++ - c++

I am trying to input three pieces of information from a .txt file.
First column is the course mark.
Second column is the course code.
Third column(s) is the course name.
I would like to store these as 3 vectors of strings.
Would using stringstream be a good option here? and maybe iterators?
The .txt file is like
65.6 10071 Mathematics 1
66.7 10101 Dynamics
60.0 10121 Quantum Physics and Relativity
66.9 10191 Introduction to Astrophysics and Cosmology
... ... ...
and my code so far is
#include<iostream>
#include<iomanip>
#include<fstream>
#include<cmath>
#include<algorithm>
#include<string>
#include<iterator>
#include<sstream>
#include<vector>
//Main Function
int main()
{
//Define variables
std::string course_mark, course_code, course_name;
std::vector<std::string> course_mark_vector;
std::vector<std::string> course_code_vector;
std::vector<std::string> course_name_vector;
std::string data_file[100];
// Ask user to enter filename
std::cout<<"Enter data filename: ";
std::cin>>data_file;
int i{0};
// Open file and check if successful
std::fstream course_stream(data_file);
if(course_stream.is_open()) {
while (!course_stream.eof()) //while the end of file is NOT reached
{
//I have 2
getline(course_stream, course_mark, ' ');
course_mark_vector.push_back(course_mark);
getline(course_stream, course_code, ' ');
course_code_vector.push_back(course_code);
getline(course_stream, course_name, '\n');
course_name_vector.push_back(course_name);
i += 1; //increment number of lines
}
course_stream.close(); //closing the file
std::cout << "Number of entries: " << i-1 << std::endl;
}
else{
std::cout << "Unable to open file. Please run again" << std::endl;
return 1;
}
Any help would be greatly appreciated

Would using stringstream be a good option here?
Yes.
and maybe iterators?
There is no need for iterators in this case.
Try this:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <iomanip>
//Main Function
int main()
{
//Define variables
std::string course_mark, course_code, course_name, data_file, line;
std::vector<std::string> course_mark_vector, course_code_vector, course_name_vector;
int i = 0;
// Ask user to enter filename
std::cout << "Enter data filename: ";
std::cin >> data_file;
// Open file and check if successful
std::ifstream course_stream(data_file);
if (!course_stream.is_open())
{
std::cout << "Unable to open file. Please run again" << std::endl;
return 1;
}
while (std::getline(course_stream, line)) //while the end of file is NOT reached
{
std::istringstream iss(line);
iss >> course_mark;
course_mark_vector.push_back(course_mark);
iss >> course_code;
course_code_vector.push_back(course_code);
std::getline(iss >> std::ws, course_name);
course_name_vector.push_back(course_name);
++i; //increment number of lines
}
course_stream.close(); //closing the file
std::cout << "Number of entries: " << i << std::endl;
return 0;
}
Demo

Related

replacing string based on user input c++

i want to receive an input from user and search a file for that input. when i found a line that includes that specific word, i want to print it and get another input to change a part of that line based on second user input with third user input. (I'm writing a hospital management app and this is a part of project that patients and edit their document).
i completed 90 percent of the project but i don't know how to replace it. check out following code:
#include <iostream>
#include <stream>
#include <string.h>
#include <string>
using namespace std;
int main(){
string srch;
string line;
fstream Myfile;
string word, replacement, name;
int counter;
Myfile.open("Patientlist.txt", ios::in|ios::out);
cout << "\nEnter your Name: ";
cin.ignore();
getline(cin, srch);
if(Myfile.is_open())
{
while(getline(Myfile, line)){
if (line.find(srch) != string::npos){
cout << "\nYour details are: \n" << line << endl << "What do you want to change? *type it's word and then type the replacement!*" << endl;
cin >> word >> replacement;
}
// i want to change in here
}
}else
{
cout << "\nSearch Failed... Patient not found!" << endl;
}
Myfile.close();
}
for example my file contains this line ( David , ha , 2002 ) and user wants to change 2002 to 2003
You cannot replace the string directly in the file. You have to:
Write to a temporary file what you read & changed.
Rename the original one (or delete it if you are sure everything went fine).
Rename the temporary file to the original one.
Ideally, the rename part should be done in one step. For instance, you do not want to end up with no file because the original file was deleted but the temporary one was not renamed due to some error - see your OS documentation for this.
Here's an idea:
#include <iostream>
#include <fstream>
#include <string>
#include <cstdio>
using namespace std;
void replace(string& s, const string& old_str, const string& new_str)
{
for (size_t off = 0, found_idx = s.find(old_str, off); found_idx != string::npos; off += new_str.length(), found_idx = s.find(old_str, off))
s.replace(found_idx, old_str.length(), new_str);
}
int main()
{
const char* in_fn = "c:/temp/in.txt";
const char* bak_fn = "c:/temp/in.bak";
const char* tmp_fn = "c:/temp/tmp.txt";
const char* out_fn = "c:/temp/out.txt";
string old_str{ "2002" };
string new_str{ "2003" };
// read, rename, write
{
ifstream in{ in_fn };
if (!in)
return -1; // could not open
ofstream tmp{ tmp_fn };
if (!tmp)
return -2; // could not open
string line;
while (getline(in, line))
{
replace(line, old_str, new_str);
tmp << line << endl;
}
} // in & tmp are closed here
// this should be done in one step
{
remove(bak_fn);
rename(in_fn, bak_fn);
remove(out_fn);
rename(tmp_fn, in_fn);
remove(tmp_fn);
}
return 0;
}
One possible way:
Close the file after you read it into "line" variable, then:
std::replace(0, line.length(), "2002", "2003")
Then overwrite the old file.
Note that std::replace is different from string::replace!!
The header is supposed to be <fstream> rather than <stream>
you can't read and write to a file simultaneously so I have closed the file after reading before reopening the file for writing.
instead of updating text inside the file, your line can be updated and then written to file.
#include <iostream>
#include <fstream>
#include <string.h>
#include <string>
using namespace std;
int main(){
string srch;
string line, line2;
fstream Myfile;
string word, replacement, name;
int counter;
Myfile.open("Patientlist.txt", ios::in);
cout << "\nEnter your Name: ";
cin.ignore();
getline(cin, srch);
if(Myfile.is_open())
{
while(getline(Myfile, line)){
if (line.find(srch) != string::npos){
cout << "\nYour details are: \n" << line << endl << "What do you want to change? *type it's word and then type the replacement!*" << endl;
cin >> word >> replacement;
int index = line.find(word);
if (index != string::npos){
Myfile.close();
Myfile.open("Patientlist.txt", ios::out);
line.replace(index, word.length(), replacement);
Myfile.write(line.data(), line.size());
Myfile.close();
}
}
// i want to change in here
}
}else
{
cout << "\nSearch Failed... Patient not found!" << endl;
}
}

read txt file and put each line into difference Vector. C++ [duplicate]

This question already has answers here:
How can I read and parse CSV files in C++?
(39 answers)
Closed 5 years ago.
I need a help with my code. I am trying to read txt file and then I want to put each line into difference vector. For example, I have a file like this.
123, 123, 431, 5123, 12312
25316, 64234, 1231, 124123
I want to put the first line to the first vector. 123|123|431|
and the second vector. 25316|64234|
I already tried seekg. But, it doesn't work. What is the best way to do it? Later, I will use these vector with Linkedlist.
Here is my code.
#include <iostream>
#include <fstream>
#include <stdlib.h>
using namespace std;
int main()
{
string fname;
cout << "Please enter file name!" << endl;
cin >> fname;
string line;
fstream myfile;
myfile.open(fname);
if (myfile.is_open())
{
myfile.seekg(0, ios_base::end);
int length = myfile.tellg();
cout << length <<endl;
}
else
{
cout << "Unable to open your file!" << endl;
}
}
First, on handling the lines separately:
As explained by others you should not use std::basic_istream::seekg(). It works with absolute positions in the streambuf and would require way more code for your use-case than necessary (you would have to find newlines in the stream, split and so on).
Use getline().
Example:
if (myfile.is_open())
{
short line_num = 1;
for (std::string line; std::getline(myfile, line); ) {
cout << "Line number: " << line_num << " Value: " << line << std::endl;
line_num++;
}
}
Output:
mindaugasb#c_cpp:~/workspace/StackOverflow/ReadingAFileLineByLine $ ./r2v.exe
Please enter file name!
f
Line number: 1 Value: 123, 123, 431, 5123, 12312
Line number: 2 Value: 25316, 64234, 1231, 124123
Second on pushing the lines, item at a time, to a vector:
I will assume there will be two vectors, for the two lines in the input file. If there are more lines, you will need to create more vectors, possibly by implementing a function that will accept as string (obtained from the input file) and return a vector in the form you want it. Example:
vector<string> line2Vec(string line)
{
char * tokens;
char * line_chararr = const_cast< char *>(line.c_str());
tokens = strtok(line_chararr, ", ");
vector<string> vs;
while (tokens != NULL)
{
vs.push_back(tokens);
tokens = strtok (NULL, ", ");
}
return vs;
}
Attention - I do not say that this is perfect Cpp code or a perfect solution to your problem. However it is A solution to how I understood the problem based on what was written. Here is the full version to play around with:
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <sstream>
#include <vector>
#include <string.h>
using namespace std;
vector<string> line2Vec(string line)
{
cout << line << endl;
char * tokens;
char * line_chararr = const_cast< char *>(line.c_str());
tokens = strtok(line_chararr, ", ");
vector<string> vs;
while (tokens != NULL)
{
vs.push_back(tokens);
tokens = strtok (NULL, ", ");
}
return vs;
}
int main()
{
string fname;
cout << "Please enter file name!" << endl;
cin >> fname;
fstream myfile;
myfile.open(fname);
if (myfile.is_open())
{
for (std::string line; std::getline(myfile, line); ) {
line2Vec(line);
}
}
else
{
cout << "Unable to open your file!" << endl;
}
}

Numbering Lines in a File With C++

I wrote a quick C++ program that asks the user for a input text file and an output text file. The program is then supposed to number the lines in the file on the left margin. However, I cannot seem to get it working properly, it compiles fine but does not number the lines like it is supposed to. I believe it is a logical error on my part. I am also not too familiar with file i/o in C++ as I am just learning it now using old school textbooks.
Here is the file:
#include <iostream>
#include <fstream>
#include <string>
#include <cassert>
#include <cstdio>
using namespace std;
int main(void)
{int i = 0 , num = 1;
string inputFileName;
string outputFileName;
string s;
ifstream fileIn;
ofstream fileOut;
char ch;
cout<<"Enter name of input file: ";
cin>>inputFileName;
cout<<"Enter name of output file: ";
cin>>outputFileName;
fileIn.open(inputFileName.data());
fileOut.open(outputFileName.data());
assert(fileIn.is_open() );
assert(fileOut.is_open() );
while (!(fileIn.eof()))
{ch=fileIn.get();
if (ch=='\n') num++;
fileOut << num << "\n";
s.insert(i,1,ch); //insert character at position i
i++;
}
fileOut << s;
fileIn.close();
fileOut.close();
return 0;
}
If anyone could point me in thr right direction or give me some tips I would be eternally grateful.
int i = 0;
string line;
while (getline(infile, line))
{
outfile << (i++) << " " << line << "\n";
}

How to open any input file whether it contains words or numbers and prints it out. C++

So Lets say this is what the input file contains
12
Hello
45
54
100
Cheese
23
How would I print it out on the screen in that order.
This is what I had but it skips some lines.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
int number;
string word;
int loop = 0;
ifstream infile;
infile.open("arraynumbers.txt");
while(infile >> number >> word)
{
if( infile >> number)
{
cout << number << endl;
}
if(infile >> word)
{
cout << word << endl;
}
}
return 0;
}
I suggest using www.cplusplus.com to answer these questions.
However, you are on the right track. Since you are just outputting the contents of the file to stdout, I suggest using readline() and a string. If you need to access the numeric strings as ints, use the atoi() function.
Example:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
string line;
ifstream file("arraynumber.txt");
if (file.is_open()) {
while (getline(file, line)) {
cout << line << endl;
}
file.close();
} else cout << "Error opening arraynumber.txt: File not found in current directory\n";
return 0;

replacing an entire line in from a file C++

So I've been playing with code and I'm stuck with finding how to replace the line found. I'm able to find the name and add the 'new_gpa' to the section but it outputs the final result in the same file but without replacing the original score and name.
how could I remove the original line found along with the gpa? and also store the new values to the file.
cristian 2.1
rachel 3.0
name search: cristian
new file:
cristian 2.1
rachel 3.0
cristian 4.1
The code is below.
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <vector>
#include <fstream>
#include <sstream>
#include <cstring>
using namespace std;
int main()
{
string name;
int offset;
string line;
ifstream read_file;
read_file.open("alpha.dat", std::ios_base::app);
cout << "Please enter your name: \n";
cin>> name;
if (read_file.is_open())
{
while(!read_file.eof())
{
getline(read_file,line);
if((offset = line.find(name)) != string::npos)
{
cout <<"the word has been found: \n";
//cout << line //example to display
//new code
istringstream iss ( line );
string thisname;
double gpa;
double new_gpa = 2.1;
if( iss >> thisname >> gpa)
{
if (thisname == name)
{
cout << name <<endl;
cout << gpa <<endl;
ofstream myfile;
myfile.open("alpha.dat",std::ios_base::app);
myfile << " \n" << name << " " << gpa+ new_gpa;
myfile.close();
read_file.close();
}
}
}
}
}
return 0;
}
You open file with std::ios_base::app, which means all you output operations are performed at the end of file, appending the content to the current file. But what you want to do is modify the data at the original place. So you should open file with std::ios_base::in, and function seekp can help you in the next step.