574 votes

Analyser (diviser) une chaîne en C++ en utilisant le délimiteur de chaîne (C++ standard)

J'analyse une chaîne de caractères en C++ en utilisant la méthode suivante :

using namespace std;

string parsed,input="text to be parsed";
stringstream input_stringstream(input);

if (getline(input_stringstream,parsed,' '))
{
     // do some processing.
}

L'analyse syntaxique avec un délimiteur à caractère unique est correcte. Mais que faire si je veux utiliser une chaîne de caractères comme délimiteur.

Exemple : Je veux me séparer :

scott>=tiger

avec >= comme délimiteur pour que je puisse avoir scott et tiger.

2 votes

stackoverflow.blog/2019/10/11/ Descendez jusqu'au numéro 5.

3voto

SridharKritha Points 346

Encore une autre réponse : Ici, j'utilise find_first_not_of fonction de chaîne de caractères qui renvoie à la position du premier caractère qui ne pas correspond à l'un des caractères spécifiés dans le delim.

size_t find_first_not_of(const string& delim, size_t pos = 0) const noexcept;

Exemple :

int main()
{
    size_t start = 0, end = 0;
    std::string str = "scott>=tiger>=cat";
    std::string delim = ">=";
    while ((start = str.find_first_not_of(delim, end)) != std::string::npos)
    {
        end = str.find(delim, start); // finds the 'first' occurance from the 'start'
        std::cout << str.substr(start, end - start)<<std::endl; // extract substring
    }
    return 0;
}

Sortie :

    scott
    tiger
    cat

3voto

jacob galam Points 579

Je fais cette solution. C'est très simple, toutes les impressions/valeurs sont dans la boucle (pas besoin de vérifier après la boucle).

#include <iostream>
#include <string>

using std::cout;
using std::string;

int main() {
    string s = "it-+is-+working!";
    string d = "-+";

    int firstFindI = 0;
    int secendFindI = s.find(d, 0); // find if have any at all
    while (secendFindI != string::npos)
    {
        secendFindI = s.find(d, firstFindI);
        cout << s.substr(firstFindI, secendFindI - firstFindI) << "\n"; // print sliced part
        firstFindI = secendFindI + d.size(); // add to the search index
    }

}

Le seul inconvénient de cette solution est qu'elle consiste à effectuer une recherche deux fois au départ.

1voto

user2366975 Points 501

Si vous ne voulez pas modifier la chaîne de caractères (comme dans la réponse de Vincenzo Pii) et vous souhaitez également afficher le dernier jeton, vous pouvez utiliser cette approche :

inline std::vector<std::string> splitString( const std::string &s, const std::string &delimiter ){
    std::vector<std::string> ret;
    size_t start = 0;
    size_t end = 0;
    size_t len = 0;
    std::string token;
    do{ end = s.find(delimiter,start); 
        len = end - start;
        token = s.substr(start, len);
        ret.emplace_back( token );
        start += len + delimiter.length();
        std::cout << token << std::endl;
    }while ( end != std::string::npos );
    return ret;
}

1voto

XLVII Points 79
std::vector<std::string> parse(std::string str,std::string delim){
    std::vector<std::string> tokens;
    char *str_c = strdup(str.c_str()); 
    char* token = NULL;

    token = strtok(str_c, delim.c_str()); 
    while (token != NULL) { 
        tokens.push_back(std::string(token));  
        token = strtok(NULL, delim.c_str()); 
    }

    delete[] str_c;

    return tokens;
}

1voto

Radem Points 11

J'utilise l'arithmétique du pointeur. le while interne pour la délimitation de la chaîne si vous vous satify avec le char delimeter juste enlever le while interne simplement. j'espère que c'est correct. si vous remarquez une erreur ou améliorer s'il vous plaît laissez le commentaire.

std::vector<std::string> split(std::string s, std::string delim)
{
    char *p = &s[0];
    char *d = &delim[0];
    std::vector<std::string> res = {""};

    do
    {
        bool is_delim = true;
        char *pp = p;
        char *dd = d;
        while (*dd && is_delim == true)
            if (*pp++ != *dd++)
                is_delim = false;

        if (is_delim)
        {
            p = pp - 1;
            res.push_back("");
        }
        else
            *(res.rbegin()) += *p;
    } while (*p++);

    return res;
}

0 votes

Bienvenue sur Stack Overflow. Bien que ce code puisse résoudre la question, y compris une explication L'explication de la manière et de la raison pour laquelle cette solution résout le problème contribuerait vraiment à améliorer la qualité de votre message, et entraînerait probablement un plus grand nombre de votes positifs. N'oubliez pas que vous répondez à la question pour les lecteurs à venir, et pas seulement pour la personne qui pose la question maintenant. Veuillez modifier votre réponse pour ajouter des explications et indiquer les limites et les hypothèses applicables.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X