web-dev-qa-db-fra.com

Lecture de getline de cin dans un stringstream (C++)

J'essaie donc de lire une entrée comme celle-ci à partir de l'entrée standard (en utilisant cin):

Adam English 85
Charlie Math 76
Erica Histoire 82
Richard Science 90

Mon objectif est de stocker éventuellement chaque élément de données dans sa propre cellule dans une structure de données que j'ai créée. Je souhaite donc analyser les entrées afin que chaque élément de données soit individuel. Étant donné que chaque ligne d'entrée est entrée par l'utilisateur une à la fois, chaque fois que je reçois une ligne entière d'entrée que je dois analyser. Actuellement, j'essaie quelque chose comme ça:

stringstream ss;
getline(cin, ss);

string name;
string course;
string grade;
ss >> name >> course >> grade;

L'erreur que j'ai est que XCode me dit qu'il n'y a pas d'appel de fonction correspondant à getline qui me confond. J'ai inclus la bibliothèque string, je suppose donc que l'erreur est liée à l'utilisation de getline pour lire de cin à stringstream? Toute aide ici serait appréciée.

5
user5482356

Vous êtes presque là, l'erreur est très probablement1 parce que vous essayez d'appeler getline avec le deuxième paramètre stringstream, il vous suffit d'apporter une légère modification et de stocker les données dans le std::cin dans une string puis de les utiliser pour initialiser une stringstream à partir de laquelle vous pouvez extraire l'entrée: 

// read input
string input;
getline(cin, input);

// initialize string stream
stringstream ss(input);

// extract input
string name;
string course;
string grade;

ss >> name >> course >> grade;

1. En supposant que vous ayez inclus:

#include <iostream>
#include <sstream>
#include <string>

using namespace std;
9
Ziezi

Vous ne pouvez pas std::getline() a std::stringstream; seulement un std::string. Lire comme une chaîne, puis utiliser un stringstream pour l'analyser.

struct Student
{
  string   name;
  string   course;
  unsigned grade;
};

vector <Student> students;
string s;
while (getline( cin, s ))
{
  istringstream ss(s);
  Student student;
  if (ss >> student.name >> student.course >> student.grade)
    students.emplace_back( student );
}

J'espère que cela t'aides.

7
Dúthomhas

Vous pouvez simplement utiliser cin >> name >> course >> grade; car >> lira quand même les espaces.

2

Soit vous n'avez pas de code using namespace std dans votre code, soit vous ne qualifiez pas entièrement les appels passés aux API dans l'espace de noms std avec un préfixe std::, par exemple, std::getline(). La solution ci-dessous analyse CSV au lieu de créer une marque pour les valeurs contenant des espaces. La logique d'extraction de stdin, d'analyse du fichier CSV et de conversion de grade de chaîne en entier est séparée. L'utilisation de regex_token_iterator est probablement la partie la plus compliquée, mais elle utilise une expression assez simple pour la plupart.

// foo.txt:

// Adam,English,85
// Charlie,Math,76
// Erica,History,82
// Richard,Science,90
// John,Foo Science,89

// after compiling to a.exe, run with:
// $ ./a.exe < foo.txt 

// output
// name: Adam, course: English, grade: 85
// name: Charlie, course: Math, grade: 76
// name: Erica, course: History, grade: 82
// name: Richard, course: Science, grade: 90
// name: John, course: Foo Science, grade: 89

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

using namespace std;

typedef unsigned int uint;

uint stoui(const string &v) {
   uint i;
   stringstream ss;
   ss << v;
   ss >> i;
   return i;
}

string strip(const string &s) {
   regex strip_pat("^\\s*(.*?)\\s*$");
   return regex_replace(s, strip_pat, "$1");
}

vector<string> parse_csv(string &line) {
   vector<string> values;
   regex csv_pat(",");
   regex_token_iterator<string::iterator> end;
   regex_token_iterator<string::iterator> itr(
      line.begin(), line.end(), csv_pat, -1);
   while (itr != end)
      values.Push_back(strip(*itr++));
   return values;
}

struct Student {
   string name;
   string course;
   uint grade;
   Student(vector<string> &data) : 
      name(data[0]), course(data[1]), grade(stoui(data[2])) {}
   void dump_info() {
      cout << "name: " << name << 
      ", course: " << course << 
      ", grade: " << grade << endl;
   }
};

int main() {
   string line;
   while (getline(cin, line)) {
      if (!line.empty()) {
         auto csv = parse_csv(line);
         Student s(csv);
         s.dump_info();
      }
   }
}
0
solstice333