Como você limpa uma variável stringstream?


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.


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


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


33

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

m=std::stringstream();

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";
}

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";

-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.


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();

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.