2013-05-25 10 views
5

śledzę ten kod do wykończeniajak przyciąć tablicę wektorową lub ciąg znaków?

std::string tcp_read(int listen_at_port=8001){ 

    using namespace std; 
    using namespace boost::algorithm; 
    std::vector<char> received_data(512); 
    tcp_read(received_data, listen_at_port); 
    string str1(received_data.begin(),received_data.end()); 
    trim_right(str1); 
    return str1; 
} 

Wszedłem throught kodu, mój received_data jest ogólnie = "add 8002 (tutaj dalej bufor jest wypełniona spacjami till sieci [511th] pozycja)"

teraz, kiedy zrobiłem trim_right, spodziewałem się, że rozmiar str1 wyniesie 8, ale wciąż będzie 512, kiedy powróci, dlaczego?

Jak uzyskać właściwie przycinać i zmieniać rozmiar tak, że ciąg tylko pomieścić aż do ostatniego znaku spoza przestrzeni

+0

Czy na pewno bufor jest wypełniony spacjami, a nie innymi białymi znakami? – PureW

Odpowiedz

2

Jak wyjaśniono w drugim answer, twój vector jest wypełniona zerami, które nie są uważane spacje, więc nie trim_right usuń te z sznurka. Łatwym rozwiązaniem problemu jest nie konstruowanie ciągu za pomocą początkowych i końcowych iteratorów wektora, ale użycie konstruktora string(char const *). Eliminuje to również połączenie z boost::trim_right.

std::string tcp_read(int listen_at_port=8001) 
{ 
    using namespace std; 

    std::vector<char> received_data(512); 
    tcp_read(received_data, listen_at_port); 

    return string(received_data.data()); 
    // or return string(&received_data[0]); 
} 
+0

co jest alternatywą do .data() wektora na vs2008, który nie obsługuje c11? –

+1

@ user494461 Skomentowana linia 'return string (& received_data [0]);' działa dla kompilatorów C++ 03. – Praetorian

1

trim_right tylko usuwa wszystkie spacje końcowe. Kiedy deklarujesz received_data, jest on inicjalizowany wszystkimi zerami. Kiedy czytasz dane z gniazda, dane na końcu bufora [na pewno] nie składają się ze spacji.

Sugeruję, aby po wywołaniu tcp_read() zwrócić liczbę bajtów, które faktycznie zostały odczytane z gniazda i wykonać recieved_data.resize(byte_count); zamiast wywoływać trim_right. Także jeśli dane odbierane przez gniazdo mogą zawierać zera, prawdopodobnie powinieneś zwrócić vector zamiast string.

[Uznanie Praetorian dla wskazując, że usuwa wszystkie spacje]

+0

+1 "trim_right" nie tylko usuwa spacje, ale wszystkie końcowe * białe spacje *. Mógłby więc zmodyfikować inicjalizację wektora tak, aby zawierał coś, co usunąłoby "trim_right". Na przykład 'std :: vector received_data (512, '\ n');' – Praetorian

+0

@Praetorian Właśnie dodawał, że lol. –

+0

@Praetorian nie myślał o wszystkich białych znakach –

0

To głupie, ale w przypadku odstępy nie są naprawdę odstępy:

string str1(received_data.begin(), 
    find(received_data.begin(), received_data.end(), received_data[511])); 

A jeśli są to:

string str1(received_data.begin(), 
    find( 
     find(received_data.begin(), received_data.end(), ' ') + 1, 
     received_data.end())); 

ale to tylko niektóre hacki, przycinanie prawo powinno działać dobrze, prawdopodobnie jest coś nie tak z danymi receive_data.

I tak, przycięcie łańcucha nie spowoduje ponownego przydzielenia żadnej pamięci, więc może być ok, aby zapisać ją tak jak jest.

Powiązane problemy