Como fazer Split String com C++? [RESOLVIDO]

1. Como fazer Split String com C++? [RESOLVIDO]

Eduardo Campos
3dUcP

(usa Manjaro Linux)

Enviado em 05/05/2018 - 10:13h

No Java, as Strings, bytes, tem o metodo split(delimitador) que retorna um array do tipo criado com base num delimitador, queria sabe como faço o mesmo em C++
Preciso delimitar linhas "\n" e espaços para filtrar headers HTTP em busca de parametros.
Exemplo da Header
GET http://127.0.0.1 HTTP/1.1\nHost: 127.0.0.1\nX-Action: executar\n\n

Aqui por exemplo, como faço para filtrar o "X-Action" e retirar "executar" como valor?
É algo simples no Java, mas não sei como fazer no C++


  


2. MELHOR RESPOSTA

Paulo
paulo1205

(usa Ubuntu)

Enviado em 06/05/2018 - 14:55h

Escrevendo, agora, da casa dos meus pais, onde tenho hospedados alguns alfarrábios.

Eu trabalho muito com Perl. Por causa disso, eu desenvolvi há algum tempo umas versões de split() semelhantes à função nativa dessa linguagem.

Em Perl, e também nas versões que mostro abaixo, a função split() pode fazer as separações considerando como separadores uma string exata, mesmo com múltiplos caracteres, ou uma expressão regular. Além disso, é possível dizer qual a quantidade máxima de partes depois da separação. As versões abaixo assim o fazem.

/* split.h */
#ifndef __SPLIT_H__
#define __SPLIT_H__


#include <regex>
#include <string>
#include <vector>


#define SPLIT_H_RCSHEADER "$Header: $"


std::vector<std::string> split(const std::string &str, const std::string &sep, size_t max_fields=0);
std::vector<std::string> split(const std::string &str, const std::regex &sep_re, size_t max_fields=0);
std::vector<std::string> split(const std::string &str, size_t max_fields=0);


#endif // !defined(__SPLIT_H__)


/* split.cc */
#include <regex>
#include <string>
#include <vector>

#include "split.h"


using namespace std;


namespace {

const string RCSHEADER{"$Header: $"};
const string HEADER_RCSHEADER{SPLIT_H_RCSHEADER};

}

vector<string> split(const string &str, const string &sep, size_t max_fields){
vector<string> result;
const size_t str_len=str.length();
if(str_len){
const size_t sep_len=sep.length();
const size_t empty_sep=!sep_len;
size_t a, b;
for(
a=0;
(
(max_fields==0 || result.size()<max_fields-1) &&
(b=str.find(sep, a))!=str.npos && a<str_len-sep_len
);
a=b+sep_len
){
b+=empty_sep;
result.emplace_back(str, a, b-a);
}
if((a<str.length() || (a==str.length() && result.size()<max_fields)))
result.emplace_back(str, a);
}

return result;
}

vector<string> split(const string &str, const regex &sep_re, size_t max_fields){
vector<string> result;
const size_t str_len=str.length();
if(str_len){
smatch sep;
auto a=str.begin();
while(
a!=str.end() &&
(max_fields==0 || result.size()<max_fields-1) &&
regex_search(a, str.end(), sep, sep_re)
){
result.emplace_back(a, a+sep.position(0)+!sep.length(0));
a+=sep.position(0)+sep.length(0)+!sep.length(0);
}
if((a!=str.end() || (a==str.end() && result.size()<max_fields)))
result.emplace_back(a, str.end());
}

return result;
}

vector<string> split(const string &str, size_t max_fields){
return split(str, regex("\\s+"), max_fields);
}


Exemplo de uso.

/* test.cc */
#include <iostream>
#include <regex>
#include <vector>

#include "split.h"


using namespace std;


string join(const vector<string> &v, const string &sep){
string result;
if(v.size()){
auto v_i=v.cbegin();
result=*v_i;
while(++v_i!=v.cend())
(result+=sep)+=*v_i;
}
return result;
}

void test(const string &descr, const vector<string> &v){
cout << " " << descr << " yields ";
if(v.empty())
cout << "nothing.\n";
else
cout << v.size() << " part(s): \"" << join(v, "\", \"") << "\".\n";
}


int main(){
vector<string> test_texts{
"Isto e um teste.",
"Isto e um\tteste.",
"\t\t\t Isto e um teste. ",
"\t \n \r \t",
""
};
vector<string> parts;

for(const auto &text: test_texts){
cout << "text=\"" << text << "\":\n";
test("split(text, \" \")", split(text, " "));
test("split(text, \" \", 3)", split(text, " ", 3));
test("split(text, regex(\" +\"))", split(text, regex(" +")));
test("split(text, regex(\" +\"), 3)", split(text, regex(" +"), 3));
test("split(text)", split(text));
test("split(text, 3)", split(text, 3));
cout << '\n';
}
}


Uma diferença (entre outras possíveis que eu não vi por falha minha), porém, entre a versão do Perl e a minha, é que aquela usa número de partes negativo como sinônimo de um valor arbitrariamente positivo, e a minha, por usar size_t, não suporta valores negativos de modo nenhum. Em vez disso, alguém poderia usar std::numeric_limits<size_t>::max().

3. Re: Como fazer Split String com C++? [RESOLVIDO]

Uilian Ries
uilianries

(usa Linux Mint)

Enviado em 06/05/2018 - 01:10h

Embora C++ não possua uma função de split, existem vários idiomas que cumprem essa tarefa.

Esta é um possível solução


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

std::vector<std::string> split(const std::string& text, const char delimiter = ' ') {
std::vector<std::string> tokens;
size_t current;
size_t next = -1;
do {
current = next + 1;
next = text.find_first_of(delimiter, current);
tokens.push_back(text.substr(current, (next - current)));
} while (next != std::string::npos);
return tokens;
}

int main() {
std::string s = "viva o linux";
const std::vector<std::string> tokens = split(s);
for (const std::string& token : tokens) {
std::cout << token << std::endl;
}
return 0;
}



4. Re: Como fazer Split String com C++?

Paulo
paulo1205

(usa Ubuntu)

Enviado em 06/05/2018 - 07:09h

Como você usou apenas um caráter como terminador, poderia ter usado std:: string::find() em lugar de std::string::find_first_of(), ou então usar um conjunto de caracteres terminadores alternativos, colocando o segundo parâmetro em “const char *” ou “const std::string &”.

Sua função também trata a ocorrência repetida de separadores como vários campos vazios. Normalmente eu gosto disso, mas há casos em que é melhor tratar separadores adjacentes como um separador só. Talvez a função pudesse ter um parâmetro a mais para dizer se separadores adjacentes seriam entendidos como um separador só ou como múltiplos.


5. Re: Como fazer Split String com C++? [RESOLVIDO]

Fernando
phoemur

(usa Debian)

Enviado em 07/05/2018 - 17:41h

Aqui tem um cardápio bem vasto de opções para você dividir sua string em C++:
https://www.fluentcpp.com/2017/04/21/how-to-split-a-string-in-c/






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts