Como você limpa uma variável stringstream?

486

Eu já tentei várias coisas,

std::stringstream m;
m.empty();
m.clear();

os quais não funcionam.

CodingWithoutComments
fonte

Respostas:

771

Para todos os tipos de biblioteca padrão, a função membro empty()é uma consulta, não um comando, ou seja, significa "você está vazio?" não "jogue fora seu conteúdo".

A clear()função de membro é herdada iose é usada para limpar o estado de erro do fluxo, por exemplo, se um fluxo de arquivo tiver o estado de erro definido como eofbit(fim do arquivo), a chamada clear()retornará o estado de erro para goodbit(sem erro) .

Para limpar o conteúdo de a stringstream, use:

m.str("");

está correto, embora esteja usando:

m.str(std::string());

é tecnicamente mais eficiente, porque você evita invocar o std::stringconstrutor que leva const char*. Mas qualquer compilador hoje em dia deve ser capaz de gerar o mesmo código nos dois casos - então eu iria apenas com o que for mais legível.

Wilka
fonte
105
Aqui está o que acontece quando você esquece a parte "clear ()". stackoverflow.com/q/2848087/635549
galath
8
@KshitijBanerjee Acho que em C ++ m.str () e m.str ("") são duas funções diferentes. m.str () chama uma função que não esperava nenhum parâmetro, enquanto m.str ("") chama a função que aceita um parâmetro const char *. m.str () pode ter sido implementado como uma função get , que retorna a string, enquanto m.str ("") pode ter sido implementado como uma função definida .
Dinesh PR
4
Como galath disse, é muito importante também adicionar m.clear (); além de m.str ("") ;. Caso contrário, você poderá obter problemas se, em algum momento, preencher o fluxo de sequência com uma sequência vazia.
Sputnik
1
@anthropod Sim, isso foi no ano passado. Desde então, consegui que funcionasse.
James
1
Oh garoto, isso é intuitivo. Assim como tudo no C ++!
lua ensolarado
47

Você pode limpar o estado de erro e esvaziar o stringstream em uma linha

std::stringstream().swap(m); // swap m with a default constructed stringstream

Isso efetivamente redefine m para um estado construído padrão

Nikos Athanasiou
fonte
3
Essa é a maneira mais eficiente e elegante de fazer isso, em comparação com todas as outras respostas aqui. No entanto, std :: stringstream :: swap é um recurso do c ++ 11 e esta solução não funciona para compiladores anteriores do c ++ 11.
101010 03/11/19
4
Recurso ainda ausente no GNU g ++ v4.8, consulte stackoverflow.com/questions/24429441/…
Joachim W
7
@ 101010: Como a troca é melhor do que a atribuição de movimento?
Deduplicator
2
@AsetD: Mesmo que não seja exceção, você esqueceu o temporário construído por padrão?
Desduplicador
3
Isso é pouco eficiente. Quando quero reutilizar ss originais. Troca um vazio para mim.
Zhang
36
m.str("");

parece funcionar.

CodingWithoutComments
fonte
3
Isso seria limpo por .clear () especificado no OP.
Dave Lugg
33

Essa deve ser a maneira mais confiável, independentemente do compilador:

m=std::stringstream();
Jerron
fonte
2
Isso é melhor na minha opinião porque m.str (""); fez com que meu stringstream ficasse com esse valor vazio, independentemente do que eu tentasse. Mas usar isso eu não tenho esse problema
gelatine1
3
Encontrei o mesmo problema, pois mm.clear(); mm.str("");fiz o truque. (sem C ++ 11, caso contrário, a troca seria melhor).
Hochl 27/08/2015
1
@ hochl: Por que swapseria melhor do que a atribuição de movimento?
Deduplicator
4
Não é bom para todas as situações. Isso realocaria o buffer sempre que mm.str ("") não.
Shital Shah
3
Meu caso de uso principal para liberar um objeto stringstream é manter um objeto stringstream local ao redor para impedir instanciações desnecessárias do stringstream - instanciar um novo objeto stringstream copia o objeto de localidade global - teoricamente, isso é rápido e envolve apenas o incremento de um atômico, mas no nível de simultaneidade com que lido, é freqüentemente incapacitante.
Spacemoose
12

Estou sempre no escopo:

{
    std::stringstream ss;
    ss << "what";
}

{
    std::stringstream ss;
    ss << "the";
}

{
    std::stringstream ss;
    ss << "heck";
}
TimoK
fonte
1
Isso é melhor do que limpar ostringstream?
Robur_131
11

meus 2 centavos:

isso parecia funcionar para mim no xcode e no dev-c ++, eu tinha um programa na forma de um menu que, se executado iterativamente de acordo com a solicitação de um usuário, preencheria uma variável stringstream que funcionaria bem na primeira vez que o código funcionasse. executar, mas não limparia a cadeia de caracteres da próxima vez que o usuário executar o mesmo código. mas as duas linhas de código abaixo finalmente limparam a variável stringstream todas as vezes antes de preencher a variável string. (2 horas de tentativa e erro e pesquisas no Google), aliás, usar cada linha por si só não funcionaria.

//clear the stringstream variable

sstm.str("");
sstm.clear();

//fill up the streamstream variable
sstm << "crap" << "morecrap";
Francisco Cortes
fonte
-1

É um problema conceitual.

Stringstream é um fluxo, portanto, seus iteradores são avançados, não podem retornar. Em um fluxo de sequência de saída, você precisa de um flush () para reinicializá-lo, como em qualquer outro fluxo de saída.

Alcino Dall Igna Junior
fonte
2
pt.cppreference.com/w/cpp/io/basic_ostream/flush flush sincroniza com o dispositivo de armazenamento ao qual está associado. Esta não é a mesma reinicialização.
Clearer,
-12

Estes não descartam os dados no stringstream no gnu c ++

    m.str("");
    m.str() = "";
    m.str(std::string());

O seguinte esvazia o stringstream para mim:

    m.str().clear();
John
fonte
7
Não tenho tanta certeza de que isso funcionaria, pelas mesmas razões que a bernhardrusch não funcionaria. A função .str () retorna uma cópia e a limpeza da cópia não faria nada.
Verdagon
1
Esta solução não funciona para o Microsoft Visual C ++.
Zak
Incorreta. Clear estaria operando na cadeia retornada do fluxo, não no próprio fluxo.
Joey Carson