This question already has an answer here:
Cannot open input file
(1 answer)
Closed 7 years ago.
I am trying to create a program that asks the user for the name of a file, then opens the file, adds the sum of all the integers listed on the file, then writes that sum on an output file.
After writing my code and saving the testfile1.txt into the same folder as the program, the program keeps giving me the: "could not access testfile1" (message I output to notify myself that it is unable to open the testfile1.txt).
Here is what I have so far (skipped the lines with description blocks):
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main(){
ifstream inputFile;
ofstream outputFile;
string testfile1;
string sum;
int total = 0;
int num;
cout << "Please input name of file." << endl;
cin >> testfile1;
cin.get();
inputFile.open(testfile1.c_str());
if (inputFile.fail()) {
inputFile.clear();
cout << "could not access testfile1" << endl;
return(1);
}
while (!inputFile.eof()) {
inputFile >> num;
total = total + num;
inputFile.close();
}
outputFile.open(sum.c_str());
outputFile << total << endl;
outputFile.close();
if (outputFile.fail()) {
cout << "could not access file." << endl;
return 1;
}
return 0;
}
Question:
How can I make this program find and open the testfile1.txt?
Note:
I am pretty sure that when prompted for the file name, I did not misspell.
Here are few remarks that will help you figure out the possible problem:
1.You could reduce some lines of code by attaching your streams to a file during definition, instead of defining them and then use open, like so:
ifstream inputFile(testfile1.c_str());
2.To check if a file is open (and handle if it couldn't):
if (!inputFile) error ("Can't open input file: ", testfile1);
and:
if (!outputFile) error ("Can't open output file: ", sum);
right after the definition.
3.All open files are implicitly closed at the end of the program (or a function that contains them), so there is no need to explicitly close() them.
4.To read the contents of the input file and sum them:
int sum = 0;
string line;
// read a line
while (getline(inputFile, line)) {
stringstream ss(line);
// assuming you are reading integers separated by white space
int num = 0;
// extract each number on the line
while (ss >> num) total += num;
// reset line
line.erase();
}
Note: test and modify your code according to your specific needs. A side note: you could probably omit: cin.get(); in your code.
use getline (std::cin,name);
for input name
and use proper function of ostream for reading and writing.
you'r getting input wrong at line 21 and line 22
Related
I am trying to open a file with C++ and output the text that is in the file. I cannot seem to figure out what I am doing wrong. Here is what I have so far.
#include <iostream>
#include <string>
#include <fstream>
#include <cstdlib>
using namespace std;
int main()
{
char fileName[50];
ifstream infile;
cout << "Enter the name of the file you would like to open: ";
cin.getline(fileName, 50);
infile.open(fileName);
if(!infile.is_open())
{
exit(EXIT_FAILURE);
}
char line[75];
infile >> line;
while (infile.good())
{
cout << line << " ";
infile >> line;
}
system("pause");
return 0;
}
After I input the file name and press enter the CMD prompt just closes. I know that the file exist, but I cannot figure out why it is exiting. Obviously it is because of the exit command, but it should be open. What am I doing wrong?
You don't need to read/write the file line by line; C++ already supports to copy the file in one step. You also should use string instead of char[] for your strings; on one hand it means that you don't need to restrict the maximal length of your strings to some arbitrary length (what if your file's pathname has more than 50 characters, or the file has lines with more than 75 characters?
Note also that your file copying code is erroneous: It will remove all whitespace from the file, as infile >> line does not read a line (use readline for that), but a word, discarding whitespace.
Also, your code should give an error message if it couldn't open the file, instead of just silently returning (you do provide an error return, which is very good, but unless you call it from something that actually gives you feedback on the error return, you'll never learn about it.
Finally, the system("pause") should probably be done in an RAII class, so it is guaranteed to be exited on return (however, exit will not call destructors, so unless you want to use atexit, you should use return in `main`` instead). A better idea would, however, be to not put this into the code, but instead run it in a terminal that doesn't immediately close after the program finishes.
Here's a program that implements those suggestions:
#include <iostream>
#include <fstream>
#include <cstdlib>
int main()
{
// make sure that system("pause") is called on all exit paths
struct cleanup
{
~cleanup() { std::system("pause"); }
} do_cleanup;
// get the file name
std::string filename;
std::cout << "Enter the name of the file you would like to open: ";
std::getline(std::cin,filename);
if (!std::cin)
{
std::cerr << "Failed to read the file name.\n";
return EXIT_FAILURE;
}
// open the file
std::ifstream infile(filename.c_str());
if (!infile)
{
std::cerr << "Could not open file: " << filename << "\n";
return EXIT_FAILURE;
}
// print the file
std::cout << infile.rdbuf();
// close the file
infile.close();
if (!infile)
{
std::cerr << "Could not properly close file: " << filename << "\n";
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
There is no need to use a char[]. You've even #included string so just use that.
string fileName;
cout << "Enter the name of the file you would like to open: ";
cin >> fileName;
// or
// getline(cin, fileName);
ifstream infile(fileName);
if (infile.fail()) {
exit(EXIT_FAILURE);
}
string line;
while (infile >> line) {
cout << line << " ";
}
system("pause");
return 0;
I also modified a few things to make it a bit cleaner.
Thanks for the help. Yes the file was in the wrong folder. It was a newb oversight!
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.
I am trying to create a program in C++ using Microsoft Visual Studio 2013. The main purpose of this program is to read three different files(headlines1,headlines2, and headlines3) and put them all together to form a single file and creating a sentence within that output file. I have figured out a function that I could use, but this function only reads and prints the 3 files out onto the console window. When I try to change the cout statement into an outfile, my outfile that I created is blank... I don't know what to do or how to structure the code.
#include<fstream>
#include<iostream>
#include<cstdlib>
using namespace std;
void readingFile(string[], ifstream &); //Funtion Prototype
int main()
{
string header1[50], header2[50], header3[50]; //Declaring array with 50 elements
int size1, size2, size3;
ifstream Fin, Fin2, Fin3;
ofstream Fout;
Fin.open("Headlines1.txt"); //Reading from these 3 files.
Fin2.open("Headlines2.txt");
Fin3.open("Headlines3.txt");
if (!Fin || !Fin2 || !Fin3) //Checking for unsuccessful open
{
cout << "Input file opening failed.\n";
cin.ignore();
return 1;
}
Fout.open("testingHeadlines.txt"); //Used for unsuccessful opening output
if (!Fout)
{
cout << "Output file opening failed.\n";
cin.ignore();
return 2;
}
cout << "Building.... Editing....\n" << endl;
cin.ignore();
cout << "Headlines file 1 below:\n" << endl;
readingFile(header1, Fin); //Function call
cout << endl << endl;
cout << "Headlines file 2 below:\n" << endl;
readingFile(header2, Fin2); //Function call
cout << endl << endl;
cout << "Headlines file 3 below:\n" << endl;
readingFile(header3, Fin3); //Function call
cout << endl << endl;
cin.ignore();
return 0;
}
//the function 'readingFile'
//Pre-conditions: Reads the contents from the files of Headlines1,2,and 3
//Post-conditions: Prints out the contents.
void readingFile(string[], ifstream &infile)
{
char next;
infile.get(next);
while (!infile.eof()) //Reading until EndOfFile
{
cout << next; //Problem is here?? I would think.
infile.get(next);
}
}
I'm just not certain if where I said the "Problem is here??" is where the problem is at. Every time I change the cout to outfile(I know, I have to change the parameters within the function header) once doing that I open the outfile and the file is blank.
All the files contain random words/phrases and when put together they will make a sentence. For ex. Headlines1 contains '***Queen Jennifer*'** Headlines2 contains '***has brain surgery*'** Headlines3 contains '***after eating 30 jalapenos.*'** and When put together it should read 'Queen Jennifer has brain surgery after eating 30 jalapenos.' but the files contain more words/ phrases that what I just listed in my example.
When I run the program above I am able to read all three Headline files, but they are printed in up to down form. For example, my output on my console screen would be:
Queen
Jennifer
has brain surgery
after eating 30 jalapenos
Problem:
Getting my headlines to read from left to right.
Getting them into a output file instead of the console screen.
Help Please.
You could replace this...
void readingFile(string[], ifstream &infile)
{
char next;
infile.get(next);
while (!infile.eof()) //Reading until EndOfFile
{
cout << next; //Problem is here?? I would think.
infile.get(next);
}
}
...and the calls there-to, such as...
readingFile(header1, Fin);
...with this...
void readingFile(ifstream& infile, ofstream& fout)
{
char next;
while (infile.get(next)) //Reading until EndOfFile or error
if (next != '\n') // if not newline
fout << next; // stream to file
}
...and calls ala...
readingFile(Fin, Fout);
That way readingFile is told where to write the output, and filters out the newline characters that were causing the output to appear on different lines.
This should do the trick.
#include <fstream>
#include <string>
int main() {
// Open the three files.
std::ifstream file_1("Headlines1.txt");
std::ifstream file_2("Headlines2.txt");
std::ifstream file_3("Headlines3.txt");
// Combine into one string.
std::string content;
content += std::string(std::istreambuf_iterator<char>(file_1),
std::istreambuf_iterator<char>());
content += std::string(std::istreambuf_iterator<char>(file_2),
std::istreambuf_iterator<char>());
content += std::string(std::istreambuf_iterator<char>(file_3),
std::istreambuf_iterator<char>());
// Output the string into a single file.
std::ofstream output_file("testingHeadlines.txt");
output_file << content;
}
I'm not sure what you're wanting to do about spacing between files, but that shouldn't be too hard for you to fine-tune this code for.
one possible thing why your ouput is like this is that std::ifstream::get() that you used in infile.get(next) is a non-formatted reading method which means it will not skip white spaces and newline character \n by default. so you need to check if next value is a newline like this:
if(next == '\n') continue ;
before passing it to cout << next. Thus you will skip printing a newline in your console screen.
I'm just learning about text file input/output. I have outputted a file which contains a header and 10 rows of data underneath it.
I now want to read this back to the main function. This works for me if I leave out the header in the text file, but if I leave the header in, I get an infinite loop.
How can I skip the 1st line (the header line) in reading this data back, or if possible, read back the header as well as the data?
Here is what I have so far:
void fileRead(int x2[], double y2[], int& n, char filename)
{
ifstream fin ("pendulum.txt"); // fin is an input file stream
if(!fin) //same as fin.fail()
{
cerr << "Failure to open pendulum.txt for input" << endl;
exit(1);
}
int j = 0, dummy = 0; //index of the first value j and dummy value
while(!fin.eof()) //loop while not end of file
{
fin >> dummy >> x2[j] >> y2[j];
cout << setw(5) << fixed << j
<< setw(12) << scientific << x2[j] << " "
<< setw(12) << y2[j] << endl; //print a copy on screen
j += 1;
}
fin.close(); //close the input file
}
You can first read the header of the file then the real contents you want as follows:
string line;
getline(fin, line);//just skip the line contents if you do not want header
while (fin >> dummy >> x2[j] >> y2[j] )
{ //^^if you do not always have a dummy at the beginning of line
//you can remove dummy when you read the rest of the file
//do something
}
Your best bet would be to use
fin.ignore(10000,'\n');
http://www.cplusplus.com/reference/istream/istream/ignore/
This will ignore the first 10000 character in the file, or ignore the characters until a newline is reached. The 10000 is fairly arbitrary and should be a number that will always be longer than the maximum line length.
man, this gentleman over there helped me quite a lot. You see, everyone says to use getline(); to skip one line, but the problem is that sometimes you dont want to store anything in a buffer, so ignore() makes much more sense to me. Well so I would like to back up our fella's answer by adding that, you could use " numeric_limits::max()" which will make it have no limit, it will ignore until it finds the delimiter...
`
#include <iostream>
#include <fstream>
#include <limits>
using std::streamsize;
int main() {
ifstream fin ("pendulum.txt");
fin.ignore(numeric_limits<streamsize>::max(),'\n');
}
`
http://www.cplusplus.com/reference/limits/numeric_limits/
The program is supposed to prompt the user for their username. Upon receiving the username it concatenates it with '.history' to create username.history. Then it opens that file (username.history) and reads the input from it. I am running into a segfault here though. Whenever it opens the file, which is empty because the file doesn't exist, it reads multiple lines and then throws the segfault. I think the problem might stem from how I'm trying to open the file, but I'm not sure. Here is the portion that is causing problems:
// File input and output
ifstream f_in;
ofstream f_out;
// Prompt user for their username.
char username[80];
cout << "Please input your username: " << endl;
cin >> username;
cout << endl;
cout << "Loading history file if it exists." << endl;
// Create file naem and initialize the file line counter to 0.
strcat(username, ".history");
int fcount = 0;
// Open file and read in lines if there are any.
// Place read lines into the command string for use later.
char tmp[50];
f_in.open(username);
while(!f_in.eof()){
f_in >> tmp;
cmd[fcount] = tmp;
fcount++;
}
f_in.close();
Other pertinent info:
cmd is declared as a global variable (char cmd[200][50])
Any help will be greatly appreaciated.
Not sure if it is the only issue, but cmd[fcount] = tmp is wrong. You should use strcpy().
while(f_in.good())
{
f_in >> tmp;
cmd[fcount] = tmp;
fcount++;
}