it-swarm.com.de

Leerzeichen von einem String ausschneiden

Ich weiß, es gibt mehrere Möglichkeiten, dies in Java und C zu tun, die Nice sind, aber in C++ kann ich scheinbar keine Möglichkeit finden, eine String-Trimming-Funktion leicht zu implementieren.

Das ist was ich momentan habe:

string trim(string& str)
{
    size_t first = str.find_first_not_of(' ');
    size_t last = str.find_last_not_of(' ');
    return str.substr(first, (last-first+1));
}

aber wann immer ich versuche und anrufe 

trim(myString);

Ich erhalte den Compiler-Fehler 

/tmp/ccZZKSEq.o: In function `song::Read(std::basic_ifstream<char, 
std::char_traits<char> >&, std::basic_ifstream<char, std::char_traits<char> >&, char const*, char const*)':
song.cpp:(.text+0x31c): undefined reference to `song::trim(std::string&)'
collect2: error: ld returned 1 exit status

Ich versuche, eine einfache und standardisierte Methode zu finden, um führende und nachgestellte Leerzeichen aus einer Zeichenfolge zu entfernen, ohne dass dabei 100 Zeilen Code erforderlich sind. Ich habe versucht, Regex zu verwenden.

Ich kann Boost auch nicht verwenden.

17
kf.

Ihr Code ist in Ordnung. Was Sie sehen, ist ein Linker-Problem.

Wenn Sie Ihren Code wie folgt in eine einzige Datei einfügen:

#include <iostream>
#include <string>

using namespace std;

string trim(const string& str)
{
    size_t first = str.find_first_not_of(' ');
    if (string::npos == first)
    {
        return str;
    }
    size_t last = str.find_last_not_of(' ');
    return str.substr(first, (last - first + 1));
}

int main() {
    string s = "abc ";
    cout << trim(s);

}

dann g++ test.cc und a.out ausführen, werden Sie sehen, dass es funktioniert.

Sie sollten prüfen, ob die Datei, die die Funktion trim enthält, in die Linkphase Ihres Übersetzungsprozesses aufgenommen wird. 

36
Anthony Kong

So kannst du es machen:

std::string & trim(std::string & str)
{
   return ltrim(rtrim(str));
}

Und die unterstützenden Funktionen sind implementiert als:

std::string & ltrim(std::string & str)
{
  auto it2 =  std::find_if( str.begin() , str.end() , [](char ch){ return !std::isspace<char>(ch , std::locale::classic() ) ; } );
  str.erase( str.begin() , it2);
  return str;   
}

std::string & rtrim(std::string & str)
{
  auto it1 =  std::find_if( str.rbegin() , str.rend() , [](char ch){ return !std::isspace<char>(ch , std::locale::classic() ) ; } );
  str.erase( it1.base() , str.end() );
  return str;   
}

Und wenn Sie all diese Voraussetzungen erfüllt haben, können Sie auch Folgendes schreiben:

std::string trim_copy(std::string const & str)
{
   auto s = str;
   return ltrim(rtrim(s));
}

Versuche dies

19
gjha

Ich denke, dass substr () eine Ausnahme auslöst, wenn str nur den Whitespace enthält. 

Ich würde es in den folgenden Code ändern:

string trim(string& str)
{
    size_t first = str.find_first_not_of(' ');
    if (first == std::string::npos)
        return "";
    size_t last = str.find_last_not_of(' ');
    return str.substr(first, (last-first+1));
}
5
Martin

Zusätzlich zur Antwort von @gjha:

inline std::string ltrim_copy(const std::string& str)
{
    auto it = std::find_if(str.cbegin(), str.cend(),
        [](char ch) { return !std::isspace<char>(ch, std::locale::classic()); });
    return std::string(it, str.cend());
}

inline std::string rtrim_copy(const std::string& str)
{
    auto it = std::find_if(str.crbegin(), str.crend(),
        [](char ch) { return !std::isspace<char>(ch, std::locale::classic()); });
    return it == str.crend() ? std::string() : std::string(str.cbegin(), ++it.base());
}

inline std::string trim_copy(const std::string& str)
{
    auto it1 = std::find_if(str.cbegin(), str.cend(),
        [](char ch) { return !std::isspace<char>(ch, std::locale::classic()); });
    if (it1 == str.cend()) {
        return std::string();
    }
    auto it2 = std::find_if(str.crbegin(), str.crend(),
        [](char ch) { return !std::isspace<char>(ch, std::locale::classic()); });
    return it2 == str.crend() ? std::string(it1, str.cend()) : std::string(it1, ++it2.base());
}
0
ivan.ukr
#include <vector>
#include <numeric>
#include <sstream>
#include <iterator>

void Trim(std::string& inputString)
{
    std::istringstream stringStream(inputString);
    std::vector<std::string> tokens((std::istream_iterator<std::string>(stringStream)), std::istream_iterator<std::string>());

    inputString = std::accumulate(std::next(tokens.begin()), tokens.end(),
                                 tokens[0], // start with first element
                                 [](std::string a, std::string b) { return a + " " + b; });
}
0
Will