C++ File (Ifstream) will not open [duplicate] - c++

This question already has answers here:
ifstream won't open file
(2 answers)
What happens if i open a file that is already open in C++
(1 answer)
Closed 2 months ago.
When file is checked if its open, it will not open.
The file doesn't open when ran, as it says "Unable to open file" based on my test cases. Is there anyway to fix this?
Is there something I need to fix with the file io function (which I created at the bottom) or something to do inside of the if statement (checking if its open)
#include "header.hpp"
int main() {
string infile, outfile;
print();
readFilenames(infile, outfile);
ifstream fin(infile.c_str());
// check if file can be opened
fin.open(infile);
if (fin.is_open())
{
string name, smallName = "", largeName = "";
int id, numPeople = 0, smallId, largeId;
double balance, totalBalance = 0, largeBalance, smallBalance;
cout << "\n\nReading records from input file " << infile << endl;
cout << "Output records to output file " << outfile << endl;
ofstream fout(outfile.c_str());
print(fout);
fout << "List of Entries : " << endl;
printHeading(fout);
// read till the end of file
while (!fin.eof())
{
numPeople++;
getline(fin, name); // read name
name = name.substr(0, name.length() - 1); // remove '\n' from the end of name
// read id and balance
fin >> id >> balance;
}
} else
cout << "Unable to open file : " << infile << endl;
cout << "\nThank you for using my program";
return 0;
}
void readFilenames(string &infile, string &outfile)
{
cout << "What input file would you like to use? ";
getline(cin, infile);
infile = infile.substr(0, infile.length() - 1);
cout << "What output file would you like to use? ";
getline(cin, outfile);
outfile = outfile.substr(0, outfile.length() - 1);
}

Related

Cannot print a vector to a text file in C++

I'm working on the following problem:
I need to write a prgoram that reads an ASCII text file from the hard drive and allows the user to display and edit the contents of the file line-by-line.
It must have the following features:
It reads the file name from the standard output and opens the text file using a file stream.
When the file is loaded, the user enters the text line number.
If the line exists, it is displayed in the standard output.
If the line does not exist (the user has entered a line number
that is greater than the number of lines in the file), an error message is displayed,
for example: The line 82 does not exist. When the line is displayed the user is given
an option to enter a new string in the standard input that will become the contents of
the line. The string can contain blank spaces. Then the user is asked to enter another line number.
Finally, the user is asked whether he wants to save the changes in the file or not.
Technical requirements: The program must be composed by more than one function
This is my code so far:
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
using namespace std;
void printErrorMessage(int lineNumber)
{
cout << endl << " ERROR: The line " << lineNumber << " does not exist"
<< endl;
}
int main()
{
int line_number;
vector<string> TextVector;
int loop = 1;
fstream myfile;
myfile.open("test.txt", std::fstream::in | std::fstream::out);
while(loop == 1)
{
if (myfile.is_open())
{
// get end line of file.
cout << "File has opened successfully." << endl;
}
else
{
cout << "File hasn't opened successfully.";
return 0;
}
cout << "Enter the text line number:" << endl;
cin >> line_number;
size_t lines_count = 0;
string line;
while(getline(myfile, line))
{
TextVector.push_back(line); // push to text file
}
if(line_number > TextVector.size() + 1)
{
printErrorMessage(line_number);
return 0;
}
cout << TextVector[line_number] << endl;
cout << "If you'd like to change the line, please enter it, otherwise enter n to exit" << endl;
string changeLine;
getline(cin, changeLine);
if (changeLine == "n")
{
myfile.close();
return 0;
}
TextVector[line_number] = changeLine; // changes the line with the new string
cout << "Would you like to enter a new line to edit? (Y/n)" << endl;
string newLine;
cin >> newLine;
if (newLine != "y" && newLine != "Y")
{
cout << "Would you like to save all your changes to the file? (Y/n)" << endl;
string saveChanges;
cin >> saveChanges;
if (saveChanges != "y" && saveChanges != "Y")
{
myfile.close();
return 0;
}
for (int i = 0; i < TextVector.size() + 1; i++)
{
cout << TextVector[i] << endl;
myfile << TextVector[i] << endl;
myfile.flush();
}
myfile.close();
return 0;
}
}
return 0;
}
Technically I do save the changes to the vector, but for some reason I cannot get to overwrite the vector into the text file that already is full.
Also, any idea why the
getline(cin, changeLine);
Still acts as if it's a normal string? shouldn't it get the whole line entered togethe with the spaces?
Some guidance would really be appreciated!

