2010-02-25 13 views
12

natknąłem subtelny błąd kilka dni temu, gdzie kod wyglądał mniej więcej tak:Jaki pożytek z "końców" w tych dniach?

ostringstream ss; 
int anInt(7); 

ss << anInt << "HABITS"; 
ss << ends; 
string theWholeLot = ss.str(); 

Problemem było to, że ends wystawał a „\ 0” do ostringstream tak theWholeLot rzeczywiście wyglądało "7HABITS\0" (tj null na końcu)

teraz ten nie wykazał, bo theWholeLot następnie wykorzystywane do podjęcia część const char * korzystając string::c_str() to oznaczało, że zerowy został zamaskowany jak stało się po prostu separator. Jednak w przypadku zmiany wartości na ciągi znaków wartość zerowa nagle oznaczała coś i porównania, takie jak:

if (theWholeLot == "7HABITS") 

zakończy się niepowodzeniem. Pomogło mi to: Prawdopodobnie powodem dla ends jest powrót do dni ostrstream, gdy strumień nie był normalnie zakończony zerowością i musiał być taki, aby str() (który następnie wyrzucił nie string, ale char *) działałby poprawnie .

Teraz jednak, że to nie jest możliwe, aby wypędzić char * z ostringstream, używając ends jest nie tylko zbędne, ale potencjalnie niebezpieczne i jestem rozważa usunięcie ich wszystkich z mojego kodu klienta.

Czy ktokolwiek widzi oczywisty powód, aby korzystać z ends tylko w środowisku zgodnym z std::string?

+0

Moja jedyna wątpliwość jest tym, czym jest środowisko std :: string? Jakikolwiek nietrywialny program będzie char * wywoływał argumenty wywołania systemowego itp. To powiedziawszy, jest jeszcze pół tuzina innych sposobów radzenia sobie z tym i kończy się pomijalną użytecznością. – Duck

+0

Oto kilka przykładów użycia 'std :: ends': http://stackoverflow.com/questions/624260/how-to-reuse-an-ostringstream/624291#624291 –

+1

To nie tylko dla ciągów. Przydaje się do ogólnych strumieni. Niektóre narzędzia unixu wymagają terminali jako bajtów zerowych. 'cout << ends;' dostarczy je. –

Odpowiedz

7

W zasadzie odpowiedziałeś na własne pytanie, które są potrzebne. Z pewnością nie mogę wymyślić żadnego powodu, aby używać std::ends, gdy std::string i std::stringstream radzą sobie z tym wszystkim.

Aby odpowiedzieć na Twoje pytanie jednoznacznie, nie, nie ma powodu, aby korzystać z std::ends tylko w środowisku zgodnym z .

+0

Powiedziałbym, że nie ma powodu, aby używać okresu 'std :: ends'. Powiedziałbym, że jestem bardzo doświadczonym programistą C++ i jeszcze nie wiedziałem, że istnieje. –

+3

@Andreas, ponieważ właśnie o tym usłyszeliśmy po raz pierwszy, brzmi to wyjątkowo na pewno :) –

+1

Jak zaznaczył Johannes, istnieją wystarczające powody. Wiele programów UNIX wymaga wspólnego terminatora "\ 0", np. do tekstu potoku ze znakami ASCII <= 32 do innych programów. Nie wyobrażam sobie życia bez 'find -print0',' xargs --null' lub 'read -d '\ 0'', żeby wymienić tylko kilka. Również wiele interfejsów API wymaga "\ 0". Jest to typowy terminator napisów, a łańcuchy są najważniejszymi elementami danych, ponieważ wszystko można przekształcić w ciąg znaków. Dlatego chcesz, aby łańcuchy były tak elastyczne, jak to tylko możliwe. –

6

Istnieje kilka interfejsów API, które oczekują "tablicy łańcuchów" z wieloma zakończonymi zero łańcuchami, podwójnym zerem dla oznaczenia końca. Raymond Chang niedawno uzyskał numer blogged about it, przede wszystkim po to, aby pokazać, jak często się to odbywa.

+0

Schludny. Dzięki za link. –

Powiązane problemy