Manage a Chinese .txt in C++ - c++

i'm trying to show in the console a cinese text, it has been pasted from wikipedia in a .txt file (i don't know the codification, maybe UTF-8?)
// reading a text file
#include <iostream>
#include <fstream>
#include <string>
#include <locale>
#include <codecvt>
using namespace std;
int main () {
const locale utf8_locale
= locale(locale(), new std::codecvt_utf8<wchar_t>());
std::wifstream file("dao.txt");
file.imbue(utf8_locale);
wstring s;
if (file.is_open())
{
while (getline(file, s))
{
cout << s << '\n';
// Do something with the string
}
else cout << "Unable to open file";
myfile.close();
}
return 0;
}
I receive:
error: no match for 'operator<<' (operand types are 'std::ostream {aka std::basic_ostream}' and 'std::__cxx11::wstring {aka std::__cxx11::basic_string}')|
Why does << is not overloaded?

There are a couple of errors:
Else does not match if
if (file.is_open())
{
...
else cout << "Unable to open file";
...
}
Use std::wcout. s is a wide string. Use the wide output.
std::wcout << s << '\n'; // not std::cout notice the w
No variable called myfile I probably meant file
/*my*/file.close();
Note:
You have to imbue the stream before opening it.
std::wifstream file;
file.imbue(utf8_locale);
file.open("dao.txt");
The problem is that an imbue will fail if any characters have been read from the file. Some implementations will check to see if there is a BOM marker (putting the chars back if there are none). But checking these BOM characters means the file has been read and thus will make the imbue fail. So always imbue the file before opening.

Related

In C++, opening a csv file with ifstream

I am trying to open a csv file in C++ using ifstream with a directory in the file path name. The file does reside in the specified directory location, but I observe an for the variable inFile when executing the code. My research up to this point says the code is correct, but something obviously is wrong. Any suggestions?
Thanks,
KG
#include <string>
#include <fstream>
#include <iostream>
virtual void run()
{
string file_dir = "/home/datafiles/";
string csvFile = file_dir + "/myFile.csv";
ifstream inFile;
inFile.open("csvFile", ios::in);
// file check to see if file is open
if(!inFile.is_open()) {
cout << "error while opening the file" << endl;
}
}
I found the answer to my csv file opening problem, a colleague assisted.
#David - You suggested removing the double quotes in the "inFile.open" line of code. In addition to removing the double quotes, I also needed to add c_str(), which "returns a pointer to a null-terminated character array with data equivalent to those stored in the string," .data() also performs the same function (cppreference.com).
#user4581301 - I am also aware that ios::in is implied with a ifstream, only included it here as a reference; thanks.
The modified code is listed below:
#include <string>
#include <fstream>
#include <iostream>
virtual void run()
{
string file_dir = "/home/datafiles/";
string csvFile = file_dir + "/myFile.csv";
ifstream inFile;
inFile.open(csvFile.c_str(), ios::in);
// file check to see if file is open
if(!inFile.is_open()) {
cout << "error while opening the file" << endl;
}
}
Really appreciate all the help.
Enjoy,
KG
Is this what you're trying to do?
#include <iostream> // std::{ cout, endl }
#include <string> // std::{ string, getline }
#include <fstream> // std::ifstream
auto main() -> int {
// Just to demonstrate.
// You want to use your real path instead of example.cpp
auto file = std::ifstream("example.cpp");
auto line = std::string();
while ( std::getline(file, line) )
std::cout << line << '\n';
std::endl(std::cout);
}
Live example

Characters not recognized while reading from file

