Nie można sobie wyobrazić czegoś tak podstawowego, jak otwarcie pliku przy użyciu standardowej biblioteki C++ dla aplikacji Windows było trudne ... ale wygląda na to, że jest. Według Unicode mam na myśli UTF-8, ale mogę przekonwertować na UTF-16 lub cokolwiek innego, chodzi o to, aby uzyskać instancję od nazwy pliku Unicode. Zanim zhackuję własne rozwiązanie, czy jest tu preferowana trasa? Zwłaszcza wieloplatformowy?Jak otworzyć std :: fstream (ofstream lub ifstream) z nazwą pliku Unicode?
Odpowiedz
Standardowa biblioteka C++ nie działa w standardzie Unicode. char
i wchar_t
nie są wymagane do kodowania Unicode.
W Windows wchar_t
jest UTF-16, ale nie ma bezpośredniego wsparcia dla UTF-8 nazw w bibliotece standardowej (the char
typ danych nie jest Unicode w systemie Windows)
Z MSVC (a tym samym STL Microsoft) , konstruktor dla filestreams jest warunkiem, który zajmuje const wchar_t*
pliku, co pozwala na tworzenie strumienia jak:
wchar_t const name[] = L"filename.txt";
std::fstream file(name);
to jednak przeciążenie nie jest określony przez standard C++ 11 (gwarantuje jedynie obecność char
wersja oparta). Nie ma go również w alternatywnych implementacjach STL, takich jak GCC's libstdC++ dla MinGW (-w64), od wersji g ++ 4.8.x.
Należy pamiętać, że podobnie jak char
w systemie Windows nie jest UTF8, w innych systemach operacyjnych wchar_t
może nie być UTF16. Więc ogólnie rzecz biorąc, nie jest to przenośne. Otwarcie strumienia z nazwą pliku wchar_t
nie jest zdefiniowane zgodnie ze standardem, a podanie nazwy pliku w postaci char
może być trudne, ponieważ kodowanie używane przez funkcję char różni się między systemami operacyjnymi.
Co masz na myśli mówiąc, że "fstream gwarantuje akceptację obu wchar_t ..."? Nie mam dostępu do oficjalnego standardu 98, ale nie mogę znaleźć wzmianki o wchar_t * ctor dla basic_fstream w n2857 (np. IIUC, aktualny projekt roboczy C++ 0x) –
Hmm, wygląda na to, że masz rację . Poprawiłem: – jalf
@ Éric: agreed, konstruktory dla basic_fstream są zdefiniowane w 27.8.1.12 ze standardu '03 i są dwa: no-args i char *.fstream jest basic_fstream
Obecne wersje Visual C++ std :: basic_fstream mają metodę open()
, która przyjmuje wchar_t * zgodnie z http://msdn.microsoft.com/en-us/library/4dx08bh4.aspx.
Czy to będzie ostatecznie/teoretycznie przenośne? –
Nie wszystkie systemy operacyjne i systemy plików obsługują nazwy plików w formacie Unicode, aby nie były przenośne. Z tego, co mogę zebrać, wchar_t * open() i konstruktor na fstream są rozszerzeniami Microsoftu, ponieważ NTFS obsługuje nazwy plików w Unicode. –
lub raczej, ponieważ NTFS używa UTF16 do kodowania nazw plików w Unicode. Linux obsługuje również nazwy plików w Unicode, ale używa UTF8, więc normalna wersja char * działa tam – jalf
Użyj std::wofstream
, std::wifstream
i std::wfstream
. Akceptują nazwę pliku Unicode. Nazwa pliku musi być wstring
, tablica wchar_t
s lub musi mieć makro _T()
lub przedrostek L
przed tekstem.
Czy możesz podać dowody, że 'std :: wfstream' to' Unicode'? Aż do mojej skromnej wiedzy używają 'wchar_t', która jest szeroką postacią, zwykle' 16-bitową'. Ale treść może być lub nie być "Unicode". –
Chodziło mi o to, że akceptują ciągi Unicode, które odpowiadają na pytanie, czyż nie? – Brackets
Właściwie to odpowiada na połowę pytania: załóżmy, że masz ścieżkę pliku UTF16 w swoim strumieniu wfstream (lub UTF8 w twoim strumieniu). Windows nie akceptuje unicode i zwróci "zły URL", jeśli masz jakieś specjalne znaki (np. Chiński). –
Wystarczy popatrzeć na Boost.Nowide:
#include <boost/nowide/fstream.hpp>
#include <boost/nowide/cout.hpp>
using boost::nowide::ifstream;
using boost::nowide::cout;
// #include <fstream>
// #include <iostream>
// using std::ifstream;
// using std::cout;
#include <string>
int main() {
ifstream f("UTF-8 (e.g. ß).txt");
std::string line;
std::getline(f, line);
cout << "UTF-8 content: " << line;
}
- 1. otworzyć plik z nazwą pliku Unicode?
- 2. Jak utworzyć std :: ofstream do pliku tymczasowego?
- 3. Odzyskiwanie deskryptor pliku z std :: fstream
- 4. python-request post z nazwą pliku Unicode
- 5. std :: fstream nie tworzy plik
- 6. Błąd std :: ofstream podczas zapisywania danych
- 7. Projektowanie klasy std :: ifstream
- 8. C++ fstream - tworzenie własnych flag formatowania
- 9. ofstream nie wylewać
- 10. Jak zwrócić fstream (C++ 0x)
- 11. Konwersja ifstream do istream
- 12. fstream nie utworzy pliku
- 13. Pomyślnie otworzyć, ale nie dobrze?
- 14. pliki std :: fstream więcej niż 2 gb
- 15. Dlaczego działa (std :: ifstream >> s)?
- 16. Jak wyświetlić wynik grep z pełną ścieżką lub nazwą pliku
- 17. Jak korzystać z domyślnych ograniczników podczas czytania pliku tekstowego ze std :: fstream?
- 18. Jak dołączyć do pliku z flagą fstream fstream :: app wydaje się nie działać
- 19. Dziwne zachowanie std :: string z unicode
- 20. zawartość do ofstream
- 21. Poszukiwania w dużych plikach z ifstream
- 22. Zapisywanie pliku z nazwą urządzenia
- 23. C++ fstream zastąpić zamiast dodać
- 24. błąd ofstream w C++
- 25. Czytanie pliku tekstowego - fopen vs. ifstream
- 26. C++ fstream << and >> Operatorzy z danych binarnych
- 27. Używanie std: fstream jak odmawiać dostępu (czytać i pisać) do pliku
- 28. Java nie może otworzyć pliku z surogatycznymi wartościami Unicode w nazwie pliku?
- 29. Co jest nie tak z ifstream seekg
- 30. Brak funkcji dopasowywania - ifstream open()
I to jest [Duplikat] (http://stackoverflow.com/questions/480849/windows-codepage-interactions-with-standard-cc-filenames) pytanie. Sprawdź, czy którakolwiek z udzielonych odpowiedzi może pomóc. –
Dlaczego nie używasz typów danych, takich jak 'std :: wofstream'? Zwróć uwagę na ** w **! – sergiol