наконецто окончательно и полностью разобрался с консолью + вин + встринги + файлы при юникоде
что надо делать чтобы юзать юникод с консолью и файлами на вин
- всегда юзать wstring
- всегда юзать wcin/wcout
- инициализация
_setmode(_fileno(stdout), _O_U16TEXT);
_setmode(_fileno(stdin), _O_U16TEXT);
SetConsoleCP(CP_UTF8);
_wfopen_s(&f, filename.c_str(), L"wtR,ccs=UTF-8");
из const wstring & filename
- чтение файла:
fread(&(buffer[0]), sizeof(wchar_t), filesize, f);
в std::wstring buffer
- запись файла:
fwrite(&(content[0]), sizeof(wchar_t), content.size(), (FILE*)fileHandle)
из const std::wstring& content
вот обертки для работы с файлами и консолью
/* Returns a list of directories (except the ones that begin with a dot) */
static void ListFilesystem(std::vector<std::wstring> &out, const std::wstring &directory, GetDirMode mode = ANY, bool includeDots = false)
{
using namespace std;
HANDLE dir;
WIN32_FIND_DATA file_data;
if(directory.empty()) { return; }
if ((dir = FindFirstFile((directory + L"/*").c_str(), &file_data)) == INVALID_HANDLE_VALUE)
return; /* No files found */
do {
const wstring file_name = file_data.cFileName;
const wstring full_file_name = directory + L"\\" + file_name;
const bool is_directory = (file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
if ((!includeDots) && (file_name[0] == L'.'))
continue;
if ( ( is_directory && (mode == FILES_ONLY) )
|| ( !is_directory && (mode == DIRS_ONLY ) ) ) {
continue;
}
out.push_back(full_file_name);
} while (FindNextFile(dir, &file_data));
FindClose(dir);
} // GetFilesInDirectory
static size_t GetSizeOfFile(const std::wstring& path)
{
struct _stat fileinfo;
_wstat(path.c_str(), &fileinfo);
return fileinfo.st_size;
}
static std::wstring LoadUtf8FileToString(const std::wstring& filename, size_t limit)
{
std::wstring buffer; // stores file contents
FILE* f = NULL;
errno_t result = 1;
for(size_t i=0; (result != 0) && (i < 5); ++i) {
result = _wfopen_s(&f, filename.c_str(), L"rtR, ccs=UTF-8");
if(result != 0) {
Sleep(10);
}
}
if(result != 0) { return std::wstring(); }
// Failed to open file
if (f == NULL)
{
// ...handle some error...
return buffer;
}
size_t filesize = GetSizeOfFile(filename);
// Read entire file contents in to memory
if ((filesize > 0) && (filesize <= limit))
{
buffer.resize(filesize);
size_t wchars_read = fread(&(buffer[0]), sizeof(wchar_t), filesize, f);
buffer.resize(wchars_read);
//buffer.shrink_to_fit(); // C++11
}
fclose(f);
return buffer;
}
static __time64_t GetUtf8FileDateModified(const std::wstring& filename) {
struct _stat buf;
int result = _wstat( filename.c_str(), &buf );
if(result != 0) {
return 0;
}
return buf.st_ctime;
}
static ptrdiff_t CreateUtf8File(const std::wstring & filename) {
FILE * f = NULL;
errno_t result = 1;
for(size_t i=0; (result != 0) && (i < 5); ++i) {
result = _wfopen_s(&f, filename.c_str(), L"wtR,ccs=UTF-8");
if(result != 0) {
Sleep(10);
}
}
return (ptrdiff_t)f;
}
static bool WriteStringToUtf8File(ptrdiff_t fileHandle, const std::wstring& content, bool newline = true, bool autoclose = false) {
if(!fileHandle || content.empty()) { return false; }
if(newline) {
return (fwrite(&(content[0]), sizeof(wchar_t), content.size(), (FILE*)fileHandle) > 0)
&& (fwrite(L"\n", sizeof(wchar_t), 1, (FILE*)fileHandle) > 0);
}
return (fwrite(&(content[0]), sizeof(wchar_t), content.size(), (FILE*)fileHandle) > 0);
if(autoclose) { fclose((FILE*)fileHandle); }
}
static void CloseUtf8File(ptrdiff_t fileHandle) { fclose((FILE*)fileHandle); }
static bool RemoveUtf8File(const std::wstring & fname) { return _wremove(fname.c_str()) == 0; }
static void Msg(const std::wstring & str = L"", bool endline = true, const std::wstring & prefix = L"") {
if(!prefix.empty()) { std::wcout << prefix; }
std::wcout << L" " << str;
if(endline) { std::wcout << std::endl; }
}
static std::wstring RequestConsoleInput(bool nonBlocking = false) {
if(nonBlocking && (std::wcin.peek() == std::wiostream::traits_type::eof())) {
return std::wstring();
}
std::wstring s;
s.resize(2048);
std::wcin.getline(&(s[0]),2048);
s.resize(wcslen(s.c_str()));
return s;
}