Appending to existing file via boost - c++

I need to aggregate many log files into a single log.
I tried to do this with boost::filesystem::copy_file but it doesn't support appending.
Any ideas? (I'm preferring doing this via boost libraries)
Tnx

You don't need Boost for this simple task - the standard iostream will do the job:
#include <fstream>
//...
using std::ifstream;
using std::ofstream;
ifstream input1("input1.log"), input2("file2.log");
// append to an existing file
ofstream output("output.log", ofstream::out | ofstream::app);
output << input1.rdbuf() << input2.rdbuf();
//...
(Note however that the above approach may have suboptimal performance; take a look at this answer to see how to improve the performance.)

Related

How can i edit a txt file without deleting the content in c++?

I want to create a database in a txt file and access it and edit certain parts of it using seekp(), but when I open the file to write in it , the program creates a new file deleting the previous one.
#include <fstream>
#include <iostream>
using namespace std;
int main() {
ofstream g;
g.open("text.txt",ios::out);
if(!g.is_open())
cout<<"error";
else {
g.seekp(2);
g.write("apple",5);
}
g.close();
return 0;
}
You'll need a different open mode.
The documentation is quite obscure when it comes to the behavior of ofstream (for all practical purposes, the behavior you observe is by design: it will truncate).
Use fstream with ios_base::in | ios_base::out | ios_base::binary instead.
Unless you're using some encoding where one character is always one, two, or four bytes, you won't be able to consistently do this with a text mode. Also, writing at any seek position before end-of-file won't shift content past the current seek position, it is simply overwritten. So in order to achieve a database-like behavior, you're at least going to need some kind of fixed-size records or an indexing data structure.

Cannot create a file/write to it, but can read an existing one in c++

I was just learning C++ file handling, but ran into an error immediately using this simple code to create a new file:
#include <iostream>
#include <fstream>
using namespace std;
int main() {
fstream file("test.txt");
file << "test";
file.close();
}
File doesn't show up. When I use .is_open(), it always gives 0. Program does compile though.
Then I manually created a .txt file with some text and tried to read it, and it worked. I supposed it was permission thingy, but it seems like all files are available to be changed? I'm not sure I completely understand how to check the permission though (I'm a bit new to all of this...), so please do help with it as well!
I use Atom and its terminal, my compiler is MingW, but I guess it might be a bit too old.
I tried to include the whole path, but it didn't work.
Thank you!
EDIT:
Just tried this code:
ofstream file;
file.open("C:\\Users\\username\\Desktop\\my_folder\\test.txt");
file << "test";
file.close();
Doesn't help. .is_open() gives 0 before I even try to write to a file.
EDIT:
Just tried this code:
fstream fileW;
fileW.open("write.txt", ios_base::in | ios_base::out | ios_base::trunc);
cout<<fileW.fail()<<endl;
cout<<fileW.is_open()<<endl;
fileW<<"Edit";
fileW.close();
Still doesn't work, returns 1 for .fail().
EDIT:
The error is "Permission denied".
EDIT:
Solved! I deleted Avast, it was blocking my program from accessing files.
Avast, I hate you. You are the worst.
Use
ofstream file("test.txt");
Your version does not create the file if it does not exist.
Similarly for input you should really use ifstream. fstream is best reserved for files you want to read and write from.

How to specify file storage

I work with C ++ and I am almost new.
My question is how to specify where to save the text file.
For example, I wrote a program that creates a text file called "usertext.txt"
And it automatically creates the text file in the code storage. But I want to create a folder For example called patch and save the text file there .
How can this be done?
#include <iostream>
#include <fstream>
using std::ios;
using std::fstream ;
int main(){
fstream filetext;
filetext.open("usertext.txt", ios::app) ;
filetext << "hellow world!" ;
filetext.close();
}
Use the functions in the filesystem library to create the directory first. Then use the directory as part of the full name when opening the file.
std::filesystem::create_directories ("/path/to/");
filetext.open("/path/to/usertext.txt", ios::app) ;
You can also use the path class to form the full name if the user gives the file name separately from the directory.
The function create_directories will create each part of the path that does not already exist; if the full thing already exists it does nothing.
You can just use the path to the folder
filetext.open("patch/usertext.txt", ios::app);
Note however that it won't handle the directory creation if it doesn't exist.
If you can use C++17, you can probably manage the path better using std::filesystem::path. But it might be overkill for your use case.

boost locale c++ - understanding the basics

First of all How do i make the following example work (from boost website):
#include <boost/locale.hpp>
#include <iostream>
using namespace std;
using namespace boost::locale;
int main()
{
generator gen;
// Specify location of dictionaries
gen.add_messages_path(".");
gen.add_messages_domain("hello");
// Generate locales and imbue them to iostream
locale::global(gen(""));
cout.imbue(locale());
// Display a message using current system locale
cout << translate("Hello World") << endl;
}
(tried creating an hello.mo file but still didn't work).
Basically what i am trying to do is to be able to cout a string like: "operation",
and then according to file1 / file2 it will print the string value under id:operation for that specific file.
how can i do that?
Thanks.
boost translate: po file not work might help.
The most confusing step is:
2. Put the .mo file into the correct file structure, for example if your trying to translate to spanish this would be ./es_ES/LC_MESSAGES/hello.mo
It's a wraper of GNU 'gettext' utilities. The manual is useful too.

Read and write image data C++

I've just started learning C++, and I'm working on a program that is supposed to grab an image from the hard disk and then save it as another name. The original image should still remain. I've got it work with text files, because with those I can just do like this:
ifstream fin("C:\\test.txt");
ofstream fout("C:\\new.txt");
char ch;
while(!fin.eof())
{
fin.get(ch);
fout.put(ch);
}
fin.close();
fout.close();
}
But I suppose that it's not like this with images. Do I have to install a lib or something like that to get it work? Or can I "just" use the included libraries? I know I'm not really an expert of C++ so please tell me if I'm totally wrong.
I hope someone can and want to help me! Thanks in advance!
Btw, the image is a .png format.
You can use the std streams but use the ios::binary argument when you open the stream. It's well documented and there is several examples around the internet
You are apparently using MS Windows: Windows distinguishes between "text" and "binary" files by different handling of line separators. For a binary file, you do not want it to translate \n\r to \n on reading. To prevent it, using the ios::binary mode when opening the file, as #Emil tells you.
BTW, you do not have to use \\ in paths under windows. Just use forward slashes:
ifstream fin("C:/test.txt");
This worked even back in WWII using MS-DOS.
If the goal is just to copy a file then CopyFile is probably better choice than doing it manually.
#include <Windows.h>
// ...
BOOL const copySuccess = CopyFile("source.png", "dest.png", failIfExists);
// TODO: handle errors.
If using Windows API is not an option, then copying a file one char at a time like you have done is very inefficient way of doing this. As others have noted, you need to open files as binary to avoid I/O messing with line endings. A simpler and more efficient way than one char at a time is this:
#include <fstream>
// ...
std::ifstream fin("source.png", std::ios::binary);
std::ofstream fout("dest.png", std::ios::binary);
// TODO: handle errors.
fout << fin.rdbuf();