HOWTO · C++

Como dividir uma string separada por vírgulas em C++

Divida uma string simples separada por vírgulas em C++ com std::stringstream e std::getline, ou com std::string::find e std::string::substr.

Nesta página

Para uma string simples delimitada por vírgulas, std::stringstream com std::getline é uma forma simples de coletar cada valor em um std::vector<std::string>. Se você precisar controlar como cada parte é extraída, std::string::find e std::string::substr oferecem uma alternativa manual. Essas abordagens dividem por um delimitador; elas não analisam a sintaxe CSV completa, como vírgulas dentro de campos entre aspas.

Dividir uma string separada por vírgulas com std::stringstream e std::getline

Inclua <sstream> para construir um fluxo a partir da string de entrada e <vector> para armazenar as partes. Passe a vírgula como terceiro argumento para std::getline; cada chamada lê até esse delimitador e coloca o texto extraído em item. O loop adiciona cada item ao vetor e, em seguida, imprime os valores coletados.

Use std::vector<std::string> quando o código posterior precisar indexar os tokens ou iterar sobre eles novamente; ele armazena cada valor extraído como uma string separada na ordem de entrada.

#include <iostream>
#include <sstream>
#include <string>
#include <vector>

int main() {
    const std::string input = "apple,banana,cherry,dates";
    std::stringstream stream(input);
    std::vector<std::string> items;
    std::string item;

    while (std::getline(stream, item, ',')) {
        items.push_back(item);
    }

    for (const std::string& value : items) {
        std::cout << value << '\n';
    }
}
apple
banana
cherry
dates

Este exemplo usa uma vírgula como delimitador e armazena as quatro strings extraídas em ordem. std::getline com um delimitador pode produzir um item vazio entre vírgulas consecutivas, enquanto um delimitador no final não produz um item final neste loop. Se a sua entrada precisar de um tratamento diferente para esses casos, decida o que cada posição do delimitador deve significar e leve isso em conta na lógica de análise. As strings extraídas mantêm os espaços que fazem parte da entrada, portanto, apare cada item separadamente se os espaços ao redor deverem ser descartados. Altere o argumento do delimitador quando a origem usar outro caractere único, como um ponto e vírgula.

Dividir uma string separada por vírgulas com std::string::find e std::string::substr

O membro std::string::find localiza a próxima vírgula e std::string::substr copia os caracteres anteriores a ela. Mantenha um índice inicial na entrada original em vez de apagar caracteres ao longo do processo. Quando find retorna std::string::npos, não há mais vírgulas, portanto, considere o sufixo restante como o item final e pare.

#include <iostream>
#include <string>
#include <vector>

int main() {
    const std::string input = "apple,banana,cherry,dates";
    std::vector<std::string> items;
    std::string::size_type start = 0;

    while (true) {
        const std::string::size_type comma = input.find(',', start);
        if (comma == std::string::npos) {
            items.push_back(input.substr(start));
            break;
        }

        items.push_back(input.substr(start, comma - start));
        start = comma + 1;
    }

    for (const std::string& value : items) {
        std::cout << value << '\n';
    }
}
apple
banana
cherry
dates

A chamada final a substr(start) é importante: ela adiciona o texto após a última vírgula, incluindo o último valor quando não há mais delimitadores. Esta versão também trata uma entrada com uma vírgula no final como tendo um item final vazio, ao contrário do loop de fluxo acima. Para uma entrada totalmente vazia, ela também armazena uma string vazia, portanto, ajuste a condição do loop se o seu aplicativo deve tratar essa entrada como sem valores. A pesquisa começa no caractere após cada vírgula, o que evita alterar a entrada durante a análise e facilita manter a string original para uso posterior. Nenhuma das abordagens trata vírgulas entre aspas ou aspas escapadas; use um analisador CSV quando essas regras fizerem parte do formato de entrada.