Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Zapis słowa z polskim znakiem do pliku .txt

Ostatnio zmodyfikowano 2021-02-17 18:05
Autor Wiadomość
Temat założony przez niniejszego użytkownika
Zapis słowa z polskim znakiem do pliku .txt
» 2021-02-17 10:17:17
Witam.
Wyświetlanie polskich znaków w konsoli to temat rzeka. Przeszukałem googla i doszedłem jak wyświetlić je w konsoli (przynajmniej w małym programiku jak w załączeniu). Chciałem teraz słowo wpisane przez Usera zapisać w pliku txt. . I tu problem - za przykład służy mi wyraz 'złoto'. Jeżeli jest wpisany jako const string i przekazywany do pliku jest OK, jeżeli wpisuje go User poprzez cin to nie zapisuje 'złoto' tylko 'zoto' pomijając polski znak "ł". Uczę sie c++ dopiero kilka tygodni, proszę o wyrozumiałość.

C/C++
#include <iostream>
#include <fstream>
#include <string>
using namespace std;


int main() {
   
setlocale( LC_ALL, "polish" );
   
string wyraz;
   
fstream plik;
   
string const nazwa = "Tekst.txt";
   
string const slowo = "złoto";
   
   
cout << "Podaj słowo z polskim znakiem: ";
   
   
cin >> wyraz;
   
   
cout << " Twoje słowo: ";
   
setlocale( LC_ALL, "C" );
   
cout << wyraz;
   
plik.open( nazwa, ios::out | ios::app );
   
plik << wyraz << '\n';
   
plik << slowo << '\n';
   
   
plik.close();
   
   
system( "pause>nul" );
   
return 0;
}
P-178108
» 2021-02-17 10:47:57
Niestety C/C++ jest mocno ułomny w tym obszarze... Spróbuj używać std::wstring + wcout.
C/C++
std::wstring slowo = L"złoto";
std::wcout << slowo;
//...
plik << slowo;
P-178109
Temat założony przez niniejszego użytkownika
» 2021-02-17 11:11:37
string const słowo to literał i ją do pliku zapisuje poprawnie. problem jest ze zmienną wyraz , którą podaje User i wpisując tu w konsoli 'złoto' w pliku pojawia się 'zoto' .

I jeszcze jedno :
jak zapisać zmienną wstring do pliku ?

Próba :
C/C++
plik << wyraz;

kończy sie niepowodzeniem
P-178110
» 2021-02-17 18:05:38
jak zapisać zmienną wstring do pliku ?
A jaki ma być efekt? Do pliku zapisuje się bajty, nie znaki. Nie ma jednego sposobu konwersję między nimi, nawet w swoim programie nie masz spójnego kodowania znaków. Trzeba wiedzieć co się robi, kod dla przykładu poniżej. Kod ma kodowanie UTF-8 i kompilator o tym wie, bo takie jest dla niego domyślne.
C/C++
#include <iostream>
#include <string>
#include <Windows.h>
#include <cstdio>

void hexdump( const std::string & s )
{
   
for( int i = 0; i < s.size(); ++i )
       
 printf( "%02X ",( unsigned char ) s[ i ] );
   
   
printf( "\n" );
}

int main()
{
   
std::cout << "Output CP: " << GetConsoleOutputCP() << '\n';
   
   
std::string code = "zażółć gęślą jaźń", user;
   
   
hexdump( code );
   
std::cout << "Z kodu: " << code << '\n';
   
   
std::cout << "\nPodaj tekst> ";
   
std::getline( std::cin, user );
   
hexdump( user );
   
std::cout << user << '\n';
}
Kod wypisuje polskie znaki wpisane w kodzie i takie wpisane przez usera. Oprócz tego dla obu wypisuje jakie są wartości bajtów.
Output CP: 852
7A 61 C5 BC C3 B3 C5 82 C4 87 20 67 C4 99 C5 9B 6C C4 85 20 6A 61 C5 BA C5 84
Z kodu: za┼╝├│┼é─ç g─Ö┼Ťl─ů ja┼║┼ä

Podaj tekst> zażółć gęślą jaźń
7A 61 BE A2 88 86 20 67 A9 98 6C A5 20 6A 61 AB E4
zażółć gęślą jaźń
Jak widać zupełnie co innego. Pierwszy napis jest tak zakodowany, jak zrobił to kompilator. Kod źródłowy jest w UTF-8 i na wyjściu domyślnie też jest UTF-8. Tekst podany przez użytkownika jest zakodowany z użyciem bieżącego kodowania konsoli, w tym wypadku program wypisał że jest to strona kodowa 852. Można poinstruować kompilator by zakodował napisy w programie z użyciem CP852 z użyciem opcji -fexec-charset=852:
C:\Users\admin\Desktop\_test_>g++ a.cpp -fexec-charset=852

C:\Users\admin\Desktop\_test_>a
Output CP: 852
7A 61 BE A2 88 86 20 67 A9 98 6C A5 20 6A 61 AB E4
Z kodu: zażółć gęślą jaźń

Podaj tekst> zażółć gęślą jaźń
7A 61 BE A2 88 86 20 67 A9 98 6C A5 20 6A 61 AB E4
zażółć gęślą jaźń
Dla początkującego to pewnie najprostsze rozwiązanie, bo trzymasz się zwykłego std::string i operujesz na tekście tak jak wcześniej, włącznie z operacjami na pliku. Minusem jest że możesz używać wyłącznie znaków z tej strony kodowej. Najlepiej* jest używać konsoli skonfigurowanej do pracy z UTF-8, tylko że bywa różnie ze wsparciem Unicode i trzeba wiedzieć co się robi. Choćby przez to że jeden znak może być zakodowany jako sekwencja wielu bajtów.

* Jednak nie najlepiej, bo jak się okazuje, wczytywanie tekstu od użytkownika nie działa dobrze w konsoli na UTF-8.
https://github.com/microsoft/terminal/issues/4551#issuecomment-585487802
Jedynym dobrym wyjściem obecnie dla Unicode w konsoli Windows to używanie UTF-16.
P-178111
« 1 »
  Strona 1 z 1