web-dev-qa-db-fra.com

Lire les numéros d'entrée séparés par des espaces

C'est peut-être une question pour débutants, mais je n'ai pas encore trouvé de réponse qui fonctionne pour moi.

Actuellement, j'écris un programme pour une classe qui accepte l'entrée d'un utilisateur (qui peut être un ou plusieurs nombres séparés par des espaces), puis détermine si le nombre est premier, parfait ou aucun. Si le nombre est parfait, il affichera les diviseurs.

Jusqu'à présent, j'ai déjà écrit le code du premier, du parfait et de la liste des diviseurs. Je suis bloqué sur la partie entrée de mon programme. Je ne sais pas comment obtenir l'entrée qui est séparée par des espaces pour parcourir mes boucles une par une.

Voici mon programme actuel:

cout<<"Enter a number, or numbers separated by a space, between 1 and 1000."<<endl;
cin>>num;

while (divisor<=num)
    if(num%divisor==0)
    {
        cout<<divisor<<endl;
        total=total+divisor;
        divisor++;
    }
    else divisor++;
if(total==num*2)
    cout<<"The number you entered is perfect!"<<endl;
else cout<<"The number you entered is not perfect!"<<endl;


if(num==2||num==3||num==5||num==7)
    cout<<"The number you entered is prime!"<<endl;

else if(num%2==0||num%3==0||num%5==0||num%7==0)
    cout<<"The number you entered is not prime!"<<endl;
else cout<<"The number you entered is prime!"<<endl;

return 0;

Cela fonctionne, mais seulement pour un seul numéro. Si quelqu'un pouvait m'aider à lire plusieurs entrées séparées par des espaces, ce serait grandement apprécié. En outre, juste une note latérale, je ne sais pas combien de nombres seront entrés, donc je ne peux pas simplement faire une variable pour chacun. Ce sera un nombre aléatoire de nombres.

Merci!

17
Raymond Aaron

Par défaut, cin lit à partir de l'entrée en supprimant tous les espaces. Donc, tout ce que vous avez à faire est d'utiliser une boucle do while pour lire l'entrée plusieurs fois:

do {
   cout<<"Enter a number, or numbers separated by a space, between 1 and 1000."<<endl;
   cin >> num;

   // reset your variables

   // your function stuff (calculations)
}
while (true); // or some condition
19
Murilo Vasconcelos

Je recommanderais de lire la ligne en chaîne, puis de la diviser en fonction des espaces. Pour cela, vous pouvez utiliser la fonction getline (...) . L'astuce consiste à avoir une structure de données de taille dynamique pour contenir les chaînes une fois divisées. Le plus simple à utiliser serait probablement un vecteur .

#include <string>
#include <vector>
...
  string rawInput;
  vector<String> numbers;
  while( getline( cin, rawInput, ' ' ) )
  {
    numbers.Push_back(rawInput);
  }

Disons que l'entrée ressemble à ceci:

Enter a number, or numbers separated by a space, between 1 and 1000.
10 5 20 1 200 7

Vous aurez maintenant un vecteur, des nombres, qui contient les éléments: {"10", "5", "20", "1", "200", "7"}.

Notez que ce sont toujours des chaînes, donc pas utiles en arithmétique. Pour les convertir en entiers, nous utilisons une combinaison de la fonction STL, atoi (...), et comme atoi nécessite une chaîne c au lieu d'une chaîne de style c ++, nous utilisons la classe string ' c_str () fonction membre.

while(!numbers.empty())
{
  string temp = numbers.pop_back();//removes the last element from the string
  num = atoi( temp.c_str() ); //re-used your 'num' variable from your code

  ...//do stuff
}

Maintenant, il y a des problèmes avec ce code. Oui, ça marche, mais c'est un peu maladroit, et ça met les chiffres dans l'ordre inverse. Permet de le réécrire pour qu'il soit un peu plus compact:

#include <string>
...
string rawInput;
cout << "Enter a number, or numbers separated by a space, between 1 and 1000." << endl;
while( getline( cin, rawInput, ' ') )
{
  num = atoi( rawInput.c_str() );
  ...//do your stuff
}

Il y a encore beaucoup de place à l'amélioration avec la gestion des erreurs (en ce moment, si vous entrez un non-nombre, le programme se bloquera), et il y a infiniment plus de façons de gérer réellement l'entrée pour l'obtenir sous une forme numérique utilisable (les joies de la programmation! ), mais cela devrait vous donner un début complet. :)

Remarque: J'ai eu les pages de référence sous forme de liens, mais je ne peux pas en publier plus de deux car j'ai moins de 15 messages: /

Edit: j'avais un peu tort sur le comportement des atoi; Je l'ai confondu avec les conversions string-> Integer de Java qui lèvent une exception Not-A-Number quand on leur donne une chaîne qui n'est pas un nombre, puis plante le programme si l'exception n'est pas gérée. atoi (), d'autre part, renvoie 0, ce qui n'est pas aussi utile car que faire si 0 est le nombre entré? Utilisons la fonction isdigit (...) . Une chose importante à noter ici est que les chaînes de style c ++ sont accessibles comme un tableau, ce qui signifie que rawInput [0] est le premier caractère de la chaîne jusqu'à rawInput [longueur - 1].

#include <string>
#include <ctype.h>
...
string rawInput;
cout << "Enter a number, or numbers separated by a space, between 1 and 1000." << endl;
while( getline( cin, rawInput, ' ') )
{
  bool isNum = true;
  for(int i = 0; i < rawInput.length() && isNum; ++i)
  {
    isNum = isdigit( rawInput[i]);
  }

  if(isNum)
  {
    num = atoi( rawInput.c_str() );
    ...//do your stuff
  }
  else
    cout << rawInput << " is not a number!" << endl;
}

Le booléen (true/false ou 1/0 respectivement) est utilisé comme indicateur pour la boucle for, qui parcourt chaque caractère de la chaîne et vérifie s'il s'agit d'un chiffre de 0 à 9. Si un caractère de la chaîne n'est pas un chiffre, la boucle se cassera lors de sa prochaine exécution lorsqu'elle atteindra la condition "&& isNum" (en supposant que vous avez déjà couvert les boucles). Ensuite, après la boucle, isNum est utilisé pour déterminer s'il faut faire vos trucs ou imprimer le message d'erreur.

14
Logan Nichols

Vous voudrez:

  • Lire l'intégralité d'une ligne depuis la console
  • Tokenisez la ligne en la divisant le long des espaces.
  • Placez ces morceaux divisés dans un tableau ou une liste
  • Parcourez ce tableau/liste, effectuez vos tests prime/perfect/etc.

Jusqu'à présent, qu'est-ce que votre classe a couvert dans ce sens?

5
ravuya