R6025 and the std::locale - c++

I have been struggling with some very simple code to write std::wstring to a file. From some research on stackoverflow it was reccomended that I should set the locale for the file before reading and writting.
typedef std::codecvt_utf8<wchar_t> ConverterType;
ConverterType converter;
// open a file in read mode.
std::wifstream readFile;
// pass in the current locale of the file and the converter
std::locale wloc(readFile.getloc(), &converter); //"en_US.UTF-8");
// imbue the file with the locale
readFile.imbue(wloc);
readFile.open(m_absoluteFilePath, std::ios::in | std::ios::binary);
if (!readFile.is_open())return false;
// read the data from the file
readFile >> readString;
// close the opened file.
readFile.close();
The above causes a R6025 error pure virtual function call. I found an online answer that suggested the following.
(http://forums.codeguru.com/showthread.php?457106-Unicode-text-file)
copy and paste from the page-
"I've got the message "Runtim Error! Program: ... R6025 - pure virtual function call
The reason is that the stream's destructor accesses the facet again which has already been destructed.
You can fix the code by shifting the creation of the facet before the creation of the stream."
...
null_wcodecvt wcodec(1);
std::locale wloc(std::locale::classic(), &wcodec);
std::wfstream file;
file.imbue(wloc);
I think this is exactly my problem, as when I remove the loc code entirely and just read and write to and from the file there is no error. The problem is I can't figure out how to move the wloc declaration prior to the wifstream declaration, since wloc is built using the readFile.getloc(). This seems to be a bit of a chicken and the egg situation to me?
What is the correct way to do this? It also seems strange to me that this dependancy of order does not seem to be well documented?
(On an additional note, I am reading and writting json strings to the file. My understanding is to use the std::ios::binary to simplify all the escape characters in the json string? perhaps this is untrue and a poor choice as I have not been able to test it, but I wanted to explain my choice of using std::ios::binary above.)

Related

Can't access the file(Internal File Buffer NULL)

I have this strange bug. I have a program which writes text to the file using the fstream, but the file is not being created and therefore no text is appended. When I debug my code, it shows me this:
create_new_file = {_Filebuffer={_Pcvt=0x0000000000000000 <NULL> _Mychar=0 '\0' _Wrotesome=false ...} }.
But whenever I use ofstream everything works.
Here is the code:
std::fstream create_new_file{ fileName.str()};
std::unique_ptr<std::string> changes = std::make_unique<std::string>("");
std::cin >> *changes;
create_new_file << *changes << "\n";
Here is the code which works:
std::ofstream create_new_file{ fileName.str()};
I have seen a similar post on Stack Overflow but the answer did not resolve my issue. I have tried adding the std::ios::trunc to the fstream but that did not help. But whenever I use ofstream everything works just as expected.
The problem is that for bidirectional file streams the trunc flag must always be explicitly specified, i.e., if you want the file content to be discarded then you must write in | out | trunc as the second argument as shown below.
Thus, to solve the problem change std::fstream create_new_file{ fileName.str()}; to :
//-------------------------------------------------------------------------vvvvvvvvvvvvvvv---->explicitly use trunc
std::fstream create_new_file{ "output.txt", ios_base::in | ios_base::out | ios_base::trunc};
Working demo
This file stream buffer open reference is useful. It shows a table with the different modes and what happens when they are used.
When you open a std::fstream the default mode for the constructor is in | out. If we look that up in the table we see that this will fail if the file doesn't exist.
And you never check for failure (which you always should do).
If you only want to write to the file then use std::ofstream as it will open the files in out mode, which creates the file if it doesn't exist.
If you want to only append to the file, still use std::ofstream but use the mode out | app, which will create the file and make sure all output is appended (written to the end).

How could I make my own file extention that works on a raspberry pi from C++?

How could I make my own file extention that works on a raspberry pi from C++?
I would like to make a file extention that keeps information for a custom OS for mobile devices such as phones, and tablets. what would the proper way to code an extention for this? information as in names, DOB, maybe their contacts?, and basically anything on the phone that id need to be stored permanantly. how would I do that?
File extensions don't really mean anything, it's just a part of the the file's name. It helps tell the operating system to what program to run with the given file. So making a file extension is quite simple, you just write your data to a file. Here is a great example of doing it in C++
After you have your binary you can read back just as easily, I'll quote a few lines from this site
A file stream object can be opened in one of two ways. First, you can supply a file name along with an i/o mode parameter to the constructor when declaring an object:
ifstream myFile ("data.bin", ios::in | ios::binary);
Alternatively, after a file stream object has been declared, you can call its open method:
ofstream myFile;
...
myFile.open ("data2.bin", ios::out | ios::binary);
Either approach will work with an ifstream, an ofstream, or an fstream object.
Normally, when manipulating text files, one omits the second parameter (the i/o mode parameter). However, in order to manipulate binary files, you should always specify the i/o mode, including ios::binary as one of the mode flags. For read/write access to a file, use an fstream:
fstream myFile;
myFile.open ("data3.bin", ios::in | ios::out | ios::binary);
To read from an fstream or ifstream object, use the read method. This method takes two parameters:
istream& read(char*, int);
The read member function extracts a given number of bytes from the given stream, placing them into the memory pointed to by the first parameter. It is your responsibility to create and manage the memory where read will place its result, as well as to ensure that it is large enough to hold the number of bytes requested. The bytes that are read and not interpreted, the method does not assume anything about line endings, and the read method does not place a null terminator at the end of the bytes that are read in.
If an error occurs while reading (for example, if you read off the end of a file), the stream is placed in an error state. If that occurs, you can use the gcount method to find out the number of characters that were actually read, and use the clear method to reset the stream to a usable state. Once a stream goes into an error state, all future read operations will fail.
An example:
#include <fstream.h>
...
char buffer[100];
ifstream myFile ("data.bin", ios::in | ios::binary);
myFile.read (buffer, 100);
if (!myFile) {
// An error occurred!
// myFile.gcount() returns the number of bytes read.
// calling myFile.clear() will reset the stream state
// so it is usable again.
}
...
if (!myFile.read (buffer, 100)) {
// Same effect as above
}

How to get raw bytes written to ostream by an external library without creating a file

(My previous questions was closed as a duplicate of Are there binary memory streams in C++ which is ridiculous, since i can't change the implementation of the library I'm using)
I'm using a library (Poco) to create zip files. It takes ostream as an input and writes the data of the zip file into it. Something like:
std::ofstream ofs("file.zip", std::ios::binary);
Compress compress(ofs);
// add data to compress ...
compress.close();
// now file.zip contains added file
This works. But I want to be able to create a zip in memory without creating a file. I tried using stringstream instead of ofstream, i get additionl newline characters in the data in the zip file is corrupted. Is there any other stream i can use?
(If someone still thinks it's a duplicate, I'm gonna need an explanation, since I don't see how this other question is helpful for me)
Use a std::stringstream -- that will create an in-memory string that you can write to as an ostream, and WILL NOT add extra newlines. If you later copy the string to an fstream that was opened in text mode (such as std::cout), then that process may add extra CR characters that are not in the string (nor in the original output).
If you are seeing extra characters corrupting your stream, they are coming from somewhere else -- something besides you compress call/lib is writing to the stream, or something with how you are looking at your stream is doing something.
If you're on linux, how about creating an anonymous file using memfd_create? You can then open /proc/self/fd/<fd> and do your stuff. Some implementations of std::ofstream may even provide a constructor that takes a FILE*, you can check if that's the case on your system.

clear data inside text file in c++

I am programming on C++. In my code I create a text file, write data to the file and reading from the file using stream, after I finish the sequence I desire I wish to clear all the data inside the txt file. Can someone tell me the command to clear the data in the txt file. Thank you
If you simply open the file for writing with the truncate-option, you'll delete the content.
std::ofstream ofs;
ofs.open("test.txt", std::ofstream::out | std::ofstream::trunc);
ofs.close();
http://www.cplusplus.com/reference/fstream/ofstream/open/
As far as I am aware, simply opening the file in write mode without append mode will erase the contents of the file.
ofstream file("filename.txt"); // Without append
ofstream file("filename.txt", ios::app); // with append
The first one will place the position bit at the beginning erasing all contents while the second version will place the position bit at the end-of-file bit and write from there.
If you set the trunc flag.
#include<fstream>
using namespace std;
fstream ofs;
int main(){
ofs.open("test.txt", ios::out | ios::trunc);
ofs<<"Your content here";
ofs.close(); //Using microsoft incremental linker version 14
}
I tested this thouroughly for my own needs in a common programming situation I had. Definitely be sure to preform the ".close();" operation. If you don't do this there is no telling whether or not you you trunc or just app to the begging of the file. Depending on the file type you might just append over the file which depending on your needs may not fullfill its purpose. Be sure to call ".close();" explicity on the fstream you are trying to replace.
Deleting the file will also remove the content.
See remove file.
You should create a function which clears all the data of the file and then run it.
void clear()
{
ofstream file("fileout.txt");
file<<"";
}

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