I can't seem to get the program to call the second function. The program is supposed to open up a joke file, read it and display it for the user. Then close the file, open a second punchline file, seek the last line and read it to the user. I'm getting it to open the first file and display the joke but it doesn't do anything after that. Any idea what I'm doing wrong? Thank you in advance.
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
using namespace std;
// Function prototypes
void displayAllLines(ifstream &joke); // Display joke
void displayLastLine(ifstream &punchline); // Display punchline
int main()
{
ifstream jokeFile, punchLineFile;
// Open the joke file
jokeFile.open("joke.txt", ios::in);
// Make sure the file actually opens
if (!jokeFile)
cout << "Error opening file." << endl;
// Call on function to display the joke
displayAllLines(jokeFile);
// Close the joke file
jokeFile.close();
// Open the punchline file
punchLineFile.open("punchline.txt", ios::in);
// Make sure the file actually opens
if (!punchLineFile)
cout << "Error obtaining the punchline, sorry :(." << endl;
// Call on function to display punchline
displayLastLine(punchLineFile);
// Close the punchline file
punchLineFile.close();
system("pause");
return 0;
}
// function to display the joke
void displayAllLines(ifstream &joke)
{
string input;
// Read an item from the file
getline(joke, input);
// Display the joke to the user
while (joke)
{
cout << input << endl;
getline(joke, input);
}
}
// function to display the punchline
void displayLastLine(ifstream &punchline)
{
string input;
punchline.seekg(0L, ios::beg); // Fast forward to the end of the file
punchline.seekg('/n', ios::cur); // rewind the the new line character
getline(punchline, input); // Read the line
cout << input << endl; // display the line
}
seekg takes a offset in the file - you are passing it '/n' which is not an offset.
Because you used a forward slash (/), rather than a backslash (\), the compiler is treating '/n' as a Unicode or multibyte character sequence and moving forward 12142 bytes (at least in VS 2013), which is probably past the end of your file.
Also your comment says "Fast forward to the end of the file", but you are using ios:beg which is the beginning of the file.
punchline.seekg(0L, ios::beg); // Fast forward to the end of the file
No, it doesn't. This fast forwards to the beginning of the file, that's what "ios::beg" means.
punchline.seekg('/n', ios::cur); // rewind the the new line character
This does not rewind to the newline character, the comment notwithstanding. It does not rewind to the first newline character, it doesn't rewind it to the last newline character. seekg() always positions the get pointer at a fixed offset, as indicated. And, here, the fixed offset is utterly meaningless.
Your compiler is likely complaining about this line. Do not ignore your compiler's complaints, even if it still compiles the code despite them.
See this question for one possible algorithm to find the last line in the file.
I faced this problem when i tried to call a particular function i but it everywhere in the program to be called from there but it doesn't until i discovered that there was an error with object code files "don't worry it is a simple problem".
the solution:
is simply just shutdown the environment you work on and open it again or rebuild your entire project. then you call will be executed successfully
Related
I'm trying to use same fstream object for first write the file and after that read the file.
when I'm using below code then the codes of writing the file is working but I'm getting junk output instead of texts which written in the file.
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
int main() {
fstream file;
file.open("test.txt",ios::in|ios::out| ios::trunc);
if (!file) {
cout << "Error";
}
else {
cout << "success";
file <<"\n\n1st Line\n 2nd line \n 3rd line\n";
string filecontent;
while (file.good()) {
getline(file, filecontent);
cout << filecontent << endl;
}
}
return 0;
}
Output
This code has two separate problems. The first (which others have already pointed out to at least some degree) is that your loop isn't detecting the end of the file correctly. In fact, almost any time you use while (!file.eof()) or while (file.good()), it's going to be a mistake--it won't detect end of file at the right time, so (for example) when you reach the end of the file, you won't detect it at the right time, and you'll see the last item in the file appear to be read twice before the loop exits.
In addition to that, however, you have a problem in that you're writing to the file, then immediately trying to read. That's simply not allowed--you want to do a seek any time you switch between reading and writing.
In this case, you have a bit of a further problem. Since you've just written data into the file, your file's current position is at the end of the file. So even if you could just start reading without seeking, you'd start reading from the end of the file. That, of course, would immediately fail.
So you also really need to seek back to the beginning of the file to be able to read it back in.
So, the big changes here are adding a line like: file.seekg(0); after you finish writing, but before you start to try to read that data back in, and then changing your reading loop to something like:
while (getline(file, filecontent)) {
cout << filecontent << endl;
}
One last point: although it's not going to make a big difference in this case, I'd advise using "\n" instead of std::endl. std::endl writes a new-line and flushes the file buffer. When you're writing to the screen it won't make any real difference, but when writing to a normal file flushing the buffer unnecessarily can and will slow your code substantially (10x slower is pretty common).
The example is taken from:
[http://www-h.eng.cam.ac.uk/help/tpl/languages/C++/1AComputing/Mich/index.php?reply=extraReadingfromfiles#extraReadingfromfilesanchor][1]
I wrote the code without the while loop to read file, the example used getline(stream, strgvar), but this is not admited by the editor
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
string message;
ifstream fin; // variable to store information about a file
fin.open("s.txt"); // trying to open file for reading
// next line would try to check if file has been opened succesfully
if (not fin.good())
{
cout << "\n\t Couldn't open the s file." << endl;
cout << "\n\t It needs to be in the same folder as your program."
<<endl;
return 1; // In the main function this line quits from the
whole program.
}
// we have menaged to open the file. Now we'll read a line from the file into the string
while (message!="works!")
{
fin >> message;
cout << message << " ";
}
//getline(fin,message);
}
My questions is why the line now commented is rejected ?
fin>>message;
The stream extraction operator '>>' is used when you want to read a single word from file.
Find complete explanation at : https://www.google.com/amp/s/www.geeksforgeeks.org/cpp-program-read-file-word-word/amp/
While
getline(fin,message);
In this, a full line from the file will be read in message variable. It will continue reading and assigning file contents till a '\n' (Line Deliminator) character does not appear. And thats why you getline() statement is rejected.
For complete explanation visit : http://www.cplusplus.com/forum/windows/48212/
Your program is expected to read a word at a time. And to accomplish this, fin>>mesage is used. Basically stream extraction operator read the contents till a space appears, and hence it is used to read single word.
And if you still want to use getline (), then add a third parameter to your function call as space character ' '.
Like
getline(fin,message,' '); // and done
Basically the third parameter of getline function is Deliminator, by default it is '\n', but if you want to define your own Deliminator, you can do so by providing third parameter. It will read the contents of file till the Deliminator does not occurs while reading.
To use std::getline() include <string> in the header.
https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/2whx1zkx(v=vs.100)
istream also has a getline. More details here
https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-6.0/aa277361(v=vs.60)
As far as I know, stream.ignore(n, 'n') should ignore an (n) amount of characters or if ā\nā is reached, and skip over to the next line, however, when I run the next code:
// include...
void insertInfo(int info) {
std::fstream stream("infoFile.txt"); // Open the file
while (!stream.eof()) {
std::string a{};
// getline(stream, a); <--- Tried this, didn't work either
stream.ignore(99, '\n');
} // Skip to the last line without any number, in theory
std::cout << info << std::endl; // Check if the output it's correct (Which is)
stream << info; // Insert the info
stream.close(); // Close the file
}
void main() //Main
{
std::cout << "Enter your name, followed by the info you want to add to infoFile:" << std::endl;
std::string info, temp = "";
std::getline(std::cin, temp); // Get the info input
std::stringstream sstream;
sstream << temp;
sstream >> temp >> info; // Remove the name keeping only the info
temp = ""; // ^
std::string::size_type sz;
insertInfo(stoi(info, &sz)); // Convert info string into an integer and insert it in infoFile
}
The console prints out the "info" correct value, however, when I check info.txt, in which I previously wrote a '0' on, you don't see any change.
I tried removing the "ignore" function and it overwrites the 0, which is exactly what I was trying to prevent.
I also tried using "getline" function but the same thing happens.
What is the error here?
Problem
Cannot write to file.
Why
void insertInfo(int info) {
std::fstream stream("infoFile.txt"); // Open the file
Opens file with default permissions, which includes reading. The C++ Standard says I should expect "r+" behaviour and the C Standard says a file opened with "r+" behaviour must exist in order to be read (Someone please add a link if you have one). You cannot create a new file. This is problem 1. The Asker has dealt with this problem by providing a file.
Note: take care when working with files via relative paths. The program's working directory may not be where you think it is. This is problem 1a. It appears that the Asker has this taken care of for the moment.
while (!stream.eof()) {
Common bug. For more details see Why is iostream::eof inside a loop condition considered wrong? In this case since all you're looking for is the end of the file, the fact that the file hasn't been opened at all or has encountered any read errors is missed. Since a file in an error state can never reach the end of the file this quickly becomes an infinite loop. This is problem 2.
std::string a{};
// getline(stream, a); <--- Tryied this, didn't work neither
stream.ignore(99, '\n');
Always test IO transactions for success. This call can fail unchecked.
} // Skip to the last line without any number, in theory
Assuming nothing has gone wrong, and since we're not checking the error state assuming's all we can do, the file has reached the end and is now in the EOF error state. We can't read from or write to the stream until we clear this error. This is problem number 3 and likely the problem the Asker is struggling with.
std::cout << info << std::endl; // Check if the output it's correct (Wich is)
stream << info; // Insert the info
This can fail unchecked.
stream.close(); // Close the file
This is not necessary. The file will be closed when it goes out of scope.
}
Solution
void insertInfo(int info) {
std::fstream stream("infoFile.txt"); // Open the file
while (!stream.eof()) {
stream.ignore(99, '\n');
} // Skip to the last line without any number, in theory
std::cout << info << std::endl; // Check if the output it's correct (Wich is)
stream.clear(); // Added a call to clear the error flags.
stream << info; // Insert the info
stream.close(); // Close the file
}
Now we can write to the file. But let's improve this shall we?
void insertInfo(int info) {
std::fstream stream("infoFile.txt");
while (stream.ignore(99, '\n')) // moved ignore here. now we ignore, then test the result
{
}
stream.clear();
stream << info << '\n'; // added a line ending. Without some delimiter the file
// turns into one big number
}
Note that this isn't exactly kosher. If any ignore fails for any reason, we bail out and possibly write over data because the code blindly clears and writes. I'm not spending much time here trying to patch this up because we can get really, really simple and solve the problem of creating a non-existent file at the same time.
void insertInfo(int info) {
std::fstream stream("infoFile.txt", std::ios::app);
stream << info << '\n';
}
Two lines and pretty much done. With app we append to the file. We do not need to find the end of the file, the stream automatically points at it. If the file does not exist, it is created.
Next improvement: Let people know if the write failed.
bool insertInfo(int info) {
std::fstream stream("infoFile.txt", std::ios::app);
return static_cast<bool>(stream << info << '\n');
}
If the file was not written for any reason, the function returns false and the caller can figure out what to do. The only thing left is to tighten up the stream. Since all we do is write to ti we don't need the permissiveness of a fstream. Always start with the most restrictive and move to the least. This helps prevent some potential errors by making them impossible.
bool insertInfo(int info) {
std::ofstream stream("infoFile.txt", std::ios::app);
return static_cast<bool>(stream << info << '\n');
}
Now we use an ofstream and eliminate all the extra overhead and risk brought in by the ability to read the stream when we don't read the stream.
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
string line = "test";
ifstream myfile("example.txt");
myfile.open("example.txt");
if (myfile.is_open())
{
cout << line << "\n";
cout << "File Opened\n";
getline(myfile, line);
cout << line;
while (getline(myfile, line))
{
cout << line << '\n';
cout << "test";
}
myfile.close();
}
else cout << "Unable to open file";
//return 0;
//getchar();
}
Apologies in advance if this has been answered, but while I've found several answers that are very close to what I need, I can't find an answer to this specific problem.
I'm new to Visual Studio, but have dabbled in c++ in the past. I'm trying to read in data from a text file and (for now) simply print that back out with cout. But, I'm not seeing any results.
At first I figured I just had my txt file in the wrong place - and I did. Initially I would receive the line "Unable to open file", indicating that the file could not be opened. So I moved it around and found out where Visual Studio wanted me to put the file.
So now I successfully see the "File Opened\n" line get printed to the screen, followed by nothing. I thought I might be using getline wrong, but if I replace the file input "myfile" with a "cin" instead, getline will happily read in keyboard input all day, so that's not it either.
So I've put in some test cout statements that print out the value of my string, line. The first one prints out "test" as it should. Then I read in a line of the txt file to that string variable, and when I cout it again I get nothing. It's a blank string.
Also, the line " cout << "test"; " From within the loop does NOT print either. So the loop's not even happening, it seems.
So, as near as I can tell, the program is able to find my textfile, example.txt. But it's not actually seeing the contents within.
The contents of the textfile (and what I'd like the program to print out) are as follows:
"This is the first line
This is the second line
Third
Fourth
Fifth"
Any and all help is much appreciated.
Figured it out.
What went wrong is this line:
ifstream myfile("example.txt");
I don't know exactly why, but since I specify the file to open in the next line down ( myfile.open("example.txt"); ), specifying the filepath in the ifstream declaration caused the issue.
I don't entirely get it, as others have said that the code runs fine for them. But this seems to work, anyway.
If there's any reason why I shouldn't use this solution, please let me know.
you might want to take a look at your file open
"myfile.open("example.txt");" i found if you don't give a file path weird things happen.
myfile.open("c:\test\example.txt");
is the adjustment I made to the code and it work like a dream.
I am unable to figure out why my code is not able to open and read a file. What am i missing?
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main (int argc, char * const argv[])
{
string line;
ifstream myfile ("input_file_1.txt");
if (myfile.is_open())
{
while (!myfile.eof())
{
getline (myfile,line);
cout << line << endl;
}
}
else
{
cout << "Was unable to open the file" << endl;
}
return 0;
}
The file "input_file_1.txt" is int he same directory as my .cpp file and it has read permissions. I even gave gave it 777 permissions and i was unable to read it.
Can anyone tell me what i am doing wrong? I really cannot figure it out....
Try to use full path for the file
The default location to look for the file is where the executable is , not where the source is.
How and where do you execute your program? From a IDE?
Can you run the program from the same directory where you have your text file.
Another possibility is to use an absolute path to the file.
If you don't specify a path, the library will attempt to load the file from the current directory. You need to make sure that this is where the file is.
Also, you might not be able to open the file if it is opened in an exclusive manner by another program. Ensure that it is not still open in another program such as your editor.
Other Problems:
Explicitly testing for EOF is usually wrong.
The last valid read (getline() here) reads up-to but no past the EOF. You then print the line. Then restart the loop. These test for eof() does not fail (as it has not read past the EOF). You then enter the loop body and attempt to read the next line (with getline()) this fails as there are 0 bytes left to read (thus leaving the value of line in an undefined state). You then print out line (undefined value) and a newline character.
while (!myfile.eof())
{
getline (myfile,line);
cout << line << endl;
}
A correct version of a loop reading a file is:
while (getline (myfile,line))
{
cout << line << endl;
}
This works because the getline() returns a reference to a stream. A stream used in a boolean context (like a while condition) tests to see if the stream is in a bad state (ie it test for EOF and other bad situations) and returns an object that can be used correctyl in the context. If the state of the stream is OK then a successful read has happened and the loop is entered (thus allowing you to print the line).
The binary created from your code (including your cpp) is executed somewhere different from your code is, probably a "bin"-folder. You schould put the file into the same folder as your executable.