Reading File in C++ with Member Functions - c++

int DataSource::insertData(char* fileName){
double vel, tireAngle, timeStamp;
string inputLine;
int i=0;
ifstream inFile;
inFile.open(fileName);
if (!inFile.good())
{
cout << "Could not open file " << fileName << endl;
return 0;
}
while(inFile.good())
{
getline(inFile, inputLine);
if(inFile.fail())
{
break;
}
istringstream lineStream(inputLine);
lineStream >> timeStamp >> vel >> tireAngle;
source.push_back(Input(vel, tireAngle, timeStamp));
++i;
}
inFile.close();
return i;
};
I'm trying to pass in the file name, open the file and parse through each line. The Input class holds the three double values, and source is a vector of type Input. I have vector, iostream,fstream,string,sstream,climits #included, along with std namespace.
So my first issue is the file not opening, I know that the right filename is being passed in. The error I'm getting is:
"Could not open file input1.txt
libc++abi.dylib: terminating with uncaught exception of type std::out_of_range: vector"
For the vector, I googled the error and I think I'm accessing a bad vector, which is either because maybe I haven't properly initialized the vector -Input- source (formatting wont let me put the "greater than, less than sign") or I'm using the wrong syntax.
This is my first post so I'm sorry if this is a bad question/formatting, but any help would be appreciated.