I have the following c++ code in visual studio to read characters from a file.
ifstream infile;
infile.open(argv[1]);
if (infile.fail()) {
cout << "Error reading from file: " << strerror(errno) << endl;
cout << argv[0] << endl;
}
else {
char currentChar;
while (infile.get(currentChar)) {
cout << currentChar << " " << int(currentChar) << endl;
//... do something with currentChar
}
ofstream outfile("output.txt");
outfile << /* output some text based on currentChar */;
}
infile.close();
The file in this case is expected to contain mostly normal ASCII characters, with the exception of two: “ and ”.
The problem is that the code in it's current form is not able to recognise those characters. couting the character outputs garbage, and its int conversion yields a negative number that's different depending on where in the file it occurs.
I have a hunch that the problem is encoding, so I've tried to imbue infile based on some examples on the internet, but I haven't seemed to get it right. infile.get either fails when reaching the quote character, or the problem remains. What details am I missing?
The file you are trying to read is likely UTF-8 encoded. The reason most characters read fine is because UTF-8 is backwards compatible with ASCII.
In order to read a UTF-8 file I'll refer you to this: http://en.cppreference.com/w/cpp/locale/codecvt_utf8
#include <fstream>
#include <iostream>
#include <string>
#include <locale>
#include <codecvt>
...
// Write file in UTF-8
std::wofstream wof;
wof.imbue(std::locale(std::locale::empty(), new std::codecvt_utf8<wchar_t,0x10ffff,std::generate_header>));
wof.open(L"file.txt");
wof << L"This is a test.";
wof << L"This is another test.";
wof << L"\nThis is the final test.\n";
wof.close();
// Read file in UTF-8
std::wifstream wif(L"file.txt");
wif.imbue(std::locale(std::locale::empty(), new std::codecvt_utf8<wchar_t,0x10ffff, std::consume_header>));
std::wstringstream wss;
wss << wif.rdbuf();
(from here)
try:
while (infile.get(&currentChar, 1))
Also, be sure that you pass argv[1]. Print its value:
cout<<argv[1]<<endl;

Open a file with C++ and output the text that is in the file

