C++ Cin和getline赢得';无法正确保存非ascii字符
我正在尝试打开一个路径包含非ascii字符的文件。用户将文件拖到cmd中,我用getline获得路径。 当我尝试使用用户提供的路径打开文件时,它不起作用C++ Cin和getline赢得';无法正确保存非ascii字符,c++,unicode,utf-8,ascii,C++,Unicode,Utf 8,Ascii,我正在尝试打开一个路径包含非ascii字符的文件。用户将文件拖到cmd中,我用getline获得路径。 当我尝试使用用户提供的路径打开文件时,它不起作用 #include <iostream> #include <string> #include <fstream> #include <cstdlib> using namespace std; int main() { string userInput; //Saves the u
#include <iostream>
#include <string>
#include <fstream>
#include <cstdlib>
using namespace std;
int main() {
string userInput; //Saves the user input
string autoInput = "C:\\Espolón\\file.txt"; //Specifying the path like this works
ifstream file1; //For opening the file with the userInput
ifstream file2; //For opening the file with autoInput
getline(cin, userInput);
system("CLS"); //Clears the CMD
file1.open(userInput); //This throws an error. Note that I didn't use is_open for cleaner code but im actually using it in my tests
file2.open(autoInput); //This works perfectly
cout << "User input: " + userInput << endl<<"Auto input: " + autoInput << endl; //Both show correctly in the CMD
system("pause");
}
#包括
#包括
#包括
#包括
使用名称空间std;
int main(){
字符串userInput;//保存用户输入
string autoInput=“C:\\Espolón\\file.txt”;//像这样指定路径很有效
ifstream file1;//用于使用userInput打开文件
ifstream file2;//用于使用自动输入打开文件
getline(cin,userInput);
系统(“CLS”);//清除命令
file1.open(userInput);//这会引发一个错误。请注意,我没有使用is_open for cleaner代码,但实际上我在测试中使用了它
file2.open(autoInput);//这非常有效
coutWindows API需要UTF16LE格式的Unicode,而不是UTF8格式。宽字符串字符和函数在Windows中被视为UTF16
字母ó
是ANSI,而不是ASCII。Windows也支持ANSI。如果程序在自己的计算机上运行,通常可以使用ANSI,但即使这样,也会遇到问题。如果希望使用ANSI,请尽量不要将其与UTF16和宽字符串格式(std::wstring
)混合使用
Windows 8和10对UTF8的控制台支持有限。但是如果您想避免UTF8的缺陷,建议使用UTF16
以下是UTF16版本:
#include <iostream>
#include <string>
#include <fstream>
#include <cstdlib>
#include <io.h>
#include <fcntl.h>
using namespace std;
int main()
{
_setmode(_fileno(stdout), _O_U16TEXT);
_setmode(_fileno(stdin), _O_U16TEXT);
wstring userInput;
wstring autoInput = L"C:\\Espolón\\file.txt";
ifstream file1, file2;
getline(wcin, userInput);
file1.open(userInput);
file2.open(autoInput);
wcout << L"file1: " << (file1.good() ? L"good\n" : L"bad\n");
wcout << L"file2: " << (file1.good() ? L"good\n" : L"bad\n");
wcout << L"User input: " + userInput << endl;
wcout << L"Auto input: " + autoInput << endl;
system("pause");
return 0;
}
看看你有没有尝试过使用宽字符版本的std::string
、cout
和cin
?对我来说,你的代码很有效。(即使是第一个版本)@ThomasMatthews是的!这在第二个代码块中。@n314159您是否尝试过使用非ascii字符的路径?您使用的是哪种IDE?我使用的是Visual Studio Community 2019。它可以工作!感谢您完整且内容丰富的回答:)不客气,但我的回答还远远不够完整。对于Windows和Uni,这个主题有点混乱代码。请参阅更新的答案和其他参考资料。
#include <iostream>
#include <string>
#include <fstream>
#include <cstdlib>
#include <io.h>
#include <fcntl.h>
using namespace std;
int main()
{
_setmode(_fileno(stdout), _O_U16TEXT);
_setmode(_fileno(stdin), _O_U16TEXT);
wstring userInput;
wstring autoInput = L"C:\\Espolón\\file.txt";
ifstream file1, file2;
getline(wcin, userInput);
file1.open(userInput);
file2.open(autoInput);
wcout << L"file1: " << (file1.good() ? L"good\n" : L"bad\n");
wcout << L"file2: " << (file1.good() ? L"good\n" : L"bad\n");
wcout << L"User input: " + userInput << endl;
wcout << L"Auto input: " + autoInput << endl;
system("pause");
return 0;
}
//need at least c++11 for writable std::string::data()
std::string get_u8(const std::wstring u16)
{
if(u16.empty()) return std::string();
int size = WideCharToMultiByte(CP_UTF8, 0, u16.c_str(), -1, 0, 0, 0, 0);
std::string u8(size, 0);
WideCharToMultiByte(CP_UTF8, 0, u16.c_str(), -1, u8.data(), size, 0, 0);
return u8;
}
std::wstring get_u16(const std::string u8)
{
if(u8.empty()) return std::wstring();
int size = MultiByteToWideChar(CP_UTF8, 0, u8.c_str(), -1, 0, 0);
std::wstring u16(size, 0);
MultiByteToWideChar(CP_UTF8, 0, u8.c_str(), -1, u16.data(), size);
return u16;
}