Trying creating and writing into a txt file in C++ - c++

Basically, I'm following a simple tutorial about files handling in C++.
I've been trying to create and write into a txt file at the same time, but any of the methods I've tried won't actually create a txt file in my executable location.
I should also say that, I print myfile.is_open() just to know if the file truly created and opened, but I get 0 everytime with every method.
What am I doing wrong ?
I mainly tried to create and write to a txt file like this:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
fstream myfile;
myfile.open("example.txt", ios::out);
cout << myfile.is_open() << endl;
myfile << "Writing this to a file.\n";
myfile.close();
}

First, I bet you're using an IDE like Visual Studio. Most IDEs set your working directory somewhere other than your project directory. I don't use Visual Studio, but many of them put them in ../.
So your file is being produced, but not where you think you should find it.
If you compile and run this program without an IDE, you'll get your file where you expect it.
You may also be able to tell your IDE that the working directory should be your project directory.
Now, to keep you from making a few bad habits, I'm going to tell you two more things.
It's considered a mistake to do using namespace std. Instead, I do using statements only on those things I am going to use frequently. In your short code, I wouldn't have done any.
Next, if you're going to write out a file, it's better to use std::ofstream. It's otherwise the same code. But it's a bit clearer that you're only using the file for output.
So my version of your code:
#include <iostream>
#include <fstream>
int main()
{
std::ofstream myfile;
myfile.open("example.txt");
std::cout << myfile.is_open() << std::endl;
myfile << "Writing this to a file.\n";
myfile.close();
}
Yeah, those std:: everywhere can be annoying, so you could do this:
#include <iostream>
#include <fstream>
using std::ofstream;
using std::cout;
using std::endl;
int main()
{
ofstream myfile;
myfile.open("example.txt");
cout << myfile.is_open() << endl;
myfile << "Writing this to a file.\n";
myfile.close();
}
I actually have an include of CommonUsing.h that I put a few things I do almost everywhere.
#pragma once
#include <chrono>
#include <iostream>
#include <date/date.h>
//======================================================================
// The most common using statements I do in most of my code.
//======================================================================
using std::cout;
using std::cerr;
using std::endl;
using std::string;
using namespace std::chrono_literals;
using date::operator<<;

Related

Declaring multiple ifstream makes code crash

I just installed mingw on my Windows 10 computer and wanted to code a program that read two files. I immediately faced a frustrating bug with ifstream: when I declare more than one ifstream, the program seems to crash (nothing is logged although the first line cout some text).
The following code compiles and logs "test" in the console:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
cout << "test" << endl;
ifstream test;
return 0;
}
The following code compiles but seems to crash at runtime, nothing is logged:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
cout << "test" << endl;
ifstream test;
ifstream test2;
return 0;
}
I tested the exact same codes on a macOS Mojave and both codes work and log "test".
I guess the issue is related to the g++ installation but I'd like to know what's really happening and how I can fix this on Windows.

constructor opens a file with a given filename c++

In my code below errors occur and the program will not run, I am required to make a Constructor that must open the file with the given filename. If the filename does not exist then it Prints an error message and terminates the program.
Below is the code that I have done so far in C++:
#include "ReadWords.h"
#include <iostream>
#include <cstdlib>
using namespace std;
ReadWords::ReadWords(const char filename[])
{
wordfile.open(filename);
if (!wordfile)
{
cout << "cannot make " << filename << endl;
exit(1);
}
}
void ReadWords::close()
{
wordfile.close();
}
Why dont you try including fstream to the top of your file and see if that works
I suppose wordfile is of type std::fstream. If your ReadWords.h #includes <fstream>, it should work (compiles and works as expected).
By the way, it's a bad practice to use using namespace std;.
Also, since you use C++, take a look at std::string. It's safer than using plain char* or char[].

find and move files in C++

