2010-08-08 5 views
1

Voici un exemple de programme utilisant stringstream. L'objectif est d'accepter les lignes de l'utilisateur (entrée standard) et d'imprimer chaque mot sur une ligne distincte.Est-il possible d'accepter de l'utilisateur (entrée standard) au flux de chaîne directement?

int main() 
{ 

    std::istringstream currentline; 
    std::string eachword; 
    std::string line; 

    // Accept line from the standard input till EOF is reached 
    while (std::getline(std::cin,line)) 
    { 
     currentline.str(line); // Convert the input to stringstream 
     while (currentline >> eachword) // Convert from the entire line to individual word 
     { 
      std::cout << eachword << std::endl; 
     } 
     currentline.clear(); 
    } 
    return 0; 
} 

Je me demande, est-il possible, je peux éviter la variable de chaîne intermédiaire (objet), la ligne et stocke directement l'entrée d'utilisateur à la CurrentLine (objet istringstream).

Note:

Je sais, la solution suivante déjà.

while (std::cin >> eachword) 
{ 
    std::cout << eachword << std::endl; 
} 
+2

Pourquoi ne pas simplement utiliser la deuxième solution? –

+0

Neil, c'est-ce que je compte faire. – user373215

Répondre

1

std::getline besoin d'un argument de référence de chaîne, et c'est là, il place la ligne qu'il a obtenu, donc bien sûr vous ne pouvez pas éviter de passer un tel argument (et toujours utiliser cette fonction). Vous pouvez élégamment la construction résumer, si vous avez besoin souvent - .: par exemple

bool getline(std::istream& i, std::istringstream& current) 
{ 
    std::string line; 
    if (std::getline(i, line)) { 
     current.str(line); 
     return true; 
    } 
    return false; 
} 
+2

Encapsulate, sûrement –

+1

? fonction Nice. Mais je crois, vous avez l'intention de prendre istream comme paramètre Dans ce cas, la déclaration if ne devrait pas être comme ceci if (std :: getline (i, ligne)) – user373215

+0

@Neil et @nsivakr, vous avez tous les deux raison, tx - +1, et éditer pour corriger –

0

Si vous souhaitez simplifier la première solution,

while (currentline(line) >> eachword) 
+0

Jacob, quand j'essaie, il n'a même pas compile. – user373215

0

Je suppose que vous voulez de ne pas utiliser un objet intermédiaire pour empêcher la copie inutile?

Vous pouvez obtenir le même effet en définissant explicitement la zone tampon des tampons de flux.

int main() 
{ 
    std::string line; 
    std::istringstream currentline; 
    std::string eachword; 

    // Accept line from the standard input till EOF is reached 
    while (std::getline(std::cin,line)) 
    { 
     // Set the buffer without copying. 
     currentline.clear(); 
     currentline.rdbuf()->pubsetbuf(&line[0], line.length()); 

     while (currentline >> eachword) 
     { 
      std::cout << eachword << std::endl; 
     } 
    } 
    return 0; 
} 

En raison de l'ordre de destruction. Vous devez juste vous assurer que le flux istringstream est détruit avant l'objet que vous utilisez en tant que buffer. Vous devez donc réarranger les déclarations en haut de main() pour vous assurer que cette ligne est créée en premier et sera donc détruite en dernier (sinon le destructeur de l'istringstream a le potentiel d'accéder à la mémoire d'un objet libre) .

+0

J'adore la solution, mais quand j'ai lancé le programme, il n'imprime pas les mots. rds, la boucle while interne, échoue à chaque fois. – user373215

+0

@nsivakr: Fixe. Ce n'est pas parce que vous réinitialisez le tampon que les indicateurs sont réinitialisés. Ajout de l'appel à effacer pour réinitialiser les indicateurs. –

+0

> Ne fonctionne toujours pas pour moi quand je l'exécute. – user373215