why won't my program back up my file?

I'm working on a C++ project where I need to backup a data file after creating it within the same program. I have already created the data file and have successfully written text to it, however, when I've tried to backup the same file using the function I've written, it won't work.
Here is some context followed by the function:
The filename I created is named contactList.ext (.ext so it's created in the current directory). When prompted for the filename in this program I type in contactList and it opens successfully, however, the only problem I'm having is that it won't backup the file. I'm trying to back it up this way: newFileName = (fileName + ".bak");
I don't know what other way there is to backup a file using c++. Any help is greatly appreciated!
void backupDataFile() {
string fileName;
string newFileName;
string line;
int contactListSize = 10, i = 0;
string contacts[contactListSize];
char userResponse;
fstream inFile, outFile;
cout << "\nEnter the name of the file you want to backup: ";
cin >> fileName;
inFile.open(fileName.c_str()); //attempts to open file
//file fails to open
if (inFile.fail()) {
cout << "\nThe file " << fileName << " was not opened successfully."
<< "\n Please check that the file currently exists.\n";
exit(1);
}
//read and display contents of file & assign each line to an array
cout << "\nThe following is the contents of " << fileName << ":\n\n";
while(getline(inFile, line)) {
cout << line << endl;
contacts[i] = line; //assigns each line to an array position
i++;
}
inFile.close(); //closes existing file allowing the opening of a new file
//verify user wishes to backup file
cout << "\nWould you like to backup this file? <y/n>: ";
cin >> userResponse;
if (userResponse == 'y') {
newFileName = (fileName + ".bak"); //assigns name of backup file
outFile.open(newFileName.c_str()); //attempts to open backup file
//file fails to create
if (outFile.fail()) {
cout << "\nThe file " << fileName << " did not backup successfully.";
exit(1);
}
///fix hereafter
else { //writes contents from contactList.ext to contactList.bak
while (i < 10) {
cout << contacts[i] << endl; //writes each contact into new file
i++;
}
//for (int j = 0; j < 10; j++) {
// outFile << contacts[j] << endl;
}
outFile.close(); //closes file
cout << "\nThe file " << fileName << " has been backed-up successfully."
<< "\nThe backup file is named " << newFileName;
}//end outer-if
else
cout << "\nYou will be directed back to the Main Menu.";
}
Your problem lies within these two sections.
while (i < 10) {
cout << contacts[i] << endl; //writes each contact into new file
i++;
}
//for (int j = 0; j < 10; j++) {
// outFile << contacts[j] << endl;
That for loop should not be commented out, you're only writing to the console (with cout), when you need to be writing to the outfile.
You also need to specify ios::out when calling outFile.out().
outFile.open(newFileName.c_str(),ios::out)
As stated by the other poster, you aren't actually running the code that outputs to the file
//outFile << contacts[j] << endl;
However another problem I see is that you output in a loop so long as i is less than 10. This is fine, but you didn't set i back to 0 after counting the number of lines when reading the file! That means that your
while(i < 10) {
loop never runs :)

Assign values to variables in c file by reading excel sheet

I need to assign values to variables in C file by reading an excel sheet. I have written a code but only the last variable has been assigned a value since I have used for loop.It is overwriting the values assigned to the previous variables as I am creating a different output file after assigning values.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
string s1, s2, s3,s4;
string filename, text, line;
string cfilename,funcname, signal, value;
int i , k , m;
cout << "Enter excel filename" << endl;
cin >> filename;
cout << "How many lines of text are in the file?" << endl;
cin >> m;
fstream file(filename);
if (!file) {
cerr << "No such file exists." << endl;
exit(1);
}
if (file.is_open()) {
while (file.eof()==0){
for (k = 0; k < m; k++) { //Loops for as many lines as there are in the file
for (i = 0; i < 4; i++) { //Loops for each comma-separated word in the line
if (i == 0){
getline(file, text, ',');
cfilename=text;
cout << cfilename << '\t';}
else if (i == 1){
getline(file, text, ',');
funcname=text;
cout << funcname << '\t';}
else if (i == 2){
getline(file, text, ',');
signal=text;
cout << signal << '\t';}
else if (i == 3){
getline(file, text, '\n');
value=text;
cout << value << '\n';}
}
string s1=signal,s2=value;
s2 = s2 + "; //";
int offset, inset;
string line;
string search=s1;
fstream cfile(cfilename);
fstream fileOutput;
fileOutput.open("output.c");
if(cfile.is_open() && fileOutput.is_open()) {
while(!cfile.eof()) {
getline(cfile, line);
if ((offset = line.find(funcname)) != string::npos){
cout << "found: " << funcname << endl;
string line1;
fileOutput << line << '\n';
skip:
while(getline(cfile,line1)){
if((inset=line1.find(search, 0)) !=string::npos){
cout<<"found: " << search << endl;
string s3 = s1+ "=" +s2;
//cout<<s3;
line1.replace( inset, inset+s1.size(), s3 );}
fileOutput << line1 << '\n';
goto skip;
}
getchar(); }
fileOutput << line << '\n'; }
cfile.close();
fileOutput.close();
}
}
}
}
file.close();
getchar();
return 0;
}
I am trying to search a function first and then variables inside that function.
Need some help here.
I'm not sure it's this the problem but... I thing the while () is too much.
when you have readed the m lines of the file, your
while (file.eof()==0)
result true because you haven't read nothing past the end of file.
So you read other m lines (failing but without controls about the success of the reading).
EDIT: I think you should write something like
cout << "Enter excel filename" << endl;
cin >> filename;
fstream file(filename);
if (!file) {
cerr << "No such file exists." << endl;
exit(1);
}
while ( getline(file, cfilename, ',') && getline(file, funcname, ',')
&& getline(file, signal, ',') && getline(file, value, '\n')) {
cout << cfilename << '\t' << funcname << '\t' << signal << '\t'
<< value << '\n';
string s1=signal,s2=value;
[...]
The program does exactly what you asked it to do:
you read a CSV file (excel format is binary!) line by line
for each line in csv:
you erase the output file because you open a fstream without specifying ios::ate
search something in a source file and write to the output file.
As you erase the output file at every new line from the input CSV file, you cannot get more than the last operation.
It would be much simpler if you opened the output file once outside of the loop.
And... while (file.eof() == 0) is an anti-pattern. You look whether you have reached end of file before trying to read a line, and then read 4 values when the first getline have set the eof flag. You must test for eof immediately after a read and not before...

Getting the user to enter a file C++ [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
" Your assignment is to prompt the user to enter the filename with the path on disk. If the file does not exist in the specified location, your program should exit with a suitable error message"
Hi everyone, so this is where I'm having an issue, I was able to get the user to enter a file name like this..
1. cout<< "enter the data file name you wish to open";
2. cin >>file;
3. indata.open(file.c_str());
4. outdata.open(file.c_str());
The second part of the question is if the file does not exist, the program should make an error, how would I go about doing so, say my file name is txt.source, but the user enters lil.pol how do I make it say there is an error, or other words how do I make the file name desired the only one the computer will accept?
What you can do is try to open the file and if it fails to open issue a message through std::cerr like this:
std::ifstream indata(file.c_str());
if(!indata) // failed to open
{
std::cerr << "Error: could not open file: " << file << std::endl;
return 1; // error code
}
// use indata here (its open)
Edit:
reading/writing data:
void createfile()
{
ofstream file_handle("test.txt");
if (!file_handle)
return;
//add record:
file_handle << "firstname1" << endl;
file_handle << "lastname1" << endl;
file_handle << "college1" << endl;
file_handle << "1001" << endl;
//add another record:
file_handle << "firstname2" << endl;
file_handle << "lastname2" << endl;
file_handle << "college2" << endl;
file_handle << "1002" << endl;
//remember each record is 4 lines, each field is single line
//this is the file format
}
int main()
{
createfile();
ifstream fin("test.txt");
if (!fin)
{
cout << "file not found" << endl;
return 0;
}
ofstream fout("out.txt");//note, it's a different name than input file
if (!fout)
{
cout << "cannot create new file" << endl;
return 0;
}
char buffer[1000];
while (fin)
{
cout << "attempting to read record:\n";
for (int i = 0; i < 4; i++)
{
fin.getline(buffer, 1000, '\n');
if (!fin) break;
cout << buffer << endl;//write to screen
fout << buffer << endl;//write to file
if (i == 3)
{
//buffer is expected to be a number!
int number = atoi(buffer);
//multiply by random number 2, just testing
cout << number * 2 << endl;
}
}
}
return 0;
}
Just make a loop and ask for new entry if the file name is wrong.
int main()
{
ifstream indata;
string fname;
for (;;)
{
cout << "enter fname, zero to exit\n";
cin >> fname;
if (fname == "0")
return 0;
indata.open(fname);
if (indata)
break;//file is valid and has been opened now
cout << "file not found, try again\n";
}
return 0;
}

ifstream getline issue (it only reads the first line)

Something is definitely wrong with my loop because after reading and executing the first line the programs ends.
if (infile.is_open())
{
cout << "Input filename: ";
cin>>filename;
infile.open(filename.c_str());
cout<< "Output filename: ";
cin>>filename;
outfile.open(filename.c_str());
while(getline(infile,input))
{
string output = "";
for(int x = 0; x < input.length(); x++)
output += cipher(input[x]);
cout<<output<<endl;
outfile<<output;
}
}
Any suggestions on how to make this work?
EDIT
Followed the suggestions and got this:
if (infile.is_open()) {
cout << "Input filename: ";
cin>>filename;
infile.open(filename.c_str());
if (!infile.is_open())
{
std::cout << "Failed to open the input file." << std::endl;
return -1;
}
cout<< "Output filename: ";
cin>>filename;
outfile.open(ofilename.c_str());
if (!outfile.is_open())
{
std::cout << "Failed to open the output file." << std::endl;
return -1;
}
while(getline(infile,line)){
string output = "";
for(int x = 0; x < input.length(); x++) {
output += cipher(input[x]);
}
}
BUT it still reads only the first line...everything else is working perfectly fine....just can't read anything beyond the first line..
It seems that you misunderstood the point of the fstream's is_open() method, since this code:
if (infile.is_open())
{
cout << "Input filename: ";
cin>>filename;
infile.open(filename.c_str());
...
}
checks whether the infile has been successfully opened (i.e. if either a previous call to member open succeeded or if the object was successfully constructed using the parameterized constructor,
and close has not been called since) and in case it is open it retrieves the name of the input file from cin and opens the file.
Good start would be the program that reads from the input file line by line and writes these lines to the output file without processing them:
// retrieve the name of the input file and open it:
cout << "Input filename: ";
cin>>filename;
infile.open(filename.c_str());
if (!infile.is_open())
{
std::cout << "Failed to open the input file." << std::endl;
return -1;
}
// retrieve the name of the output file and open it:
cout << "Output filename: ";
cin >> filename;
outfile.open(filename.c_str());
if (!outfile.is_open())
{
std::cout << "Failed to open the output file." << std::endl;
return -1;
}
std::string line;
while(getline(infile,line))
{
std::cout << line << std::endl;
outfile << line;
}
So I suggest this.
Write char cipher(char ch) to return enciphered input for anything. if you don't want to encipher whitespace, then don't. But always return the enciphered character or unmodifed character.
Use std::transform , std::istream_iterator , and std::ostream_iterator to transform your input and output files.
Check your file states at the correct times.
An example appears below:
#include <iostream>
#include <fstream>
#include <iteraor>
#include <string>
using namespace std;
char cipher(char ch)
{
if (std::isalpha(ch))
{
// TODO: change ch to whatever you want here.
}
// but always return it, whether you changed it or not.
return ch;
}
int main()
{
int res = EXIT_SUCCESS;
string in_filename, out_filename;
cout << "Input filename: ";
cin >> in_filename;
cout << "Output filename: ";
cin >> out_filename;
// don't skip whitespace
ifstream infile(in_filename);
ofstream outfile(out_filename);
if ((infile >> noskipws) && outfile)
{
std::transform(istream_iterator<char>(infile),
istream_iterator<char>(),
ostream_iterator<char>(outfile),
cipher);
}
else
{
perror("Failed to open files.");
res = EXIT_FAILURE;
}
return res;
}