Mon programme s'arrête sans erreur à l'appel d'une fonction
Résolu/Fermé- Mon programme s'arrête sans erreur à l'appel d'une fonction
- Erreur 0x80070643 - Accueil - Windows
- Fonction si et - Guide
- Appel inconnu - Guide
- Nommez une application d'appel vidéo ou de visioconférence - Guide
- Programme demarrage windows 10 - Guide
3 réponses
19 févr. 2023 à 01:08
Si le fichier est vide, on n'arrive pas jusqu'à la fonction split(), auparavant la fonction data.pop_back(); est un "undefined behavior" qui tente de supprimer un caractère d'une chaine vide.
20 févr. 2023 à 19:20
Bonjour,
Le problème est à mon avis que tu ne fermes pas tes descripteurs fichiers et que du point de vue du C++ tu tentes d'écrire dans un fichier qui est en cours de lecture.
Voici une réécriture (avec quelques ajustements de ton programme). J'ai supposé ici que chaque ligne contenait le login et le mot de passe séparés par un espace. Le programme suppose qu'il n'y a pas d'espace autre que celui qui sépare un login et un mot de passe. On pourrait (sachant qu'un login ne peut comporter d'espace) plutôt chercher le premier espace (voir std::string::find) et splitter ainsi.
#include <iostream> #include <fstream> #include <map> #include <vector> //#include "sha256.h" using namespace std; inline string sha256(const string & s) { return s; } void split_(const string & str, char l, vector<string>& vect) { string actual; for (char letter: str) { if (letter == l) { vect.push_back(actual); actual = ""; } else { actual += letter; } } vect.push_back(actual); } int main() { // Get login from user string username, password; cout << "Enter your username: "; getline(cin, username); cout << "Enter your password: "; getline(cin, password); // Read map from file string filename = "code.txt"; ifstream file("code.txt"); map<string, string> my_map; if (file) { string line; vector<string> data_split; while (getline(file, line)) { split_(line, ' ', data_split); my_map[data_split[0]] = data_split[1]; } file.close(); } else { cerr << "Can't read " << filename << endl; return 1; } if (my_map.find(username) != my_map.end()) { // Verify if username in map and if code match if (my_map[username] == password) { cout << "Successfully logged!!"; return 0; } else { cout << "Wrong password!!"; return -1; } } else { // Register if username didn't exist cout << "Success fully registered!!\n"; ofstream file_out("code.txt", ios_base::app); if (file_out) { cout << username << ' ' << sha256(password) << endl; file_out << username << ' ' << sha256(password); file_out.close(); } } return 0; }
Quelques éléments d'explications :
- Il est important de fermer un descripteur fichier après utilisation, uniquement si celui-ci a été ouvert avec succès.
- J'ai utilisé using namespace std pour éviter d'avoir partout std::. Certains sont contre mais dans un c++ ça n'a pas vraiment d'importance. Par contre il ne faut jamais l'utiliser dans un hpp.
- J'ai délibérément remplacé ta fonction sha256 par la fonction identité, car elle n'est à mon avis pas liée au problème posé et permet à tout un chacun de reproduire plus facilement ton problème.
- Il est inutile de passer un paramètre en const si tu le passe par recopie (par exemple c'est le cas de ton char l). Ce qualificatif n'a d'intérêt pratique que si tu veux (dans ce que tu as écrit) valider qu'on ne modifie pas la recopie (donc l'intérêt est limité). Il est généralement utilisé lors d'un passage par pointeur ou par référence (voir const string & str dans le code que je propose) pour s'assurer que la fonction ne modifie pas la donnée passée en paramètre.
- J'ai distingué le cas où la clé (l'utilisateur) est déjà présente ou non dans la map (contrôle ou ajout d'une clé).
- J'ai changé le contrôle du login/mot de passe (ton test est en O(n) alors qu'une recherche dans une std::map se fait en O(log(n)).
Bonne chance
18 févr. 2023 à 23:30
Il est possible que le programme se bloque dans la fonction split_ si jamais la variable actual n'est jamais vidée après la dernière ligne de la chaîne str. Cela peut arriver si la chaîne str ne se termine pas par le caractère l spécifié dans la fonction split_. Pour résoudre ce problème, vous pouvez ajouter la ligne vect.push_back(actual) après la boucle for pour ajouter le contenu de actual à vect.
Voici la fonction split_ modifiée pour éviter ce problème :
void split_(const std::string str, const char l, std::vector<std::string>& vect) { std::string actual; for (char letter: str) { if (letter == l) { vect.push_back(actual); actual = ""; } else { actual += letter; } } vect.push_back(actual); }
Si cela ne résout pas votre problème, il est possible que le programme ait une autre erreur ailleurs dans le code. Vous pouvez ajouter des instructions std::cout supplémentaires pour identifier où le programme bloque et pour afficher les variables à chaque étape de l'exécution.
19 févr. 2023 à 01:17
merci,
je suis (presque) sur que c'est ça, mon fichier est vide quand j'ai fait le test!
merci à vous tous de m'avoir aider.