C++ text file I/O - c++

This is a very simple question but wherever I look I get a different answer (is this because it's changed or will change in c++0x?):
In c++ how do I read two numbers from a text file and output them in another text file?
Additionally, where do I put the input file? Just in the project directory? And do I need to already have the output file? Or will one be created?

You're probably getting different answers because there are many different ways to do this.
Reading and writing two numbers can be pretty simple:
std::ifstream infile("input_file.txt");
std::ofstream outfile("output_file.txt");
int a, b;
infile >> a >> b;
outfile << a << "\t" << b;
You (obviously) need to replace "input_file.txt" with the name of a real text file. You can specify that file with an absolute or relative path, if you want. If you only specify the file name, not a path, that means it'll look for the file in the "current directory" (which may or may not be the same as the directory containing the executable).
When you open a file just for writing as I have above, by default any existing data will be erased, and replaced with what you write. If no file by that name (and again, you can specify the path to the file) exists, a new one will be created. You can also specify append mode, which adds new data to the end of the existing file, or (for an std::fstream) update mode, where you can read existing data and write new data.

If your program is a filter, i.e. it reads stuff from somewhere, and outputs stuff elsewhere, you will benefit of using standard input and standard output instead of named files. It will allow you to easily use the shell redirections to use files, saving your program to handle all the file operations.
#include <iostream>
int main()
{
int a, b;
std::cin >> a >> b;
std::cout << a << " " << b;
}
Then use it from the shell.
> cat my_input_file | my_program > my_output_file

Put in the same folder as the executable. Or you can use a file path to point at it.
It can be created if it does not exist.

Related

Adding a new line to existing txt file in c++

As a tutorial I've been a question to add new line to an existing file with a list of items. i've tried numerous ways to add it. no luck yet
ofstream outdata;
ifstream indata;
indata.open("fruits.txt");
outdata.open("fruits.txt");
if(indata.is_open()){
std::string fruit;
std::cout << "enter a fruit to list "<<endl;
std::cin >> fruit;
outdata << "\n" << fruit << "\n" << endl;
indata.close();
outdata.close();
return 0;
}
This part of the code is supposed to ask the user to enter a value. Its supposed to be stored as new line without deleting the existing line. But here I'm. I've seen a few answers here. but can't find anything understandable.
When you open a file for writing its contents are immediately removed, if the file already exists.
outdata.open("fruits.txt");
You opened the same file for writing here. This is before your code tries to read anything from the same file (I don't actually see anything in your code that tries to read it, I presume you left that part out). And by the time you get to the file it's already empty and there's nothing to read any more from it.
You have three choices:
Read the entire contents of the file into your program, and only then open it for writing and write out the new contents.
Open a different file for writing. After finishing reading and writing both files, and closing them, rename the new file to the original file.
Open the file for appending:
outdata.open("fruits.txt", std::ios::app);
It's not necessary to open it for reading, this will add to the end of the file, instead of overwriting it.

Is it possible to read and write to a header file?

So I'm trying to overwrite a macro I have on a header file but I can't seem to open it by using std::ifstream. Is it even possible to read/write to an existing header file or are there default permissions that don't allow programs to modify header file contents?
std::ifstream versionH;
char temp[100];
versionH.open("..\temp.h");
if (!versionH.is_open()) {
std::cout << "Didn't open" << std::endl;
return 1;
}
while (!versionH.eof()) {
versionH >> temp;
std::cout << temp << std::endl;
}
I would hope that I'd be able to read in the header file and display it's contents but 'versionH.is_open()' is returning false. Is there something I'm missing here?
Is it possible to read and write to a header file?
Headers are files. It is possible to read and write files (assuming the file exists, and the process has sufficient permissions etc.). Therefore we can infer that header files can be read and written to.
Note that modifying a header file that has been used to compile a program has no effect on the compiled program. It can only affect programs compiled using the modified file.
Furthermore, files in the context where the program is compiled are irrelevant to the program. Only the files in the file system where the program is executed can be read.
Is there something I'm missing here?
Probably the file doesn't exist. The filename is most suspicious. Does it really contain a tab character (\t), or did you intend to write a (windows) dir separator? The backslash is the escape character, so in order to write it in a string literal, you must escape it (with another backslash: \\).

What does this code mean "ofstream fout(getenv("OUTPUT_PATH"));"

I'm still new to cpp, and I will appericate if someone can help me to understand this line of code:
ofstream fout(getenv("OUTPUT_PATH"));
This code I saw almost every single Hacker Rank challange. What is the purpose of this code?
I say, when in doubt, simplify.
When something seems too complex and does not make sense at first glance, find ways to break it into smaller pieces that make sense to you.
ofstream fout(getenv("OUTPUT_PATH"));
can be broken into two pieces.
auto res = getenv("OUTPUT_PATH");
ofstream fout(res);
You can look up the documentation of getenv() to understand what the first line does. In your case, it returns the value of the environment variable OUTPUT_PATH. After the line is executed, res will be that value.
You can lookup the documentation for the constructors of ofstream to understand what the second line does. In your case, it constructs an ofstream object using the value of the environment variable OUTPUT_PATH.
After that line, you can use the fout object to write to the stream. The output will be available in the file defined by the environment variable OUTPUT_PATH.
The reason that Hacker Rank does this is because they have 100's or 1000's of users running the same pieces of code at the same time. To make sure each run uses a unique output file they set OUTPUT_PATH to a unique name before running the code. This will result in the output will be placed into a unique file. The wrapper code on Hacker Rank will then compare the output from your file against the expected output.
It's creating an output file stream with the filename of whatever the environment variable "OUTPUT_PATH" is set to.
it's an easy stuff. It is taking the output environment path and passing
that to the object of output stream i.e fout.
Hope you remember
ios_base -> ios -> ostream -> ofstream
As Per cppreference ,
std::ofstream
typedef basic_ofstream ofstream;
Output stream class to operate on files
std::getenv
Defined in header cstdlib
char* getenv( const char* env_var );
Searches the environment list provided by the host environment (the OS), for a string that matches the C string pointed to by env_var and returns a pointer to the C string that is associated with the matched environment list member.
check out your home path using:
#include <iostream>
#include <cstdlib>
int main()
{
if(const char* env_p = std::getenv("PATH"))
std::cout << "Your PATH is: " << env_p << '\n';
}
you are going to see all the paths you have set in your environment
environment has the location of the compiler or other executable stuff.

How can i solve an issue in writing data in specific file in my clr project?

I am trying to add some data to a specific file in my project. I am doing that in the function below.
void Files::write_employee(employee employeeObject)
{
fstream infile;
infile.open("employeeFile.txt",ios::in|ios::out|ios::app);
string record;
char delimiter='#';
record=employeeObject.get_id()+delimiter;
record+=employeeObject.get_name()+delimiter;
record+=employeeObject.get_password()+delimiter;
record+=employeeObject.get_age()+delimiter;
record+=employeeObject.get_gender()+delimiter;
record+=employeeObject.get_MaritalStatus()+delimiter;
record+=employeeObject.get_ministryName()+delimiter;
record+=employeeObject.get_departmentName()+delimiter;
record+=employeeObject.get_salary()+delimiter;
record+=employeeObject.get_photoPath()+delimiter;
record+=employeeObject.get_photoFileName()+delimiter;
if (infile.fail())exit(1);
else {infile<<record;
infile.close();}
}
This function explains how to add data to my file through save the entered data
in an object and save this values in string record and push it to the file.
The big problem is my file which I am trying to add data in, not created yet.
and I don't know why.
thanks in advance.
You use infile whereas you are outputting to file. While this does not affect the program code, it makes no sense and break your program readability. Use outfile instead.
Remember that it is just like cout << and cin >> for the standard I/O.
Also, try not to use ios::in when your purpose is only to output to the file and vise versa.
According to std::fstream::open example at cplusplus.com, your code is correct and the file must be created. First try to specify an absolute file path to a location that you have write access. If it does not work, print the error message using the following line of code:
cerr << "Error: " << strerror(errno);

Use of `ofstream` appears not to create nor write to file

At the end of a simulation, I want to write some results as an appended row to a data file. The code I am using is the following, where you can assume that outFile was correctly allocated as an std::ofstream, that output_file is a std::string containing a valid path to a file that does not yet exist, and that the variables printed out to the file are just int types that get values during the simulation.
outFile.open(output_file.c_str(), std::ios::out | std::ios::app );
outFile << num_nodes << ", " << tot_s << ", " << tot_c << ", " << tot_d << std::endl;
outFile.close();
I've checked whether it correctly opens the file with the ofstream::is_open() function and it returns false. However, I can't figure out why. I've tried it with many different file names and directory paths, all of which I have checked and they are valid (no typos, etc.)
The file being written is just into a folder on the desktop where I create files all the time, so I don't see how it could be a permissions issue. If it was a permissions issue, how can I check that?
Otherwise, what else can be preventing it from writing to the file?
Added:
Following up on the comments, after adding a call to perror(), it is displaying the "No such file or directory" error. The file path in question is:
/home/ely/Desktop/Evolutionary_Dynamics/GamesOnCycle/data/test.data
I want this file to be created, and all the directories in that path exist, it's all spelled correctly, etc., and there are no weird permission issues with the GamesOnCycle folder or its data subfolder. Note that it is a linux system (Ubuntu 11.04) so the forward slashes are correct for the file path, unless I'm missing something that C++ has to have w.r.t. file paths.
This could be happening due to several reasons.
1) The file is already open.
2) All the directories in the file path are not created.
3) Lack of file permissions.
For an additional reference, please see When will ofstream::open fail?
This may sound bad, but are you on windows or linux? If windows, for your file path, do you have it defined with double "\" in your string, or just one? If just one, you aren't putting the characters in your path that you think you are. To be safe, use the "/" character.
So if you had this:
string pathname = "C:\Users\me\Desktop";
That is NOT a valid path. You are escaping "\U", "\m" and "\D" into your string. You'd need this:
string pathname = "C:\\Users\\me\\Desktop";
or
string pathname = "C:/Users/me/Desktop";
The "/" isn't an escape character.
It's what seems likely to me.