Trim / remove a tab ( "\t" ) from a string

46,283

Solution 1

hackingwords' answer gets you halfway there. But std::remove() from <algorithm> doesn't actually make the string any shorter -- it just returns an iterator saying "the new sequence would end here." You need to call my_string().erase() to do that:

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

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

Solution 2

If you want to remove all occurences in the string, then you can use the erase/remove idiom:

#include <algorithm>

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

If you want to remove only the tab at the beginning and end of the string, you could use the 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

If using Boost is too much overhead, you can roll your own trim function using find_first_not_of and find_last_not_of string methods.

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);

Solution 3

The remove algorithm shifts all characters not to be deleted to the beginning, overwriting deleted characters but it doesn't modify the container's length (since it works on iterators and doesn't know the underlying container). To achieve this, call erase:

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

Solution 4

Since others already answered how to do this with std::string, here's what you can use for CString:

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

if you want to get rid of all tabs, even those inside the string, use

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

Solution 5

Scan the string and remove all the found occurences.

Share:
46,283
afterxleep
Author by

afterxleep

@andyuk2010linkedin

Updated on June 03, 2020

Comments

  • afterxleep
    afterxleep almost 4 years

    Can anyone suggest a way of stripping tab characters ( "\t"s ) from a string? CString or std::string.

    So that "1E10      " for example becomes "1E10".

  • sharptooth
    sharptooth over 15 years
    Won't work. '' stands for NULL character (at least in VC++). Will cause problems.
  • Ankit Roy
    Ankit Roy over 15 years
    remove() is half of it -- you also need to wrap that call to remove() with a call to myString.erase(), since remove() doesn't actually shorten the string (it doesn't (and can't) know how).
  • afterxleep
    afterxleep over 15 years
    More specifically replace( "\t", "" )
  • Ankit Roy
    Ankit Roy over 15 years
    I think you have the parameters to erase() mixed up. You want to erase from the iterator returned by remove() to the end of str.
  • Ankit Roy
    Ankit Roy over 15 years
    std::remove() doesn't make the string any shorter -- it just returns an iterator saying "the new string ends here." You need to call s.erase() afterwards with that iterator to actually shorten the string.
  • Ankit Roy
    Ankit Roy over 15 years
    I think you made the same mistake as Konrad Rudolph -- you need to delete from the iterator returned by std::remove() to the end of the string.
  • Geekoder
    Geekoder over 15 years
    You're right, I forgot using the erase/remove idiom. Corrected.
  • CoreModule
    CoreModule over 15 years
    I didn't test is but I inteded to use '\t' because I think "\t" will look for the text \t instead of the tab character (don't know for sure).
  • sharptooth
    sharptooth over 15 years
    Nope, replace("\t", "") will work just as needed, but it's not very time-efficient. Escape sequences work the same in character literals and string literals.
  • Ankit Roy
    Ankit Roy over 15 years
    P.S: Actually I don't think remove() shifts the found characters to the end -- I think the end will just contain whatever it contained initially.
  • Konrad Rudolph
    Konrad Rudolph over 15 years
    @j_r_h: Not, it really does. Basically, remove(a, b, v) is exactly equal to stable_partition(a, b, p) with the predicate p = _1 != value.
  • Ankit Roy
    Ankit Roy over 15 years
    Are you sure? According to sgi.com/tech/stl/remove.html: "The iterators in the range [new_last, last) are all still dereferenceable, but the elements that they point to are unspecified." Certainly the MinGW and MSVC++8 implementations of remove() != stable_partition().
  • Ankit Roy
    Ankit Roy over 15 years
    Also remove() is an in-place O(n) algorithm, while stable_partition() seems to be "harder" -- at least the SGI implementation of stable_partition() tries to allocate a temporary buffer and use that in O(n) time, otherwise falling back to an O(nlog n) algorithm.
  • Konrad Rudolph
    Konrad Rudolph over 15 years
    j_random_hacker: Sorry, I can't argue from the Standard, I looked at the GCC source. Furthermore, I readily agree that a general-purpose stable sort may be more difficult to implement, however, at least the GCC remove implementation does exactly what I said above.
  • Konrad Rudolph
    Konrad Rudolph over 15 years
    (cont) And due to the Standard constraints on runtime (exactly N applications I of the predicate) I fail to see any other workable implementation. But that's strictly speculation, I admit.
  • Konrad Rudolph
    Konrad Rudolph over 15 years
    @j_r_h: My 2nd comment was in support of the original statement. As for the source: GCC 4.2 remove invokes find and remove_copy. find gets the first occurrence and r_c shifts all subsequent finds to the end.
  • Konrad Rudolph
    Konrad Rudolph over 15 years
    (cont'd) That said, I see now that you are right that they are not identical; remove just moves the other elements to the front, it does not move the deleted elements to the back. So yes, you were right all along. But I had to test it first: pastie.org/396239 So, thanks for persisting!
  • Ankit Roy
    Ankit Roy over 15 years
    @Konrad: No problem, glad we cleared that up and I wasn't losing my mind after all! :)
  • Admin
    Admin over 10 years
    Which header/library to include for using TrimRight and Trim methods on string? I have done #include <cstring>, but this is not appearing in intellisense.
  • nurettin
    nurettin about 10 years
    @FarazAhmad CString Stefan uses is a class of its own. It's from the afx.h header. You can use it by linking to MS common runtime library in windows.
  • rubikonx9
    rubikonx9 over 8 years
    Because it won't handle correctly all cases. It'll only skip leading spaces, then leading tabs, and only in this order.
  • SebiSebi
    SebiSebi over 6 years
    std::remove() link is broken. Correct link: en.cppreference.com/w/cpp/algorithm/remove
  • Ankit Roy
    Ankit Roy over 6 years
    @SebiSebi: Thanks for that, fixed!