How to save a CSV file as UTF-8 - c++

I write the code to create the . CSV files out there with Thai characters. But when I open a file using Microsoft Excel Thai characters in that file a wrong.But when I open it in Notepad, and then I press Save. And open it in Excel again. It is desired I think it is because the program does not Encoding to utf-8.
I had to do to Program, save it as utf-8.
std:: ofstream MyCSVFile;
MyCSVFile.open("myfile.csv", std::ios::out | std::ios::app);
MyCSVFile << "Name,Address" << endl;
MyCSVFile <<name<<","<<address << endl;
MyCSVFile.close();
}

You need to write the BOM to the beginning of the file. Try this:
const char *bom = "\xef\xbb\xbf";
MyCSVFile << bom;
MyCSVFile << "Name...
This a good read: BOM in Wikipedia.

You need to do the following (assuming the file path is stored in FilePath):
Here is the code you should use:
const std::wstring fileStr(FilePath);
wofstream mFile(FilePath);
mFile.imbue(std::locale(std::locale::empty(), new std::codecvt_utf8<wchar_t>));
if (mFile.is_open())
{
const wchar_t *bom = L"\xef\xbb\xbf";
mFile << bom;
...
Now you can write the text, and of course close the file.

Related

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.

How to read UTF-8 file data in C++?

I have a list of IPA (UTF-8) symbols in a text file called ipa.txt with numbers assigned to them. How do I cross reference it with a source file which is also a text file that contains a bunch of words and their corresponding IPA, to return a text file for every names with their names as their filename and inside the text file should contain their corresponding numbers of IPA.
Below is what I've tried but didn't work, only outputs were mostly 000000.
int main()
{
std::unordered_map <wchar_t, int> map;
std::wifstream file;
file.open("ipa.txt");
if (file.is_open()) {
std::cout << "opened ipa file";
}
wchar_t from;
int to;
while (file >> from >> to) {
map.insert(std::make_pair(from, to));
}
std::wifstream outfile;
outfile.open("source.txt");
if (outfile.is_open()) {
std::cout << "opened source file";
}
std::wstring id;
std::wstring name;
while (outfile >> id >> name) {
std::ofstream outputfile;
outputfile.open(id + L".txt");
for (wchar_t c : name) outputfile << map[c];
}
system("pause");
return 0;
}
I believe you are using the wrong type for c used in the iteration over name. As c is used as key for the map, and name is a wstring, you should use:
for (wchar_t c : name) outputfile << map[c];
instead of:
for (char c : name) outputfile << map[c];
Isn't it?
Hope this may help, Stefano
First thought:
map <- std::unordered_map<char, int>
open ipa.txt:
for each line in file:
map[line[0]] = line[1]
open source.txt:
for each line in file:
create and open line[0].txt:
for each char in line[1]:
write map[char] to line[0].txt
Regarding the actual C++ implementation, AFAIK utf-8 should fit inside char and std::string so you don't have to do anything special there. If you need utf-8 string literals you must use the u8 prefix: u8"literal". Everything else should be standard file IO.
EDIT: Here are some links to the relevant documentation to help you get started:
ifstream (for reading from files)
ofstream (for writing to files)
unordered_map (for mapping 'keys' to 'values')
Outside of that it will probably just take a little Googling. File IO is very common so I'm sure you can find some good examples online. As long as your file format is consistent you shouldn't have too much trouble with the file parsing. Then the rest of it is just storing values in the map and then looking them up when you need them, which is pretty simple.

What should binary file look like after conversion from text?

Problem:
Split the binary I/O from the example code into two: one program that converts an ordinary text file into binary and one program that reads binary and converts into text. Test these programs by comparing a text file with what you get by converting it to binary and back.
Example code:
#include "std_lib_facilities.h"
int main(){
cout <<"Please enter input file name.\n";
string name;
cin >> name;
// open file to read, with no byte interpretation
ifstream ifs(name.c_str(), ios_base::binary);
if(!ifs) error("Can't open input file: ", name);
cout << "Please enter output file name.\n";
cin >> name;
// open file to write
ofstream ofs(name.c_str(), ios_base::binary);
if(!ofs) error("Can't open output file: ", name);
vector<int> v;
// read from binary file
int i;
while(ifs.read(as_bytes(i), sizeof(int))) v.push_back(i);
// do something with v
// write to binary file
for(int i = 0; i < v.size(); ++i) ofs.write(as_bytes(v[i]), sizeof(int));
return 0;
}
Here is my code, instead of reading and writing int values, I tried with strings:
#include "std_lib_facilities.h"
void textToBinary(string, string);
//--------------------------------------------------------------------------------
int main(){
const string info("This program converts text to binary files.\n");
cout << info;
const string testFile("test.txt");
const string binaryFile("binary.bin");
textToBinary(testFile, binaryFile);
getchar();
return 0;
}
//--------------------------------------------------------------------------------
void textToBinary(string ftest, string fbinary){
// open text file to read
ifstream ift(ftest);
if(!ift) error("Can't open input file: ", ftest);
// copy contents in vector
vector<string>textFile;
string line;
while (getline(ift,line)) textFile.push_back(line);
// open binary file to write
ofstream fb(fbinary, ios::binary);
if(!fb) error("Can't open output file: ", fbinary);
// convert text to binary, by writing the vector contents
for(size_t i = 0; i < textFile.size(); ++i){ fb.write(textFile[i].c_str(), textFile[i].length()); fb <<'\n';}
cout << "Conversion done!\n";
}
Note:
My text file contains Lorem Ipsum, no digits or special punctuation. After I write the text using binary mode, there is a perfect character interpretation and the source text file looks exactly like the destination. (My attention goes to the fact that when using binary mode and the function write(as_bytes(), sizeof()), the content of the text file is translated perfectly and there are not mistakes.)
Question:
How should the binary file look like after I use binary mode(no char interpretation) and the function write(as_bytes(), sizeof()) when writing?
In both Unix-land and Windows a file is primarily just a sequence of bytes.
With the Windows NTFS file system (which is default) you can have more than one sequence of bytes in the same file, but there is always one main sequence which is the one that ordinary tools see. To ordinary tools every file appears as just a single sequence of bytes.
Text mode and binary mode in C++ concern whether the basic i/o machinery should translate to and from an external convention. In Unix-land there is no difference. In Windows text mode translates newlines from internal single byte C convention (namely ASCII linefeed, '\n'), to external double byte Windows convention (namely ASCII carriage return '\r' + linefeed '\n'), and vice versa. Also, on input in Windows, encountering a single byte value 26, a "control Z", is or can be interpreted as end of file.
Regarding the literal question,
” The question is in what format are they written in the binary file, shouldn't they be written in not-interpreted form, i.e raw bytes?
the text is written as raw bytes in both cases. The difference is only about how newlines are translated to the external convention for newlines. Since your text 1)doesn't contain any newlines, there's no difference. Edit: Not shown in your code except by scrolling it sideways, there's a fb <<'\n' that outputs a newline to the file opened in binary mode, and if this produces the same bytes as in the original text file, then there is no effective translation, which implies you're not doing this in Windows.
About the extra streams for Windows files, they're used e.g. for Windows (file) Explorer's custom file properties, and they're accessible e.g. via a bug in the Windows command interpreter, like this:
C:\my\forums\so\0306>echo This is the main stream >x.txt
C:\my\forums\so\0306>dir | find "x"
04-Jul-15 08:36 PM 26 x.txt
C:\my\forums\so\0306>echo This is a second byte stream, he he >x.txt:2nd
C:\my\forums\so\0306>dir | find "x"
04-Jul-15 08:37 PM 26 x.txt
C:\my\forums\so\0306>type x.txt
This is the main stream
C:\my\forums\so\0306>type x.txt:2nd
The filename, directory name, or volume label syntax is incorrect.
C:\my\forums\so\0306>find /v "" <x.txt:2nd
This is a second byte stream, he he
C:\my\forums\so\0306>_
I just couldn't resist posting an example. :)
1) You state that “My text file contains Lorem Ipsum, no digits or special punctuation”, which indicates no newlines.

