Cannot create a txt file using fstream::open - c++

I have two files and in one I have created simple class :
#include <iostream>
#include <fstream>
#include <string>
#include <time.h>
#include <stdlib.h>
#include <conio.h>
#include <unistd.h>
class myclass{
protected:
int ima,imb,imc,tm;
fstream file;
public:
void creafile(string filename){
string dir;
dir = "txtfile/";
file.open((dir + filename).c_str(), ios::in | ios::out);
if(file.fail()){
// file.open(filename, ios::in | ios::out);
//if(file.fail())
cout<<"Error when creating the file"<<endl;
exit(1);
}
file.close();
}}
and my main file is called data.cpp and contain only this code:
using namespace std;
#include "mylib.h"
int main() {
myclass dat,hi;
dat.creafile("creatorfile.txt");
return 0;
}
My problem is that I always get an error when calling creafile Error when creating the file. To make a simpler test case, I also tried the following code:
file.open("myfile.txt");
if(!file){
cout<<"Error when creating the file"<<endl;
exit(1);
}
file.close();
However, it still gives the error Error when creating the file. I've tried using all flags ios::app ios::in ios::out etc but nothing changes. I have 500gb free space, and running Windows 7.

According to the reference, ios::in | ios::out std::ios_base::openmode configuration will an generate error if the file does not exist, so you won't create a new one with that.
I don't know why you're using the member std::fstream, createfile could just be a static function that does not change any object. You're even closing it afterwards! It would create a file using a local std::ofstream, open mode of which is std::ios_base::out, which will create the file:
std::ofstream ofs(dir + filename); // .c_str() not needed since C++11

