Pergunta

Eu estou escrevendo código simples que irá extrair um monte de nome, pares int de um arquivo. Eu estou modificando o código existente que usa apenas:

string chrom;
unsigned int size;
while ( cin >> chrom >> size ) {
    //  save values
}

Mas eu quero usar outro (similar) arquivo de entrada que tem as mesmas duas primeiras colunas, mas são seguidos por outros dados (que será ignorado). Então eu escrevo:

string chrom;
unsigned int size;
string line;
while ( getline(cin, line) ) {
    if( stringstream(line) >> chrom >> size ) {
        // save values
    }
}

Mas isso não compilar, dando o obsceno típico std lib modelo de vomitar:

 error: no match for "operator>>" in "std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >(((const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&)((const std::basic_string<char, std::char_traits<char>, std::allocator<char> >*)(& line))), std::operator|(_S_out, _S_in)) >> chrom"
istream:131: note: candidates are: std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(std::basic_istream<_CharT, _Traits>& (*)(std::basic_istream<_CharT, _Traits>&)) [with _CharT = char, _Traits = std::char_traits<char>]
[...another dozen lines...]

Right. linha não é um std :: string, mas alguma variação de std :: basic_string, etc. No entanto, instanciar explicitamente as obras stringstream.

string chrom;
unsigned int size;
string line;
while ( getline(genome, line) ) {
    stringstream ss(line);
    if ( ss >> chrom >> size ) {
       // save values
    }
    // Discard remainder of line
}

Por quê? O que está errado com o primeiro caso? A exemplo basic_io nas obras cplusplus.com sempre útil, por que não faz o meu código?

Update: Outro ponto de referência: o stringstream temporária funciona quando o primeiro valor extraído é um int em vez de uma string:

unsigned int chrom;  // works as int...
unsigned int size;
string line;
while ( getline(cin, line) ) {
    if( stringstream(line) >> chrom >> size ) {
        // save values
    }
}
Foi útil?

Solução

Três grupos de funções de membro e um grupo de funções globais sobrecarregar este "operador de extracção" (>>), ver http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/ .

  • stringstream (linha); --created um objeto temporário
  • ss stringstream (linha); -. Um objeto normal,

quando "chrom" é int, operador >> é sobrecarregado como extractor aritmética que é membro funções. Tanto o objeto normal ou bem objeto de trabalho temporário.

Quando "chrom" é uma string, operador >> deve ser sobrecarregado como istream& operator>> (istream& is, char* str), esta é uma função global, que deve levar a referência do objeto como parâmetro. No entanto, dado objecto temporário, que não estão autorizados a passar objectos temporários por referência não-const em C ++ padrão. A função de sobrecarga não pode obter a referência do objecto temporário a menos que a função de sobrecarga é definido como istream& operator>> (const istream& is, char* str). Infelizmente, isso não é o fato. A função (s) não pode ser sobrecarregado no caso objecto temporário, e, portanto, dando o erro como error: no match for function...

Outras dicas

Para expandir a resposta de John Weldon, o operador extrace ">>" faz duas coisas:

  1. extrai o próximo valor e coloca-o na variável à direita do operador.
  2. Incrementa a posição atual do fluxo do lado esquerdo.

Portanto, ele modifica tanto a sua esquerda e operando à direita. No seu caso, a esquerda mão operando é um valor temporário, e as carrancas do compilador em modificá-lo.

Alguns operadores em C e C ++ requerem que o valor do lado esquerdo do operador ser um Ivalue, isto é, que eles podem ser modificados.

Aqui é uma explicação mais completa.

Uma vez que o primeiro valor extraído da stringstream é um std :: string. Se fosse, digamos, um int, o stringstream (linha) versão iria funcionar.

Não há nenhum operador função membro >> em stringstream para std :: string. Portanto, o fluxo temporário não pode funcionar como um lvalue.

Não que eu entender completamente o acima ... mas talvez seja um ponto de partida para uma resposta melhor.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top