Create a file in linux - c++

I'm new in linux, I'd like to create a file and write something into.
I don't get any error, but the code doesn't create any file...what am I missing?
#include <iostream>
#include <fstream>
int main(){
std::ofstream out("/Home/peter/Dropbox/C++/linux/data.dat", std::ios::out | std::ios::binary);
if(!out)
std::cout << " File isn't open\n" << std::endl;
char s = 'a';
for(int i = 0; i<100; i++)
out.put(s);
return 0;
}

You should add out.close() to the end of your program. This will flush the write buffer to ensure that it was properly written to.
Also, confirm that you actually have (rather, that your program has) permission to create and write files in that directory.
Finally, make sure the path you're writing to is actually correct. As #Adam pointed out in a comment, you probably meant to use /home/... and not /Home/...

I copied and pasted the script, but changed the path, and the code executed successfully. I recommend using out.close() after you are done with the file to close the stream.
You could also use stream operators on the file to write it:
for( int i = 0; i < 100; i++ )
out << s;

Change out.put(s); to out << s;
Secondly once you are done working with files and streams, it is a good practice to close them. It prevents unwanted memory leaks. so put out.close() before return or when you are done working with file.

Related

I can't get the ofstream function to work

Hello and sorry if the answer is clear to those out there. I am still fairly new to programming and ask for some guidance.
This function should write just one of the three string parameters it takes in to the txt file I have already generated. When I run the program the function seems to work fine and the cout statement shows the info is in the string and does get passes successfully. The issue is after running the program I go to check the txt file and find it is still blank.
I am using C++17 on visual studio professional 2015.
void AddNewMagicItem(const std::string & ItemKey,
const std::string & ItemDescription,
const std::string &filename)
{
const char* ItemKeyName = ItemKey.c_str();
const char* ItemDescriptionBody = ItemDescription.c_str();
const char* FileToAddItemTo = filename.c_str();
std::ofstream AddingItem(FileToAddItemTo);
std::ifstream FileCheck(FileToAddItemTo);
AddingItem.open(FileToAddItemTo, std::ios::out | std::ios::app);
if (_access(FileToAddItemTo, 0) == 0)
{
if (FileCheck.is_open())
{
AddingItem << ItemKey;
std::cout << ItemKey << std::endl;
}
}
AddingItem.close(); // not sure these are necessary
FileCheck.close(); //not sure these are necessary
}
This should print out a message onto a .txt file when you pass a string into the ItemKey parameter.
Thank you very much for your help and again please forgive me as I am also new to stackoverflow and might have made some mistakes in formatting this question or not being clear enough.
ADD ON: Thank you everyone who has answered this question and for all your help. I appreciate the help and would like to personally thank you all for your help, comments, and input on this topic. May your code compile every time and may your code reviews always be commented.
As mentioned by previous commenters/answerers, your code can be simplified by letting the destructor of the ofstream object close the file for you, and by refraining from using the c_str() conversion function.
This code seems to do what you wanted, on GCC v8 at least:
#include <string>
#include <fstream>
#include <iostream>
void AddNewMagicItem(const std::string& ItemKey,
const std::string& ItemDescription,
const std::string& fileName)
{
std::ofstream AddingItem{fileName, std::ios::app};
if (AddingItem) { // if file successfully opened
AddingItem << ItemKey;
std::cout << ItemKey << std::endl;
}
else {
std::cerr << "Could not open file " << fileName << std::endl;
}
// implicit close of AddingItem file handle here
}
int main(int argc, char* argv[])
{
std::string outputFileName{"foobar.txt"};
std::string desc{"Description"};
// use implicit conversion of "key*" C strings to std::string objects:
AddNewMagicItem("key1", desc, outputFileName);
AddNewMagicItem("key2", desc, outputFileName);
AddNewMagicItem("key3", desc, outputFileName);
return 0;
}
Main Problem
std::ofstream AddingItem(FileToAddItemTo);
opened the file. Opening it again with
AddingItem.open(FileToAddItemTo, std::ios::out | std::ios::app);
caused the stream to fail.
Solution
Move the open modes into the constructor (std::ofstream AddingItem(FileToAddItemTo, std::ios::app);) and remove the manual open.
Note that only the app open mode is needed. ofstream implies the out mode is already set.
Note: If the user does not have access to the file, the file cannot be opened. There is no need to test for this separately. I find testing for an open file followed by a call to perror or a similar target-specific call to provide details on the cause of the failure to be a useful feature.
Note that there are several different states the stream could be in and is_open is sort of off to the side. You want to check all of them to make sure an IO transaction succeeded. In this case the file is open, so if is_open is all you check, you miss the failbit. A common related bug when reading is only testing for EOF and winding up in a loop of failed reads that will never reach the end of the file (or reading past the end of the file by checking too soon).
AddingItem << ItemKey;
becomes
if (!(AddingItem << ItemKey))
{
//handle failure
}
Sometimes you will need better granularity to determine exactly what happened in order to properly handle the error. Check the state bits and possibly perror and target-specific
diagnostics as above.
Side Problem
Opening a file for simultaneous read and write with multiple fstreams is not recommended. The different streams will provide different buffered views of the same file resulting in instability.
Attempting to read and write the same file through a single ostream can be done, but it is exceptionally difficult to get right. The standard rule of thumb is read the file into memory and close the file, edit the memory, and the open the file, write the memory, close the file. Keep the in-memory copy of the file if possible so that you do not have to reread the file.
If you need to be certain a file was written correctly, write the file and then read it back, parse it, and verify that the information is correct. While verifying, do not allow the file to be written again. Don't try to multithread this.
Details
Here's a little example to show what went wrong and where.
#include <iostream>
#include <fstream>
int main()
{
std::ofstream AddingItem("test");
if (AddingItem.is_open()) // test file is open
{
std::cout << "open";
}
if (AddingItem) // test stream is writable
{
std::cout << " and writable\n";
}
else
{
std::cout << " and NOT writable\n";
}
AddingItem.open("test", std::ios::app);
if (AddingItem.is_open())
{
std::cout << "open";
}
if (AddingItem)
{
std::cout << " and writable\n";
}
else
{
std::cout << " and NOT writable\n";
}
}
Assuming the working directory is valid and the user has permissions to write to test, we will see that the program output is
open and writable
open and NOT writable
This shows that
std::ofstream AddingItem("test");
opened the file and that
AddingItem.open("test", std::ios::app);
left the file open, but put the stream in a non-writable error state to force you to deal with the potential logic error of trying to have two files open in the same stream at the same time. Basically it's saying, "I'm sorry Dave, I'm afraid I can't do that." without Undefined Behaviour or the full Hal 9000 bloodbath.
Unfortunately to get this message, you have to look at the correct error bits. In this case I looked at all of them with if (AddingItem).
As a complement of the already given question comments:
If you want to write data into a file, I do not understand why you have used a std::ifstream. Only std::ofstream is needed.
You can write data into a file this way:
const std::string file_path("../tmp_test/file_test.txt"); // path to the file
std::string content_to_write("Something\n"); // content to be written in the file
std::ofstream file_s(file_path, std::ios::app); // construct and open the ostream in appending mode
if(file_s) // if the stream is successfully open
{
file_s << content_to_write; // write data
file_s.close(); // close the file (or you can also let the file_s destructor do it for you at the end of the block)
}
else
std::cout << "Fail to open: " << file_path << std::endl; // write an error message
As you said being quite new to programming, I have explicitly commented each line to make it more understandable.
I hope it helps.
EDIT:
For more explanation, you tried to open the file 3 times (twice in writing mode and once in reading mode). This is the cause of your problems. You only need to open the file once in writing mode.
Morever, checking that the input stream is open will not tell you if the output stream is open too. Keep in mind that you open a file stream. If you want to check if it is properly open, you have to check it over the related object, not over another one.