I am trying to open a file with C++ and output the text that is in the file. I cannot seem to figure out what I am doing wrong. Here is what I have so far.
#include <iostream>
#include <string>
#include <fstream>
#include <cstdlib>
using namespace std;
int main()
{
char fileName[50];
ifstream infile;
cout << "Enter the name of the file you would like to open: ";
cin.getline(fileName, 50);
infile.open(fileName);
if(!infile.is_open())
{
exit(EXIT_FAILURE);
}
char line[75];
infile >> line;
while (infile.good())
{
cout << line << " ";
infile >> line;
}
system("pause");
return 0;
}
After I input the file name and press enter the CMD prompt just closes. I know that the file exist, but I cannot figure out why it is exiting. Obviously it is because of the exit command, but it should be open. What am I doing wrong?
You don't need to read/write the file line by line; C++ already supports to copy the file in one step. You also should use string instead of char[] for your strings; on one hand it means that you don't need to restrict the maximal length of your strings to some arbitrary length (what if your file's pathname has more than 50 characters, or the file has lines with more than 75 characters?
Note also that your file copying code is erroneous: It will remove all whitespace from the file, as infile >> line does not read a line (use readline for that), but a word, discarding whitespace.
Also, your code should give an error message if it couldn't open the file, instead of just silently returning (you do provide an error return, which is very good, but unless you call it from something that actually gives you feedback on the error return, you'll never learn about it.
Finally, the system("pause") should probably be done in an RAII class, so it is guaranteed to be exited on return (however, exit will not call destructors, so unless you want to use atexit, you should use return in `main`` instead). A better idea would, however, be to not put this into the code, but instead run it in a terminal that doesn't immediately close after the program finishes.
Here's a program that implements those suggestions:
#include <iostream>
#include <fstream>
#include <cstdlib>
int main()
{
// make sure that system("pause") is called on all exit paths
struct cleanup
{
~cleanup() { std::system("pause"); }
} do_cleanup;
// get the file name
std::string filename;
std::cout << "Enter the name of the file you would like to open: ";
std::getline(std::cin,filename);
if (!std::cin)
{
std::cerr << "Failed to read the file name.\n";
return EXIT_FAILURE;
}
// open the file
std::ifstream infile(filename.c_str());
if (!infile)
{
std::cerr << "Could not open file: " << filename << "\n";
return EXIT_FAILURE;
}
// print the file
std::cout << infile.rdbuf();
// close the file
infile.close();
if (!infile)
{
std::cerr << "Could not properly close file: " << filename << "\n";
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
There is no need to use a char[]. You've even #included string so just use that.
string fileName;
cout << "Enter the name of the file you would like to open: ";
cin >> fileName;
// or
// getline(cin, fileName);
ifstream infile(fileName);
if (infile.fail()) {
exit(EXIT_FAILURE);
}
string line;
while (infile >> line) {
cout << line << " ";
}
system("pause");
return 0;
I also modified a few things to make it a bit cleaner.
Thanks for the help. Yes the file was in the wrong folder. It was a newb oversight!

Read all character including the null byte

I want to read out the chrome history from its file. I want to get all characters and null byte that's in that file. The problem I'm facing is that I only get some part of the text that's in the file. I belive it stop due to a null byte or a speical character.
Here´s my code that I have at the moment.
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
using namespace std;
int main(){
string str;
std::ifstream in("c:/Users/Petrus/Documents/History"); // I have copy my file into my documents to make sure I'm not interfering with Chrome.
std::stringstream buffer;
if (!in.is_open()){
cout << "Failed to open" << endl;
}
else{
cout << "Opened OK" << endl;
}
buffer << in.rdbuf();
std::string contents(buffer.str());
while (getline(buffer, str))
{
cout << str;
}
in.close();
system("PAUSE");
return 0;
}
If you want to take a look at the chrome history file its located at:
C:\Users\YOUR NAME\AppData\Local\Google\Chrome\User Data\Default -->History
(PS You have to include hidden files to be able to see Appdata.)
Thanks in advance
std::getline() should be used only to read plain text files.
To read arbitrary binary files you should use read(). Additionally, on your operating system you must open binary files using the std::ios::binary flag.

fstream to display all text in txt

I want to display all the text that is in the fille to the output,
I use by using the code below, the code I got up and results posts are just a little out
#include <fstream>
#include <iostream>
using namespace std;
int main()
{
char str[10];
//Creates an instance of ofstream, and opens example.txt
ofstream a_file ( "example.txt" );
// Outputs to example.txt through a_file
a_file<<"This text will now be inside of example.txt";
// Close the file stream explicitly
a_file.close();
//Opens for reading the file
ifstream b_file ( "example.txt" );
//Reads one string from the file
b_file>> str;
//Should output 'this'
cout<< str <<"\n";
cin.get(); // wait for a keypress
// b_file is closed implicitly here
}
The above code simply displays the words "This" does not come out all into output.yang I want is all text in the file appear in the console ..
The overloaded operator>> for char* will only read up to the first whitespace char (it's also extremely risky, if it tries to read a word longer then the buf length you'll end up with undefined behavior).
The following should do what you want in the most simple manner, as long as your compiler supports the rvalue stream overloads (if not you'll have to create a local ostream variable and then use the stream operator):
#include <fstream>
#include <iostream>
int main()
{
std::ofstream("example.txt") << "This text will now be inside of example.txt";
std::cout << std::ifstream("example.txt").rdbuf() << '\n';
}
try something like this
#include <fstream>
#include <iostream>
using namespace std;
int main(){
string line;
ofstream a_file ( "example.txt" );
ifstream myfile ("filename.txt");
if (myfile.is_open()) {
while ( getline (myfile,line) ) {
a_file << line << '\n';
}
myfile.close();
a_file.close();
} else
cout << "Unable to open file";
}
Hope that helps
This is not the best way to read from a file. You probably need to use getline and read line by line. Note that you are using a buffer of fixed size, and you might cause an overflow. Do not do that.
This is an example that is similar to what you wish to achieve, not the best way to do things.
#include <fstream>
#include <iostream>
using namespace std;
int main() {
string str;
ofstream a_file("example.txt");
a_file << "This text will now be inside of example.txt";
a_file.close();
ifstream b_file("example.txt");
getline(b_file, str);
b_file.close();
cout << str << endl;
return 0;
}
This is a duplicate question of:
reading a line from ifstream into a string variable
As you know from text input/output with C++, cin only reads up to a newline or a space. If you want to read a whole line, use std::getline(b_file, str)