2017-03-13 5 views
-2

Je rencontre des problèmes avec une tâche, et j'ai cherché dans toute la pile et google, mais je n'arrive pas à comprendre les problèmes.C++ comparant le fichier texte et l'erreur de segmentation (core dumped)

À l'heure actuelle, le seul code que j'ai à ce jour est de demander à l'utilisateur de mettre une phrase, puis de diviser la phrase en différentes chaînes. Et j'ai aussi besoin de le comparer à un fichier texte que j'ai à mi-chemin.

Premier problème: Ma méthode de décomposition des mots en différentes chaînes ne fonctionne que rarement. Par exemple quand j'écris "les gens d'histoire" il me dit theres une faute de segmentation, mais si je tape dans "les gens d'histoire" (avec l'espace à la fin), cela fonctionne bien. Je suis confus quel est le problème.

Le deuxième problème est que je ne peux pas comprendre comment comparer ma chaîne au fichier texte ligne par ligne, il semble stocker le fichier entier dans ma variable de chaîne "texte".

#include <iostream> 
#include <fstream> 
#include <string> 

using namespace std; 

int noun(string n) 
{ 
    ifstream inputfile; 
    bool found = false; // set boolean value to false first 
    string text; 
    inputfile.open("nouns"); // open text file 
    if (!inputfile.is_open()) 
    { // checks to make sure file is open 
     cout << "Error" << endl; 
    } 

    while (getline(inputfile,text,' ')) 
    { 
     if (n == text) 
     { 
      found = true; 
      cout << text; 
     } 
    } 
    inputfile.close(); // close the file 
    return found; // return true or false 
} 

int main() 
{ 
    string sent; 
    string word1, word2, word3, word4; // strings to parse the string 'sent' 
    cout << "Please enter a sentence" << endl; 
    getline (cin, sent); 

    int w1, w2, w3, w4 = 0; // positions in relation to the string 
    while (sent[w1] != ' ') 
    { // while loop to store first word 
     word1 += sent[w1]; 
     w1++; 
    } 

    w2 = w1 + 1; 
    while (sent[w2] != ' ') 
    { // while loop to store second word 
     word2 += sent[w2]; 
     w2++; 
    } 

    w3 = w2 + 1; 
    while (sent[w3] != ' ') 
    { // while loop to store 3rd word 
     word3 += sent[w3]; 
     w3++; 
    } 

    w4 = w3 + 1; 
    while (sent[w4] != sent[-1]) 
    { // while loop to store 4th word 
     word4 += sent[w4]; 
     w4++; 
    } 

    cout << word1; 

    if (sent.empty()) 
    { // empty set returns "invalid sentence" 
     cout << "Invalid Sentence" << endl; 
    } 
    else if (noun(word1) == true) 
    { 
     cout << "This is valid according to rule 1" << endl; 
    } 

    return 0; 
} 
+0

une autre chose que j'ai oublié de mentionner, si j'écris juste le mot "histoire" il imprime "histoire!" idk où le point d'exclamation vient de – HCL212

+0

Pourquoi ne pas juste 'cin >> word1; cin >> mot2; ... '? – SingerOfTheFall

+1

S'il vous plaît [modifier] votre code pour le réduire à [mcve] de votre problème. Votre code actuel comprend beaucoup de choses qui sont périphériques à votre problème - un échantillon minimal ressemble normalement à un bon test unitaire: effectuer une seule tâche, avec des valeurs d'entrée spécifiées pour la reproductibilité. –

Répondre

1

quand j'écris « les gens d'histoire » il me dit Theres une erreur de segmentation, mais si je tape « les gens d'histoire » (avec l'espace à la fin), il fonctionne très bien

Bien facile. Votre boucle while parcourt la chaîne jusqu'à ce qu'elle trouve un espace. Mais que faire s'il n'y a pas d'espace? Est-ce que la boucle se termine alors? Non - Il continuera jusqu'à ce qu'il finisse par trouver un caractère d'espace quelque part en mémoire ou se bloque ou autre chose (C'est undefined behavior donc tout peut arriver, en ajoutant un point d'exclamation à la fin de votre sortie). Comment réparer ça? Vérifiez si vous êtes à la fin de la chaîne.

while (sent[w1] != ' ' && w1 < sent.size()) ... 

ou utiliser une approche complètement différente de diviser la chaîne en premier lieu (Jetez un oeil à cette réponse here).

Au deuxième problème. Lire à partir du fichier me semble correct, mais sans savoir comment le contenu du fichier ressemble, je ne peux pas vraiment vous aider.

Selon votre code, je vous attendez le fichier à regarder un peu comme ça:

noun1 noun2 noun3 noun4 etc. 

puisque vous définissez le séparateur de getline être un espace: getline(inputfile, text, ' '). Cela signifierait que tous les noms du fichier sont séparés par un espace et listés sur une seule ligne. Est-ce le cas? Non? Eh bien, il suffit de changer le délimiteur pour être le délimiteur correct que vous utilisez dans le fichier lui-même. (Btw Si chaque nom est listé dans une ligne séparée, vous n'avez pas besoin de spécifier un délimiteur getline(inputfile, text))

De même si vous vérifiez si le fichier n'a pas pu être ouvert, ne continuez pas à lire mais arrêtez l'exécution de ce fichier. fonction.

if (!inputfile.is_open()) { // checks to make sure file is open 
    cout << "Error" << endl; 
    return false; // return for example or throw an exception 
} 

Pourtant, il y a encore d'autres problèmes avec votre application, par exemple vérifier l'entrée de l'utilisateur avant de le traiter et vous n'avez pas besoin de fermer un ifstream son destructeur prend soin de cela.

Ou que pensez-vous que int w1, w2, w3, w4 = 0 fait? Définir toutes les variables à 0? Devinez quoi, non. w4 est initialisé et défini sur 0, mais toutes les autres valeurs ne sont pas initialisées et n'importe où leur utilisation appelle à nouveau UB.Donc, ce sent[w1] est un comportement indéfini, ce w1++ est, ce w2 = w1 + 1 est, et ...

Soyez toujours sûr et faites-le dans le bon sens. Une ligne par déclaration de variable et directement les initialiser.

int w1 = 0; 
int w2 = 0; 
int w3 = 0; 
int w4 = 0; 

ont également vous déjà entendu parler du principe DRY? Vos 4 boucles sont similaires, n'est-ce pas? Vous pouvez écrire une fonction pour le faire et l'appeler 4 fois (ou comme je l'ai déjà dit, utilisez une approche complètement différente).

+0

Merci pour le conseil, je viens de comprendre que la comparaison avec la fonction de fichier texte est bien, mais ses boucles mes essayant d'analyser la phrase originale qui pose problème. Nous ne sommes pas autorisés à utiliser des vecteurs et des tableaux, c'est pourquoi j'ai du mal à comprendre cela. – HCL212

+0

effectivement votre commentaire m'a juste aidé à cliquer dans ma tête, merci beaucoup! J'essayais de l'enrouler autour de mon cerveau pendant des heures la nuit dernière! Merci encore! – HCL212

+0

Content de pouvoir aider;) – muXXmit2X