Settings in c++ with file .txt

I would like to make a read and write file in c++. I would also like the information i write be a string. so then i can read that string from the file and see the value. Im gonna use this sort of like a settings file where the program can read your settings that you've used and apply them without having to reconfigure the program everytime. In small here's what i got:
int main()
{
std::string tortilla = "tacos";
std::string godast = "pizza";
std::ofstream MyFile;
MyFile.open("1.txt");
MyFile << tortilla;
MyFile.close();
std::ifstream ReadFile("1.txt");
while (std::getline(ReadFile, tortilla))
As you see the code is not done yet by far but i just want to learn this element for now. Thank you in before.
EDIT: Here i want the output of reading "tortilla" to be tacos. So the string is intact troughout
To output the content of tortilla add:
{
std::cout << "tortilla is " << tortilla << std::endl;
}
And iostream must be included for std::cout. HTH.

Unable to open file.txt with c++

I've looked up similar posts here, but none seem to be doing the job for my question. I'm basically trying take a sequence of words in a .txt file and put each word in a vector, and printing each value afterwards. For example, we have I love racing cars in array.txt, and I want my vector to have "I" at position 0, "love" at 1 and so on. Unfortunately, the code does not access "array.txt", so it never executes the code in the if condition.
Now I've heard that by using the fstream library it should work just fine, but the file is never found. I suspect that it doesn't work because it cannot find the path, but I have never opened files in C++. Also, I have not put my file anywhere in my project folder.
Some changes I've already tried:
file.open("array.txt");
omitting file.close();
include "C:\array.txt"; (with the # in front)
file.open("C:\array.txt")
And I'm using Windows 10, if this matters.
#include <iostream>;
#include <string>;
#include <vector>;
#include <fstream>;
//#include <"C:\Users\Samer El-Hage\Documents">;
using namespace std;
void main(){
vector<string> v (10);
ifstream file;
file.open("C:\array.txt", ios::in);
if (file.is_open())
{
for (int i = 0; i < 3; i++)
{
file >> v[i];
}
file.close();
}
else cout << "Could not access file.";
for (int i = 0; i < 3; i++)
{
cout << v[i] << " ";
}
}
This code prints "Could not access file."
The file cannot be opened because the file system can't find the file named "[Bell]rray.txt". the character sequence '\a' is the "Make my computer Beep" character.
Use either forward slashes: "C:/array.txt", an escaped backslash: "C:\\array.txt" or a raw string literal: R"(C:\array.txt)"
The file must also exist at the specified location. If you do not provide a drive and just say "array.txt" the location defaults to wherever the executable is (or in an IDE, the Working Directory).
Also, you have unnecessary semi-colons after your includes. (In fact, in a Treat Warnings as Errors setup, this won't compile!)
I got it! I had not put the .txt file in my folder with the source code, which, strangely enough, was not mentioned in my previous search results... I got to search better!
\a simply turns the computer beep on. Try writing "C:\\array.txt" instead in the open call.
Try not calling open explicitly:
ifstream file ("array.txt");
Look at the examples here:1

ofstream does not create file when running with CLion using CMake

I have this code to create a file, when I run it with CLion it prints out to the console but does not create file, how can I fix this? thanks
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ofstream log_file;
log_file.open("sample23.txt");
if (log_file.is_open())
std::cout << "Open";
log_file << "stuff" << endl;
log_file.close();
return 0;
}
The file may be created into another directory (the working directory).
You can find that location (and change it if needed) as indicated here:
How do I change the working directory for my program
make sure to flush before closing because file is empty
try this out
ofstream f;
f.open( "sample.txt", ios::out );
f << flush;
f.close();
3 things here:
1.) In order to output to another file, you must make another variable like this:
ifstream someoutputfile;
someoutputfile.open("filename");
2.) you actually must make another variable to be "placeholder" of sorts that will automatically assign the first thing your file finds and assigns that to. This may depend on what datatype (int, double, string etc) your input file consists of. Instead of:
log_file << "stuff" << endl;
you can do something like this...
// if my input file is integers for instance..
int data = 0;
log_file >> data;
This can also work for if your file contains multiple data types.
ex:
// if I have two different data types...
string somebody;
int data = 0;
log_file >> data >> somebody;
3.) to output your file data to the screen, just follow a similar way as the example in #1.
someoutputfile << data << somebody << endl;
in addition, dont forget to close the data of BOTH your input and output files:
someoutputfile.close()
Hope that helps in some way :)

Copying File using standard streams to a different location

I am trying to create a method that copies a file to a folder that is local to my project. I am quite puzzled because from what I understand this should work. I decided to create a simple text file to test my copy file method but it doesn't seem to be working.
std::string newFile="Files\\newText.txt";
std::ifstream oldFile("C:\\Users\\dtruman\\Documents\\oldText.txt", std::ios::binary | std::ios::in);
std::ofstream newTarget(newFile, std::ios::binary | std::ios::out);
char c;
while(oldFile.get(c));
{
std::cout << c << std::endl;
newTarget.put(c);
}
newTarget.close();
oldFile.close();
Some of this stuff was me fiddling with the code. My problem is that no matter what I seem to do it never seems to copy the file over correctly, the contents of the new text file are always different then the original. Am I missing something, to my knowledge this block of code should work.
This line
while(oldFile.get(c));
consumes the entire file without any side effects due to the ; at the end.
You need:
while(oldFile.get(c)) // Without the ;
{
std::cout << c << std::endl;
newTarget.put(c);
}