I'm new to C++ and I've just read <C++ Primer> 4ed. Now I want to implement a little program to help me manage some mp3 files in my computer.
I have a .txt file which includes all the names(part of the names actually) of the files which I want to move(not copy) to a new folder(in the same column). For example, "word" and "file" in the .txt and I want to move all the .mp3 files whose filename contain "word" or "file" to a new folder. Hope my discription is clear, Opps..
I know how to read the strings in .txt into a set<string> and traverse it, but I have no idea how to search and move a file in a folder. I just want to know what else should I learn so that I can implement this function. I read C++ Primer and still I can't do much thing, that's really sad...
To move a file in C++, you do not have to use external libraries like Boost.Filesystem, but you can use standard functionality.
There is the new filesystem API, which has a rename function:
#include <iostream>
#include <filesystem>
int main() {
try {
std::filesystem::rename("from.txt", "to.txt");
} catch (std::filesystem::filesystem_error& e) {
std::cout << e.what() << '\n';
}
return 0;
}
The drawback is to compile it, you need a recent C++17 compiler. (I tested it on gcc 8.0.1, and I also needed to link against -lstdc++fs).
But what should work on any C++ compiler today, is the old C API, which also provides rename (cstdio):
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cerrno>
int main() {
if(std::rename("from.txt", "to.txt") < 0) {
std::cout << strerror(errno) << '\n';
}
return 0;
}
But note that in both cases, the rename will fail if the source and destination files are not on the same filesystem. Then you will see an error like this:
filesystem error: cannot rename: Invalid cross-device link [from.txt] [/tmp/to.txt]
In that case, you can only make a copy and then remove the original file:
#include <fstream>
#include <iostream>
#include <ios>
#include <cstdio>
int main() {
std::ifstream in("from.txt", std::ios::in | std::ios::binary);
std::ofstream out("to.txt", std::ios::out | std::ios::binary);
out << in.rdbuf();
std::remove("from.txt");
}
Or with the new API:
#include <iostream>
#include <filesystem>
int main()
{
try {
std::filesystem::copy("from.txt", "to.txt");
std::filesystem::remove("from.txt");
} catch (std::filesystem::filesystem_error& e) {
std::cout << e.what() << '\n';
}
return 0;
}
Use rename() function to move a file
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
char oldname[] = "C:\\Users\\file_old.txt";
char newname[] = "C:\\Users\\New Folder\\file_new.txt";
/* Deletes the file if exists */
if (rename(oldname, newname) != 0)
perror("Error moving file");
else
cout << "File moved successfully";
return 0;
}
The only way for this to work only using std would be to read the file completely using a std::ifstream and then write it to the new location with a std::ofstream. This will however not remove the old file from disk. So basically you create a copy of the file. Its also much slower than a real move.
The optimal solution is to use OS specific APIs like win32 which e.g provide a MoveFile() function. Poco provides an platform independent abstraction of such APIs. See: http://www.appinf.com/docs/poco/Poco.File.html
Another way to move a file in Windows is using the MoveFile function as it is shown in the following code.
std::wstring oldPath = L"C:\\Users\\user1\\Desktop\\example\\text.txt";
std::wstring newPath = L"C:\\Users\\user1\\Desktop\\example1\\text.txt";
bool result = MoveFile(newPath.c_str(), oldPath.c_str());
if (result)
printf("File was moved!");
else
printf("File wasn't moved!");
under Windows run system call with batch commands:
system("move *text*.mp3 new_folder/");
system("move *word*.mp3 new_folder/");
Under Unix same with shell syntax.

How to link C++ source files with Code::Blocks

I'm doing something wrong, I know. I can't quite figure out how to
link two .cpp files together through a header file. The calling
method can't see the other source.
I'm using Code::Blocks as an IDE with MinGW.
Any help would be greatly appreciated. It would be even more
appreciated if you could show the fixed source, link in the reply to a
pastebin page with it.
/***********************************main.cpp***********************************/
#include <iostream>
using namespace std;
#include "test.h"
int main()
{
printTest(); //can't see printTest, defined in test.cpp
return 0;
};
/***********************************test.h***********************************/
#ifndef TEST_H_INCLUDED
#define TEST_H_INCLUDED
void printTest();
#endif // TEST_H_INCLUDED
/***********************************test.cpp***********************************/
#include "test.h"
void printTest()
{
cout << "Hello world!" << endl;
};
You might find this code blocks wiki helpful. It looks like Code blocks uses a managed build system so if you add the file to the project properly then it should know to compile it and link in the object file that results.
And just to be more explicit about some other comments, when you use "using namespace std;" the namespace is only brought into scope for the file where the using statement is located. That is why others are telling you to explicitly specify the std:: namespace. You could also bring all of the std namespace into scope in the test.cpp file. Many people consider this a bad habit to get into. It's generally better to bring into scope just what you need via
using std::cout;
using std::endl;
Finally, remember that std::endl adds a new line AND flushes the buffer, it's not a good replacement for a new line character in all cases.
In test.cpp replace cout << "Hello world!" << endl;
by std::cout << "Hello world!" << std::endl;
sanket answer’s seems incomplete to me.
You need to add #include <iostream> in your test.cpp so that the compiler knows what "cout" is.
As sanket stated, you should use std::cout and std::endl in test.cpp.

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();
}