Linux reverse string polskie znaki polska czcionka
Ostatnio zmodyfikowano 2022-06-30 16:29
OfEl Temat założony przez niniejszego użytkownika |
Linux reverse string polskie znaki polska czcionka » 2022-06-30 09:55:10 jeden z waszych użytkowników zauważył, że przy wypisywaniu string wspak nie pokazują się polskie znaki reverse string polskie znaki polska czcionkaużytkownik @pekfos odpowiedział, że do opcji kompilatora wystarczy dopisać -fexec-charset=852 i wszystko fajnie tylko nie działa to pod kontrolą systemu linux Moje pytanie brzmi jak to można rozwiązać pod unix/linux Podejmowałem różna próby zamieniając napis na bity czy na kod ASCI z marnym efektem std::locale{"pl_PL.utf-8"} #include <iostream> #include <cstring> #include <bitset> #include <cstdlib> #include <vector> #include <algorithm> #include <climits>
using namespace std;
int main() { cout << std::locale( "" ).name(); cout << "\n"; std::string rex( "król" ); std::string rev; std::copy( rex.crbegin(), rex.crend(), std::back_inserter( rev ) ); for( const auto & ch: rex ) std::cout << ch; std::cout << '\n'; for( const auto & ch: rev ) std::cout << ch; std::cout << "\n\n"; return 0; }
#include <iostream> #include <cstring> #include <bitset> #include <cstdlib> #include <vector> #include <algorithm> #include <climits>
using namespace std;
template < typename T > std::ostream & operator <<( std::ostream & os, const std::vector < T > & v ) { for( T const & i: v ) { os << i << " "; } return os; } template < size_t N > std::string bitset_to_string( std::bitset < N > bits ) { static_assert( N % CHAR_BIT == 0 ); std::string result; for( size_t p = 0; p < N / CHAR_BIT; ++p ) { char next = 0; for( size_t r = 0; r < CHAR_BIT; ++r ) { size_t index = N -( CHAR_BIT * p ) - r - 1; size_t pos = CHAR_BIT - r - 1; if( bits[ index ] ) next |=( 1 << pos ); } result.push_back( next ); } return result; } int main() { std::string rex = "król"; vector < bitset < 8 >> v; cout << rex << "\n"; for( std::size_t i = 0; i < rex.length(); ++i ) { v.push_back( std::bitset < 8 >( rex[ i ] ) ); std::cout << std::bitset < 8 >( rex[ i ] ) << ' '; } cout << "\n\n"; std::reverse( v.begin(), v.end() ); cout << v << '\n'; for( const auto & el: v ) { cout << bitset_to_string( el ) << " "; } cout << '\n'; return 0; }
napisałem też w RUST jedno rozwiązanie działa pod unix/linux/windows link_do_online_kompilatorowcompile_rust_onlineuse std::io;
fn main() { let rex = "król"; println !( "{}", rex ); println !( "{}", rex.chars().rev().collect::< String >() ); io::stdin().read_line( & mut String::new() ).unwrap(); }
Może ktoś wie jak to zrobili czarodzieje z RUST. Bardzo chętnie uzupełniłbym swoją wiedzę Proszę się też nie śpieszyć z odpowiedzią Z góry serdecznie dziękuję za odpowiedź. wystarczy, przy założeniu że jeden znak to jeden bajt. czy może mi to ktoś wyłożyć łopatologicznie lub wskazać materiały lub hasła pod jakimi mam szukać |
|
DejaVu |
» 2022-06-30 10:34:39 Przekonwertuj std::string na std::wstring i rób reverse na std::wstring. |
|
OfEl Temat założony przez niniejszego użytkownika |
» 2022-06-30 16:08:00 znalazłem nawet coś u was Unicode w WinAPI ale to wszystko pod windows i na stackoverflow i tam jest odnośnik do geeksforgeeks i tam jest coś na The MIT License (MIT), ale z tym będę się musiał dopiero zmierzyć |
|
DejaVu |
» 2022-06-30 16:13:28 Generalnie Twój problem to taki, że w UTF-8 polski znak jest reprezentowany de-facto przez dwa znaki. Jak odwracasz 'std::string' to w praktyce odwracasz kolejność bajtów, ponieważ metoda nie posiada logiki do interpretacji, że litera zajmuje więcej niż jeden bajt. Problem ten rozwiąże Ci przykładowo std::wstring, ponieważ wchar_t zajmuje od 2 do 4 bajtów pamięci (w zależności od kompilatora i bibliotek) i tym samym rozwiązuje problem obliczenia chociażby poprawnej długości tekstu lub też wyciągania pojedynczych liter, odwracania tekstu itp. std::string tekst1 = "król"; std::wstring tekst2 = L"król"; |
|
OfEl Temat założony przez niniejszego użytkownika |
» 2022-06-30 16:27:17 Administrator @DejaVu problem rozwiązany dziękuję za wyjaśnienie i naprowadzenie Ekspert C++ @pekfos dziękuję za wyjaśnienie i podany przykład I found the solution on the website riptutorial Conversion to std::wstring #include <iostream> #include <cstring> #include <codecvt> #include <locale> #include <algorithm>
using namespace std;
using convert_t = std::codecvt_utf8 < wchar_t >; std::wstring_convert < convert_t, wchar_t > strconverter;
std::string to_string( std::wstring wstr ) { return strconverter.to_bytes( wstr ); }
std::wstring to_wstring( std::string str ) { return strconverter.from_bytes( str ); }
int main() { std::string rex = "król"; cout << rex << '\n'; std::wstring input_wstr = to_wstring( rex ); wcout << input_wstr << '\n'; std::reverse( input_wstr.begin(), input_wstr.end() ); cout << to_string( input_wstr ) << "\n"; return 0; }
|
|
pekfos |
» 2022-06-30 16:29:02 wystarczy, przy założeniu że jeden znak to jeden bajt. czy może mi to ktoś wyłożyć łopatologicznie lub wskazać materiały lub hasła pod jakimi mam szukać To się odnosiło do kodu źródłowego. "wystarczy dopisać -fexec-charset=852" żeby spełnić te założenie na GCC i konsoli Windowsowej w typowej polskiej konfiguracji. Na linuksie jest łatwiej, możesz pisać w UTF-8 na konsolę i jak nie masz czegoś skonfigurowanego po swojemu, to powinno zadziałać. Ale UTF-8 jest kodowaniem zmiennej długości i nie możesz zrobić std::reverse() na std::string. std::wstring typowo używa UTF-16, co też jest kodowaniem zmiennej długości, ale dla większości znaków jedna wartość odpowiada jednemu znakowi. #include <iostream> #include <locale> #include <codecvt>
int main() { std::string str = "zażółć gęślą jaźń"; std::cout << str << '\n'; std::cout << "źle: " << std::string( str.rbegin(), str.rend() ) << '\n'; typedef std::wstring_convert < std::codecvt_utf8 < wchar_t >> Converter; std::wstring wstr = Converter().from_bytes( str ); std::cout << Converter().to_bytes( std::wstring( wstr.rbegin(), wstr.rend() ) ) << '\n'; } |
|
« 1 » |