2009-02-17 16 views
10

Czy ktoś może zaproponować sposób usuwania znaków tabulacji ("\ t" s) z ciągu znaków? CString lub std :: string.Przycinanie/usuwanie zakładki (" t") z ciągu znaków

tak, że "1E10            " na przykład staje się "1E10".

Dzięki w oczekiwaniu.

+0

Masz na myśli tylko od początku lub końca? Lub z dowolnego miejsca w ciągu? Czy "abc \ tdef" należy pozostawić bez zmian, czy też zredukować do "abcdef"? –

+0

Powinienem być bardziej jasny w tym, miałem na myśli z dowolnego miejsca w sznurku. – AndyUK

Odpowiedz

18

hackingwords' answer zabierze Cię w połowie drogi. Ale std::remove() z <algorithm> tak naprawdę nie czyni łańcucha krótszym - po prostu zwraca iterator mówiąc "nowa sekwencja tutaj się kończy." Trzeba zadzwonić my_string().erase() to zrobić:

#include <string> 
#include <algorithm> // For std::remove() 

my_str.erase(std::remove(my_str.begin(), my_str.end(), '\t'), my_str.end()); 
+1

std :: remove() link jest zepsuty. Poprawny link: http://pl.cppreference.com/w/cpp/algorithm/remove – SebiSebi

+1

@SebiSebi: Dzięki za to, naprawiony! –

2

Zeskanuj ciąg znaków i usuń wszystkie znalezione zdarzenia.

0

Pierwszy pomysł byłoby użyć remove

remove(myString.begin(), myString.end(), "\t"); 

Choć może trzeba użyć remove_if zamiast jeśli to porównanie nie działa.

+0

remove() jest połową tego - musisz również owijać to wywołanie remove() za pomocą wywołania myString.erase(), ponieważ remove() właściwie nie skraca łańcucha (nie ma (i nie może) "t) wiem jak). –

1

CString wymienić?

zastąpić („\ t”, „”)

+0

Nie działa. "" oznacza NULL znak (przynajmniej w VC++). Spowoduje problemy. – sharptooth

+0

Myślę, że ma na myśli "". Wydaje się, że pracujesz dla mnie. – AndyUK

+0

Dokładniej zamień ("\ t", "") – AndyUK

6

Algorytm remove przesuwa wszystkie znaki nie mogą być usunięte na początku, zastępując usunięte znaki, ale to nie zmienia długości kontenera (od działa na iteratory i nie zna podstawowego kontenera). Aby to osiągnąć, należy zadzwonić erase:

str.erase(remove(str.begin(), str.end(), '\t'), str.end()); 
+0

Myślę, że masz parametry do wymazania() pomieszane. Chcesz usunąć * z * iteratora zwróconego przez remove() na * koniec * str. –

+0

oops :) tak, oczywiście. –

+0

+2 dla Ciebie Konrad! :) –

19

Jeśli chcesz usunąć wszystkie wystąpienia w ciągu, a następnie można użyć erase/remove idiom:

#include <algorithm> 

s.erase(std::remove(s.begin(), s.end(), '\t'), s.end()); 

Jeśli chcesz usunąć tylko kartę u początek i koniec łańcucha, można użyć boost string algorithms:

#include <boost/algorithm/string.hpp> 

boost::trim(s); // removes all leading and trailing white spaces 
boost::trim_if(s, boost::is_any_of("\t")); // removes only tabs 

przypadku korzystania Boost jest zbyt dużo napowietrznych, można toczyć własną funkcję wykończenia USI ng find_first_not_of i find_last_not_of metody łańcuchowe.

std::string::size_type begin = s.find_first_not_of("\t"); 
std::string::size_type end = s.find_last_not_of("\t"); 

std::string trimmed = s.substr(begin, end-begin + 1); 
+0

std :: remove() nie sprawia, że ​​łańcuch jest krótszy - po prostu zwraca iterator mówiąc "nowy ciąg kończy się tutaj". Musisz wywołać s.erase() później tym iteratorem, aby faktycznie skrócić ciąg znaków. –

+0

Masz rację, zapomniałem użyć wymazania/usunięcia idiomu. Poprawione. –

+0

+2 także dla ciebie, Luc :) –

2

HackingWords jest prawie tam Use wymazać w połączeniu ze Usuń.

std::string my_string = "this\tis\ta\ttabbed\tstring"; 
my_string.erase(std::remove(my_string.begin(), my_string.end(), my_string.end(), '\t')); 
+0

Myślę, że popełniłeś ten sam błąd co Konrad Rudolph - musisz usunąć * z * iteratora zwróconego przez std :: remove() na * koniec * ciągu znaków. –

+0

+2 do korekty graham. –

+0

Tak, wyścigi za pierwsze oznacza, że ​​musisz szybko kodować. –

3

Ponieważ inni już odpowiedział jak to zrobić z std :: string, oto co można wykorzystać do CString:

myString.TrimRight('\t'); // trims tabs from end of string 
myString.Trim('\t'); // trims tabs from beginning and end of string 

jeśli chcesz pozbyć się wszystkich kart, nawet tych wewnątrz ciąg użyć

myString.Replace(_T("\t"), _T("")); 
+0

Który nagłówek/biblioteka należy dołączyć do używania metod TrimRight i Trim w ciągach znaków? Zrobiłem #include , ale to nie pojawia się w intellisense. –

+0

@FarazAhmad CString Stefan używa własnej klasy. Pochodzi z nagłówka afx.h. Możesz go użyć, łącząc się ze wspólną biblioteką runtime MS w oknach. – nurettin

0

zastanawiam się, dlaczego nikt nie przycina ciąg ten sposób:

void trim (string& s) { 
    string t = ""; 
    int i = 0; 
    while(s[i] == ' ') i++; 
    while(s[i] == '\t') i++; 
    for(i; i < s.length(); i++) 
     t += s[i]; 

    s = t; 
} 
+1

Ponieważ nie będzie poprawnie obsługiwać wszystkich przypadków. Pominie tylko wiodące spacje, a następnie prowadzi karty i tylko w tej kolejności. – rubikonx9