Partage
  • Partager sur Facebook
  • Partager sur Twitter

Problème avec std::stoi qui donne invalid_argument

23 avril 2019 à 19:16:36

Bonjour,

Désolé, je pense que mon problème va paraître bête, mais je n'arrive pas à m'en dépatouiller, alors voilà, je fais un petit Snake (cmd) en C++, jusque là, rien de bien compliqué, mais j'ai voulu faire un espèce de log pour avoir les 3 meilleures joueurs, du coup j'ai mis un simple .txt à côté et là j'ai un problème :

	ifstream logFile ("snake.txt");
	string line;
	string list [6];

	if (logFile.is_open()) {

		int i = 0;
		while( getline (logFile, line)) {
			list[i] = line;
			i++;
		}
	}

	else {
		cout << "Please replace the missing file 'snake.txt' in the folder."<<endl;
		system("pause");
		return 0;
	}

	logFile.close();
	cout<<stoi(list[1]);
	if ( 10 > stoi( list[1] )){
		cout << "Hello World";
	}
	string player = "";
	do {
		cout << "Player (12 char max): ";
		cin >> player;
	} while (player == "");

		int score = snake.GetScore();
		cout<< stoi(list[1]);

		if ( score > std::stoi(list[1]) ) {

			list[5] = list[3];
			list[4] = list[2];
			list[3] = list[1];
			list[2] = list[0];
			list[1] = score;
			list[0] = player;
		}

		else if ( score > std::stoi(list[3]) ) {

			list[5] = list[3];
			list[4] = list[2];
			list[3] = score;
			list[2] = player;
		}

		else if ( score > std::stoi(list[5]) ) {

			list[5] = score;
			list[4] = player;
		}

J'ai retiré le code superflu, qui ne sert pas pour ça, donc comme vous le voyez, je ne trouve pas théoriquement de problème quand je fais cout << stoi(list[1]);, pas de problème il me renvoie 0 (le score du 1er), mais après quant on en vient aux conditions, j'ai l'erreur 

Merci d'avance 

PS : Je pensais que ça peut être un problème avec le '\n' à la fin, mais dans ce cas, il ne devrait pas pouvoir le convertir à la base.

  • Partager sur Facebook
  • Partager sur Twitter
24 avril 2019 à 8:50:03

Bonjour,

Il n'y a pas de '\n' car std::getline() les retire.

Il manque des contrôles dans ce code.
- Ligne 8: que se passe-t-il s'il n'y a pas exactement 6 lignes extraites du fichier? On aura ligne[5] qui sera vide ou on aura une mémoire vérolée par une écriture dans ligne[6]!
- Tous les accès à std::stoi(). Des données d'origine externes sont toujours à contrôler. Le cas ligne[1] ou ligne[3] ou ligne[5] vide est probable et va indubitablement provoquer une exception.
- Ligne 27. Préciser que l'on souhaite moins de 12 caractères c'est bien. Mais il faudrait peut-être vérifier que c'est bien le cas, c'est fou le nombre de personnes inciviles qui justement feront exprès d'en saisir 13, voire des très tordues qui en saisiront 10 millions.

Pour contourner les exceptions de std::stoi(), on peut les 'catcher' ou on peut utiliser une fonction qui n'en produit pas comme std::from_chars() qui n'existe que depuis C++17.

int stoi_securisee( std::string const& s , int valdef=-1 ) {  // retourne -1 en cas d'incident
    int  res = valdef;
    try {
        res = std::stoi( s );
    }
    catch ( std::logic_error& ) {
    }
    return  res;
}
  • Partager sur Facebook
  • Partager sur Twitter

En recherche d'emploi.

9 juin 2019 à 22:48:08

Merci beaucoup ça a réglé le problème !!!
  • Partager sur Facebook
  • Partager sur Twitter
9 juin 2019 à 23:47:11

Bonsoir

en simplifié, que fait la fonction stoi ?

Je vous remercie

https://en.cppreference.com/w/cpp/string/basic_string/stol

  • Partager sur Facebook
  • Partager sur Twitter
10 juin 2019 à 1:40:54

YES, man a écrit:

Bonsoir

en simplifié, que fait la fonction stoi ?

Je vous remercie

https://en.cppreference.com/w/cpp/string/basic_string/stol


Ah oui quand même...Alors comme ça, ça pose des questions sur le lien entre thread materiel et logiciel alors que ça bloque sur std::stoi????

 C'est un peu comme chercher à resoudre un des 7 problèmes du millenaire alors que ça bloque sur une simple derivée...

sinon, en simplifié : https://en.cppreference.com/w/cpp/string/basic_string/stol#Return_value

(Au pif, as tu lu la premiere ligne de ton propre lien? Si oui, tu en as compris quoi? Si non, qu'est que tu n'as pas comrpis?)

-
Edité par eugchriss 10 juin 2019 à 1:43:22

  • Partager sur Facebook
  • Partager sur Twitter

Eug

10 juin 2019 à 16:31:54

Bonjour,

D'après ce que j'ai compris, std::stoi, extrait le plus grand entier possible comme succession de chiffre, en retirant les espaces vides les précédant, et arrête l'extraction dès qu'il tombe sur la présence de quelque chose qui n'est plus un chiffre si j'ai compris.

n'hésitez pas à me dire si je peux améliorer ma compréhension

  • Partager sur Facebook
  • Partager sur Twitter