I don't think you should be using good() to check if the input is valid. Try changing
if (!inFile.good())
to
if (!inFile.is_open())
and changing
while(inFile.good())
{
getline(inFile, inputLine);
to
while(getline(inFile, inputLine))

Related

Why won't my cout statements print after opening a textfile?

I am trying to write a program where I read a text file and then take each line in the textfile and store them in a string vector. I think I am able to open the textfile however I noticed that after I open the textfile anything after that point does not execute. For example I have a cout statement at the end of my main function that outputs when I enter the name of a file that doesn't exist. However if I type in a file name does exists I get no output from the last cout statement. Anyone know why this is? Thanks!
int main()
{
vector<string>line;
string fileName = "test.txt";
ifstream myFile(fileName.c_str());
int i = 0;
int count = 0;
vector<string>lines;
cout << "test" << endl;
if (myFile.is_open())
{
cout << "test2" << endl;
while (!myFile.eof())
{
getline(myFile, lines[i],'\n');
i++;
}
myFile.close();
}
if (!myFile.is_open())
{
cout<< "File not open"<< endl;
}
myFile.close();
cout << "Test3" <<endl;
return 0;
}
Try this:
string fileName = "test.txt";
ifstream myFile(fileName); // .c_str() not needed - ifstream can take an actual string
vector<string> lines;
string line; // temporary variable for std::getline
while (getline(myFile, line)) {
lines.push_back(line); // use push_back to add new elements to the vector
}
As pointed out in the comments, the most likely reason that your program seems to "end" prematurely is that it's crashing. std::getline takes a reference-to-string as its second argument. In your code, your vector is empty; therefore lines[i] for any i returns a reference to invalid memory. When getline tries to access that memory, the program crashes.
If you want an exception thrown when you try to access an out-of-bounds index of a vector, use lines.at(i) instead of lines[i].
You need to use push_back() because your initial vector is empty and, you can not use indexes on empty vector. If you do so, it will leads to undefined behavior.
std::ifstream input( "filename.ext" );
std::vector<std::string> lines;
for( std::string line; getline( input, line ); )
{
lines.push_back(line);
}

Can I redirect an ifstream to cin?

I have a program that reads input from the terminal and the stream from cin is used in multiple classes for parsing at various levels.
Instead of using cin for getting the data from the terminal, I want to read in a file that has the information I need to parse, but I don't want to modify all my header and .cpp files to accept an ifstream& parameter.
To keep the existing code in place I'm trying to simply redirect the ifstream to cin, but don't know how.
So assume I have the following in main:
ifstream inFile("myfile.txt", ifstream::io);
string line;
while(getline(inFile, line))
{
char firstChar;
inFile >> firstChar;
cout << firstChar;
inFile.ios::rdbuf(cin.rdbuf());
Continue myFile;
}
In my continue.cpp I'm just doing:
Continue()
{
string line;
cin >> line;
cout << "---remaining line: " << line << "\n";
}
However it's only printing the first char from main.
Simply swap pointers to std::streambuf:
ifstream file("myfile.txt");
string line;
if (file.is_open()) {
cin.rdbuf(file.rdbuf()); // swap
cin >> line;
}
std::cout << line;
istream objects read from a std::streambuf, and that can be swapped in an out. The relevant member function is .rdbuf
You can also redirect the underlying C stdin file handle to a different file, this will also affect your cin:
freopen ("myfile.txt", "r", stdin);
Here's a very quick and easy way to do it.
If your file is called "file.txt", the code would be:
fstream cin("file.txt");
This way, everything that's from the file would be redirected to cin >>

find word in a text in C++ and print some next specific lines

I wrote a code in C++ that writes a .txt file.
Then I want to open the code again and give some information, so I can get a new text depending on what I gave as an input.
For example I want to give the name of a month, and print in another .txt file all the lines that came after the word "November".
I found some solutions, but none of them worked for me!
One solution that I found on stack overflow is the following:
void Keyword(ifstream & stream, string token) {
string line;
while (getline(stream, line)) {
if (line.find(token) != string::npos) {
cout << line << endl;
}
}
cout << token << " not found" << endl;
}
I can't print the next lines with the code above.
Any suggestion would be helpful!
Thanks!
If you want to perform operations on files such as 'Read' and/or 'Write',you might want to search on the net(or if you have a C++ book) on topics such as "File I/O operations using C++". Anyways moving on, C++ has 2 basic classes to handle files which are ifstream and ofstream. And to use them you have to include ethier the header fstream(i.e #include<fstream>) or include them separately as #include<ifstream> and #include<ofstream>. ifstream is basically used for all input operations such as reading files etc. Similarly ofstream is used for all output operations such as writing data to files.
You can open a file and write data to it by doing the following,
ofstream myFile("filename");// Create an instance of ofstream and open file for writing data
and to write data to the file use the << operator like below,
myFile<<data;
Similarly, You can open a file and read data as follows,
ifstream myFile("filename");//Create an instance of ifstream and open file to read data
and to read data from the file use the >> operator as shown below,
myFile>>data;
You can also open a file using the method void open(const char *filename, ios::openmode mode); as shown below,
//Writing only
ofstream outFile;
outFile.open("filename.txt",ios::out);
//Reading only
ifstream inFile;
inFile.open("filename.txt",ios::in);
//For reading and writing
fstream file;
file.open("filename.txt",ios::in|ios::out);
//For closing File
outFile.close();
//or
inFile.close();
//or
file.close();
Note the open() method takes various flags such as ios::in for reading mode, ios::out for writing mode, ios::app for adding data to the end etc.
All of these can also combined by using the bit OR operator | as shown below,
outFile.open("filename.txt",ios::out|ios::app);
There is a lot more in IO. I just covered the things required to start.
Here is the solution to your problem. Try to understand it.
#include<iostream>
#include<fstream>
#include<cstring>
using namespace std;
int main()
{
ofstream outFile;
ifstream inFile;
char fileName[10],data[50];
int noLines;
cout<<"Enter Month:"<<endl;
cin>>fileName;
cout<<"Enter Number of lines you want to enter:"<<endl;
cin>>noLines;
outFile.open(fileName,ios::out);
cout<<fileName<<"(Enter Data):";
for(int i=0;i<=noLines;i++)
{
cin.getline(data,50);
outFile<<data<<endl;
}
outFile.close();
cout<<"Openening "<<fileName<<" :"<<endl;
inFile.open(fileName,ios::in);
for(int i=0 ;i<=noLines ;i++)
{
inFile.getline(data,50);
cout<<data<<endl;
}
inFile.close();
return 0;
}
OP has found most of the solution already:
string line;
while (getline(stream, line)) {
if (line.find(token) != string::npos) {
cout << line << endl;
}
}
cout << token << " not found" << endl;
But this only prints the lines with the keyword. And always prints the "not found" message. Ooops.
Instead I pitch:
string line;
bool found = false;
while (!found && getline(stream, line))
{ // search for keyword
if (line.find(token) != string::npos)
{
found = true; // found keyword. Stop looking
}
}
if (found)
{ // print out all remaining lines in the file
while (getline(stream, line))
{
cout << line << endl;
}
}
else
{
cout << token << " not found" << endl;
}
The above splits the finding of the token and the printing of the remaining file into two stages for readability. It can be compressed into one loop, but two things make this a sucker bet:
this program will be IO bound. It will spend the vast majority of its time reading the file, so little tweaks that do not address getting the file into memory are wasted time.
combining the loops would require the addition of logic to the loop that would, over along run, dwarf the minuscule cost of switching loops.
Try this:
http://www.cplusplus.com/doc/tutorial/files/
and this:
http://www.cplusplus.com/forum/beginner/14975/
It's about reading and writing files in c++ and about searching in files.

C++ read from file into a vector

I am working on a program that should read from a file and store the contents of that file in a vector. I must read the contents of the .txt file and push the strings back into a vector before it reaches a ' '. If it is a space you will skip that part of the file and continue pushing back the contents after the space. Does anybody know what function to use to read from a file and put the contents into a vector or array? Thanks for your time.
int main()
{
Code mess;
ifstream inFile;
inFile.open("message1.txt");
if (inFile.fail()) {
cerr << "Could not find file" << endl;
}
vector<string> code;
string S;
while (inFile.good()) {
code.push_back(S);
}
cout << mess.decode(code) << endl;
return 0;
}
Basically you can also do it like this :
std::ifstream fh("text.txt");
std::vector<std::string> vs;
std::string s;
while(fh>>s){
vs.push_back(s);
}
for(int i=0; i<vs.size(); i++){
std::cout<<vs[i]<<std::endl;
}
You should change your reading code to
while (inFile >> S) {
code.push_back(S);
}
Your current code doesn't read anything into your S variable.
Regarding loop conditions while (inFile.good()) see this Q&A please:
Why is iostream::eof inside a loop condition considered wrong?
Using std::iostream::good() has more or less the same issues.

What is a better way to read a file until it ends than using istream eof?

I have read that using istream eof is "buggy" and not a "formal" way of writing code, so what is a better code to use? For example, I have the following code:
using namespace std; //I've heard this is bad practice also
int main(){
string line;
ifstream myfile("example.txt");
while(!myfile.eof()){
getline(myfile, line);
}//while
//do something with line
}//main
What should I replace !myfile.eof() with? Thanks!
if (ifstream myfile("example.txt"))
{
while (getline(myfile, line))
{
...
}
if (!eof(myfile))
std::cerr << "error before end of input file\n";
}
else
std::cerr << "error opening input file\n";
The key is to realize that getline returns a reference to the stream, and that a boolean operation on the stream reference returns true if the stream is OK and false if the previous operation failed. That includes a failure to open the file.
while (getline(myfile, line))
{
// do something with line
}
I don't know why your original example had "do something" outside of the while loop.