Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
I have a menu that that starts some methods based on user's choice. Two of the methods however don't work properly, and I have no idea why.
This is the part of the menu for them:
case 2:
{
string fileName;
cout << "Which file to read?:";
cin>>fileName;
this->ReadFromFile(fileName);
break;
}
case 3:
{
string fileName;
cout << "Enter name for the file:";
cin>>fileName;
this->WriteToFile(fileName);
break;
}
Here are the methods:
void ReadFromFile(string file)
{
string line;
ifstream rfile ("FileSystem/" + file);//open file for reading
if (rfile.is_open())
{
while(getline(rfile, line))
{
cout << line << endl;
}
}
else
{
cout << "An error occurred when tried to read from this file." << endl;
}
rfile.close();
_getch();
}
void WriteToFile(string fileName)
{
ofstream myFile;
ifstream exists (fileName);//open read stream to check if file exists
if(exists)//returns true if file can be opened and false if it cant
{
exists.close();//close the stream
myFile.open(fileName, ios_base::app);// open file for reading(ostream)
}
else
{
exists.close();
CreateFile(fileName);//file doenst exists, so we create one and list it in the file tree
myFile.open("FileSystem/" + fileName, ios_base::app);// open file for reading(ostream)
}
if(myFile.is_open())
{
string input;
cout << "start writing and press enter to finish. It will be done better later." << endl;
cin>>input;
myFile << input;
}
else
{
cout<<"An error occurred when tried to open this file."<<endl;
}
myFile.close();
_getch();
}
Now here is the funny part. When I try to write something to a file, it doesn't matter that I open it with: 'ios_base::app' or 'ios:app' it just rewrites it. But it cant even do that properly. If i have a line with whitespaces like'Hi this is me.' for example, it only writes the first word, which here is 'Hi'.
So if I then decide to read the file the first thing that happens is that it says that the file cant be oppened, even before it asks me for a name. That happens the first 3 tries and then the reading magically works.
I have bashed my head into this for the last two hours and I still cant understand what is happening. Can anyone please explain this to me, and show me my mistakes?
string input;
cout << "start writing and press enter to finish. It will be done better later." << endl;
cin>>input;
myFile << input;
In the lines above, cin>>input will stop reading at a space. You should use std::getline instead. See also this answer.
Related
I have just a couple issues here with my code. It works but I'm not advanced enough to do what I want to yet. Nor do I know how to word it for a google search. I have a Blackjack game that I'm doing and want to know how to edit certain lines of the file depending on user input. Simpler, I want a user to be able to open the game and start with their balance from the last time they were playing(a save and load feature). My issues are the balance and the username are on the same line in the text file (purposefully) and I want to assign the variables to those in the text file. I know I'm on the right track, I just dont know where to go from here. Thanks for the help in advance. If I broke a rule of posting, I'm sorry.
input username
if username is present in file
edit balance on leave
if username isnt present in file
create new user
Here is my code for the load function:
void load(userAcc user1)
{
ifstream in;
in.open("Balances.txt");
if (in.is_open())
{
string word;
for (int x = 0; in >> word; x++);
{
user1.name = word;
user1.balance = word;
}
cout << user1.name << endl;
cout << user1.balance << endl;
in.close();
}
else
cout << "Cannot open a file";
}
void save(userAcc user1)
{
user1.balance = "1000";
cout << "Enter a username: ";
cin >> user1.name;
ofstream out;
out.open("Balances.txt", ios_base::app);
if (out.is_open())
{
out << user1.name << " " << user1.balance << endl;
out.close();
}
else
cout << "Cannot open a file";
}
In
for (int x = 0; in >> word; x++);
remove the trailing ;. It ends the statement before the body of the for loop, separating the two. The for spins around doing nothing but reading the file until it ends and incrementing the unused variable x and the following code block will be run exactly once, storing whatever is in word (and since the loop will exit when the read into word fails, what's in word will depend on the C++ Standard version the the compiler's been set to use) into user1.
Once the ; is removed, the for loop will read into word until no more words can be read from the file. Every word read is copied into the same userAcc writing over the previous word. When the file hits the end in >> word will fail and the loop will exit. The last word in the file will then be printed out, all other words having been overwritten.
Naïve fixing of this would look something like
void load(userAcc user1)
{
ifstream in;
in.open("Balances.txt");
if (in.is_open())
{
while (in >> user1.name // read name in from file
>> user1.balance) // read balance in from file
{ // loop will exit when it cannot read a name and a balance from the file
// for now we're just printing out what's read from the file.
cout << user1.name << endl << user1.balance << endl;
}
// in.close(); not needed. File will automatically close when in goes out of scope.
}
else
cout << "Cannot open a file";
}
But we probably want to do more than print out all of the users in the file, so let's put them into a convenient resizable container like std::vector.
vector<userAcc> load() // takes no parameters, returns list of accounts
{
vector<userAcc> accounts;
ifstream in;
in.open("Balances.txt");
if (in.is_open())
{
userAcc user1; // account we can read into
while (in >> user1.name >> user1.balance)
{
accounts.push_back(user1); // store account
}
}
else
cout << "Cannot open a file";
return accounts; // hand accounts read back to caller.
}
Use of the function would be something like
vector<userAcc> accounts = load();
The save function looks pretty much good-to-go as written.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
As the title suggests I am trying to find a specific word inside a file, and then deleting the line including it, but what I do here destroys the content of the file:
cin>>ID; //id of the line we want to delete
ifstream read;
read.open("infos.txt");
ofstream write;
write.open("infos.txt");
while (read >> name >> surname >> id) {
if (ID != id) {
write << name << " " << surname << " " << id << endl;
}
else write << " ";
}
read.close();
write.close();
Both of your files have same name. Calling basic_ofstream::open destroys content of a file if it already exists. In your case you destroyed data in input file before doing anything. Use different name and later rename. I assume line in input is ended with "\n" so we can use getline(). Then we need to tell if word is present in line and for that there is this function. std::string:npos is returned if line doesn't contain word.
#include <cstdio> // include for std::rename
#include <fstream>
#include <string>
void removeID() {
std::string ID;
cin >> ID; //id of the line we want to delete
ifstream read("infos.txt");
ofstream write("tmp.txt");
if (read.is_open()) {
std::string line;
while (getline(read, line)) {
if (line.find(ID) != std::string::npos)
write << line;
}
} else {
std::cerr << "Error: coudn't open file\n";
/* additional handle */
}
read.close();
write.close();
std::remove("infos.txt");
std::rename("tmp.txt", "infos.txt");
}
I am writing a program that I allow the user to specify an input file to open and when I test with incorrect file names, the program is behaving very weird and it seems to have something to do with the input buffer, but I don't know where to begin other than using getline() instead of cin >> but I have already tried that.
here is the code that I think may be the problem:
bool openfile(ifstream&);
string userInput();
int main()
{
// ...
while (!openfile(inputFile))
openfile(inputFile);
string input = userInput();
// ...
}
bool openfile(ifstream &inputFile)
{
string filename;
cout << "Please enter the name of the file or type quit to exit the program: ";
cin >> filename;
cout << endl;
if (filename == "quit")
exit(4);
else
inputFile.open(filename);
if (!inputFile)
{
cout << "The file \"" << filename << "\" could not be opened or does not exist.\n";
return false;
}
return true;
}
string userInput()
{
string englishSentence;
cout << "Please enter a sentence or type quit to exit the program: \n";
getline(cin, englishSentence);
if (englishSentence == "quit")
exit(4);
return englishSentence;
}
Those are the two functions that read any input. openfile() is called first as you can see. Any help is greatly appreciated. Let me know if you suspect something else in my code and I will paste it.
while (!openfile(inputFile))
openfile(inputFile);
What this does is attempt to open the file twice each iteration, as long as the first attempt fails. Also, you need to make sure that inputFile is closed before attempting to open it again since it appears that you're reusing the same file object repeatedly.
Certainly first try something like:
while (!openfile(inputFile))
;
You can just do:
while (!openfile(inputFile));
Since the way you have it it would request an input filename twice if it fails the first time.
Basically to outline the problem:
Begin Loop
Request Filename
Invalid Filename
Request Replacement Filename
Return to start of the loop (Checks again)
Some problems I see from your code:
int main(); { ... } does not define the main function. You need to drop the semicolon, or it won't even compile.
while (!openfile(inputFile)) openfile(inputFile); repeats openfile(inputFile) unnecessarily. If the first one (in the condition) fails and the second one (in the body) succeeds, a third call will be made (in the condition) to check if the loop should continue. What you probably want is just while (!openfile(inputFile)) { }.
You open a file in openfile and never use it in the subsequent userInput.
I am writing a program that reads from two files ("joke.text"and"punchline.txt") there is "garbage" in the punchline file and i cant figure out how to read just the line i want. Please help. Also, I am using Visual Studios
this is what I have:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
fstream jokeFile;
string data;
char input;
cout << "opening the file... \n";
jokeFile.open("joke.txt", ios::in);
if (jokeFile.is_open())
{
getline(jokeFile, data);
while (jokeFile )
{
cout << data <<endl;
getline(jokeFile, data);
}
jokeFile.close();
}
else
{
cout << "ERROR: could not open that file\n";
}
cout << "would like you see the punchline? (Y/N) \n";
cin >> input;
/* if ( input == 'N' || 'n')
{
cout << "Ok, keep guessing\n";
}*/
if (input == 'Y' || 'y')
{
jokeFile.open("punchline.txt", ios::in);
if (jokeFile.is_open())
{
//getline(jokeFile, data, '\n');
while (jokeFile)
{
cout << data;
getline(jokeFile, data, '\n');
}
jokeFile.close();
}
else
{
cout << "ERROR: could not open the file\n";
}
}
/*{
cout << "invalid response, try again\n";
}*/
system("pause");
return 0;
}
and here is the output:
opening the file...
Two men who work together in a facory were talking.
"I know how to get some time off," said one.
"How are you going to do that?" asked the other.
"Watch," he said, and climbed a ladder to the ceiling.
The foreman asked what he was doing up there,
and the man replied. "I'm a lightbulb."
"I think you need some time off," the foreman
said, and the first man walked out of the
factory. After a moment, the second man followed
him. "Where do you think you're going?"
the foreman shouted.
would like you see the punchline? (Y/N)
y
asdasdasdasdasdfdssdfdsaasdfdssfddsfdsasdsad"I can't work in the dark, " he said.
There are two possibilities:
You know the position you wish to seek to. If so, then see the seek functions here: http://www.cplusplus.com/reference/istream/istream/seekg/
You do not know the position you wish to seek to, but you know what the garbage "looks like", in which case you'll need to read it and parse it till you've read past it.
You can use fseek in order to get the size of the file, than divide it to half, and start reading from half with fseek again.
int fseek(FILE *stream, long int offset, int whence)
Example: (Have not been tested)
int size = fseek(jokeFile, 0, SEEK_END);
fseek(jokeFile, size/2.0, SEEK_SET);
I think your question is misleading for the problem you're presenting. It looks like your program is trying to output all of the jokefile.txt, prompt the user, then output all of the punchline.txt file. The garbage output before the punch line must be the gibberish returned to the 'data' string when the EOF is reached on jokefile.txt. And your first read of punchline.txt is commented out, so the cout in that loop dumps the garbage before reading and outputing the punch line.
I'm still a beginner to programming, I got an assignment asks me to make a code that read a text file and then remove the stop words. I made a code but it's not that good. what i want is to know how to remove a word from a line and apply case folding to the file after removing the stop words.
here is my code...
string line, deleteline;
ifstream stopword;
stopword.open("example.txt");
if (stopword.is_open())
{
while ( getline (stopword,line) )
{
cout << line << endl;
}
stopword.close();
}
else cout << "Unable to open file";
ofstream temp;
temp.open("temp.txt");
cout << "Please input the stop-word you want to delete..\n ";
cin >> deleteline;
while (getline(stopword,line))
{
if (line != deleteline)
{
temp << line << endl;
}
}
temp.close();
stopword.close();
remove("example.txt");
rename("temp.txt","example.txt");
cout <<endl<<endl<<endl;
system("pause");
return 0;
}
The code would be right, but you closed the file... and after closing, you're trying to read from it later. That won't quite work, unless you open it again.
Here you close the file (7th line in main):
stopword.close();
And then, in the 2nd while you try to getline from that stream:
while (getline(stopword,line))
In order for that to work, you have to open the file again. And clear the stream, because it'll probably have the eofbit error state flag set.