Point 1: You cannot open to read if the file doesn't exist. Fortunately you probably don't want to. Simultaneously reading and writing the same file is problematic and almost always a bad idea. Until you know you have to read and write at the same time,
open the file for reading
read in the file
close the file.
edit the file in memory
open the file for writing
write out the file
close the file
If you have a really big file you can't store in memory,
open the file for reading
open a temporary file for writing
read in part of the file
edit the part you read
write the part you read to temporary
if more file, goto 3 (but don't use goto), else continue
close file
close temporary file
delete file
rename temporary file to file
Point 2: You have created the txtfile folder, but have you created it in the right place? Your development environment (include of conio.h suggests Visual Studio or antique) may not be running your program from where you think it is running.
Add this to your code in main:
char buf[4097]; // really big buffer
getcwd(buf, (int)sizeof(buf)); // get working directory
std::cout << buf << std::endl; // print the working directory
If the folder printed out is not where you made the txtfile folder, you can't open the file. If you want to automatically make the folder, read here: How to make a folder/directory
Point 3: exit(1); is a really big hammer. It is a nasty hammer. Read more here. Don't use it without a really, really good reason. In this case return is more than enough to get you out of the function, and if you add a return value to the function, main can test the return value to see if it should continue or return. Or you can throw an exception.

Related

ifstream does not open a file in the next iteration

I have two similar methods that open a file identically, but process them and return values a bit differently, yet while the first method does that successfully, the second method, which is called after the first one, fails.
I have tried changing the path to this file, its extension, but I think I miss some important knowledge about ifstream.
vector<User> Database::createUserDatabase()
{
vector<User> users;
ifstream inputFile;
inputFile.open(pathToFile, ios::in);
//Some file processing
inputFile.close();
return users;
}
And that works perfectly, while
vector<User> Database::createBookDatabase()
{
vector<Book> books;
ifstream inputFile;
inputFile.open(pathToFile, ios::in);
//Some file processing
inputFile.close();
return books;
}
fails to end whenever I check if the file has been opened or not using
inputFile.is_open()
These functions are defined in class files Database.cpp, User.cpp, Book.cpp, which are correctly linked to the main.cpp with the following content:
#include <iostream>
#include <cstdlib>
#include <string>
#include <cstring>
#include <sstream>
#include <vector>
#include <fstream>
#include "../lib/Book.h"
#include "../lib/User.h"
#include "../lib/Database.h"
using namespace std;
int main()
{
Database userDatabase("../database/users.txt", "users");
Database bookDatabase("../database/lmsdb.txt", "books");
vector<User> users = userDatabase.createUserDatabase();
vector<Book> books = bookDatabase.createBookDatabase();
return 0;
}
Here are my Project directories
Using gdb debugger, I have confirmed that the file is not being opened at all. I assume that I did not close the files properly, but I have a little knowledge of C++ yet (been learning it for only a week or so).
Looking forward to see what you can suggest reading/researching, yet I really would like to see a straightforward solution to this problem.
I assume that I did not close the files properly, [..]
Yes, but that probably isn't the cause of the issue. The C++ way is to not close them explicitly. Due to RAII, the ifstream will close itself once it goes out of scope (i.e. when the enclosing function terminates).
There are many reasons why a file could fail to open, including:
It doesn't exist.
Trying to open a read-only file in write mode.
The file is in use by another process. (Maybe you have it opened in an editor?)
Insufficient privileges (e.g. due to the file being protected).

How do I prevent overwriting information in a text file with the ofstream?

I am currently learning C++ and I was trying to add text to a file, but it keeps overwriting it, is there anyway I can append stuff to it?
#include <iostream>
#include <cstdlib>
#include <fstream>
int main()
{
std::ofstream fil3;
fil3.open("test.txt");
file3 << " bye!"; // replaces text already existing in file :(
fil3.close();
return 0;
}
So, I already have a text file with the words "Good" in it and I wanna try adding "bye!" to it so I have "Good Bye!". Can someone explain to me what function I should be using here? Thanks!
When you open the file, use the append flag:
file3.open("test.txt", std::ofstream::app);
You can read more about file operation options here.

Writing To a file using fstream will erase the file

I have a problem, I have a saved text file, I want to use fstream header file in C++ to write something to that file, but using ofstream will erase the whole file as soon as I run the compiled application, why and how to avoid it?
#include <fstream>
#include <iostream>
using namespace std;
int main()
{
ofstream write("1.txt");
return 0;
}
You need to tell ofstream to append to the file.
std::ofstream write("1.txt",std::ios::app);
There are several other flags that control similar characteristics of the stream, read a book or reference for more information.

C++ program sees an included .txt file as code

I am just learning the very basic aspects of input/output streams, and can't seem to have my program read a text file. It gives me errors that indicate it is trying to read the .txt file as C++ code, while I am just using values in there to test my stream.
These are the contents of my included .txt file:
12345
Success
And here is the main program's code:
#include <fstream>
#include <iostream>
#include "C:\Users\Pavel\Desktop\strings.txt"
using namespace std;
int main (int nNumberOfArgs, char* pszArgs[])
{
ifstream in;
in.open("C:\Users\Pavel\Desktop\strings.txt");
int x;
string sz;
in << x << sz;
in.close();
return 0;
}
The first error message I receive is "expected unqualified-id before numeric constant" which tells me the program is attempting to compile the included file. How can I prevent this and have the text file read as intended?
Don't #include your .txt file. Includes are for source code. They textually insert the file into your code, as if you had actually copy-pasted it there. You shouldn't be #includeing a file you're opening with an ifstream.
Opening files on the filesystem at runtime doesn't require any mention of that file's name in the source code. (You could, for instance, ask the user for a filename, and then open it just fine!)
The case where you might #include data in your source would be if you wanted to have that data embedded into the executable of your program (and thus not rely on a file that was on the filesystem when running). But to do that, you have to format your file as a valid C++ data declaration. So it would not be a .txt file at that point.
For instance, in strings.cpp
#include <string>
// See http://stackoverflow.com/questions/1135841/c-multiline-string-literal
std::string myData =
"12345\n"
"Success";
Then in your main program:
#include <iostream>
#include <sstream>
#include "strings.cpp"
using namespace std;
int main (int nNumberOfArgs, char* pszArgs[])
{
istringstream in (myData);
int x;
// Note: "sz" is shorthand for "string terminated by zero"
// C++ std::strings are *not* null terminated, and can actually
// legally have embedded nulls. Unfortunately, C++ does
// have to deal with both kinds of strings (such as with the
// zero-terminated array of char*s passed as pszArgs...)
string str;
// Note: >> is the "extractor"
in >> x >> str;
// Note: << is the "inserter"
cout << x << "\n" << str << "\n";
return 0;
}
Generally speaking, just #include-ing a source file like this is not the way you want to do things. You'll quickly run into trouble if you do that in more than one file in your project (duplicate declarations of myData). So the usual trick is to separate things into header files and implementation files...including the headers as many times as you want, but only putting one copy of the implementation into your build process.
An #include directive works the same way regardless of the extension of the file being included - txt, h, no extension at all - it doesn't matter. How it works is the contents of the file are pasted into your source file by the preprocessor before that file is passed to the compiler. As far as the compiler is concerned, you might as well have just copied and pasted the contents yourself.

Strange fstream problem

I have really strange problem. In Visual C++ express, I have very simple code, just:
#include <fstream>
using namespace std;
int main()
{
fstream file;
file.open("test.txt");
file<<"Hello";
file.close();
}
This same code works OK in my one project, but when I create now project and use this same lines of code, no file test.txt is created. Please, what is wrong?ยจ
EDIT: I expect to see test.txt in VS2008/project_name/debug - just like the first functional project does.
Canonical code to write to a file:
#include <fstream>
#include <iostream>
using namespace std;
int main() {
ofstream file;
file.open("test.txt");
if ( ! file.is_open() ) {
cerr << "open error\n";
}
if ( ! ( file << "Hello" ) ) {
cerr << "write error\n";
}
file.close();
}
Whenever you perform file I/O you must test every single operation, with the possible exception of closing a file, which it is not usually possible to recover from.
As for the file being created somewhere else - simply give it a weird name like mxyzptlk.txt and then search for it using Windows explorer.
Perhaps the executable is run in a different directory than it was before, making test.txt appear somewhere else. Try using an absolute path, such as "C:\\Users\\NoName\\Desktop\\test.txt" (The double backslashes are needed as escape characters in C strings).
fstream::open() takes two arguments: filename and mode. Since you are not providing the second, you may wish to check what the default argument in fstream is or provide ios_base::out yourself.
Furthermore, you may wish to check whether the file is open. It is possible that you do not have write permissions in the current working directory (where 'test.txt' will be written since you don't provide an absolute path). fstream provides the is_open() method as one way of checking this.
Lastly, think about indenting your code. While you only have a few lines there, code can soon become difficult to read without proper indentation. Sample code:
#include <fstream>
using namespace std;
int main()
{
fstream file;
file.open("test.txt", ios_base::out);
if (not file.is_open())
{
// Your error-handling code here
}
file << "Hello";
file.close();
}
You can use Process Monitor and filter on file access and your process to determine whether the open/write is succeeding and where on disk it's happening.
Theres two ways to fix this. Either do:
file.open("test.txt", ios::out)
#include <fstream>
using namespace std;
int main()
{
fstream file;
file.open("test.txt", ios::out);
file<<"Hello";
file.close();
}
Or you can create an ofstream instead of fstream.
#include <fstream>
using namespace std;
int main()
{
ofstream file;
file.open("test.txt");
file<<"Hello";
file.close();
}