Creating the same text file over and over

I need to create a program that writes a text file in the current folder, the text file always contains the same information, for example:
Hello,
This is an example of how the text file may look
some information over here
and here
and so on
So I was thinking in doing something like this:
#include <iostream>
#include <fstream>
using namespace std;
int main(){
ofstream myfile("myfile.txt");
myfile << "Hello," << endl;
myfile << "This is an example of how the text file may look" << endl;
myfile << "some information over here" << endl;
myfile << "and here" << endl;
myfile << "and so on";
myfile.close();
return 0;
}
Which works if the number of lines in my text file is small, the problem is that my text file has over 2000 lines, and I'm not willing to give the myfile << TEXT << endl; format to every line.
Is there a more effective way to create this text file?
Thanks.
If you have the problem of writing in same file, you need to use an append mode.
i.e., your file must be opened like this
ofstream myfile("ABC.txt",ios::app)
You may use Raw string in C++11:
const char* my_text =
R"(Hello,
This is an example of how the text file may look
some information over here
and here
and so on)";
int main()
{
std::ofstream myfile("myfile.txt");
myfile << my_text;
myfile.close();
return 0;
}
Live example
Alternatively, you may use some tools to create the array for you as xxd -i
If you don't care about the subtile differences between '\n' and std::endl, then you can create a static string with your text outside of your function, and then it's just :
myfile << str // Maybe << std::endl; too
If your text is really big, you can write a small script to format it, like changing every newlines with "\n", etc.
It sounds like you should really be using resource files. I won't copy and paste all of the information here, but there's a very good Q&A already on this website, over here: Embed Text File in a Resource in a native Windows Application
Alternatively, you could even stick the string in a header file then include that header file where it's needed:
(assuming no C++11 since if you do you could simply use Raw to make things a little easier but an answer for that has already been posted - no need to repeat).
#pragma once
#include <iostream>
std::string fileData =
"data line 1\r\n"
"data line 2\r\n"
"etc.\r\n"
;
Use std::wstring and prepend the strings with L if you need more complex characters.
All you need to do is to write a little script (or even just use Notepad++ if it's a one off) to replace backslashes with double backslash, replace double quotation marks with backslash double quotation marks, and replace line breaks with \r\n"{line break}{tab}". Tidy up the beginning and end, and you're done. Then just write the string to a file.

C++ write text to file, how to multiple lines

How do you write multiple lines to a file? ... This is what I have.. Also, some of the lines include text like: #import <Foundation/Foundation.h> How would I go about doing this? The code below is what I have right now..
//Creates Config.h
FILE * pFile;
char *buffer = "//Empty Header File";
char file [256];
sprintf (file , "%s/Desktop/%s/Control.h",homeDir, game_name);
pFile = fopen (file, "w+");
fwrite (buffer , sizeof(char), sizeof(buffer), pFile);
fclose (pFile);
Since this is C++, I suggest you utilize the standard IOStreams library and use the concrete file stream classes std::ifstream and std::ofstream for handling files. They implement RAII to handle the closing of the file, and use built in operators and the read()/write() member functions to perform formatted and unformatted I/O respectively. Moreover, they blend well together with the use of std::basic_string, the standard C++ string class.
With that said, if we implement this in C++ correctly, it should look like this:
std::string path = "/Desktop/";
std::string filename = homeDir + path + game_name + "/Control.h";
std::ofstream file(filename, std::ios_base::app);
This handles opening the file, but as you say you wish to write multiple lines to a file. Well this is simple. Just use '\n' whenever you wish to put a newline:
file << buffer << '\n';
If you give us more information about your issue, I will be able to elaborate more in my answer. But until you do, the above is sufficient.
Change to
sprintf (file , "%s/Desktop/%s/Control.h\n",homeDir, game_name);
\n - is a new-line code.
In C++ you would do it like this:
ofstream fout("someplace/Control.h");
fout << "a line of text" << endl;
fout << "another line of text" << endl;
I've left out some details like how to construct a filename and how to open a file in "append" mode, but you should try to tackle one problem at a time.