2017-03-13 25 views
-2

私は割り当てに問題があり、スタックとグーグル全体を検索しましたが、問題を把握することはできません。テキストファイルとセグメンテーションフォールトを比較するC++(コアダンプ)

今のところ、私が今までに持っている唯一のコードは、ユーザーに文章を入力し、文章を別の文字列に分割することです。そして私はそれを私が途中で得たテキストファイルと比較する必要もあります。

最初の問題:単語を別の文字列に分割する私の方法は時々しか動作しません。例えば、私が "歴史人"と書くと、それは私にセグメンテーションの誤りを教えてくれるが、私が "歴史人"(最後にスペースを入れている)をタイプすればうまくいく。私は問題が何であるか混乱している。

2番目の問題は、文字列とテキストファイルを行単位で比較する方法を見つけることができないことです。文字列変数 "text"にファイル全体を格納するようです。

#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

私は「履歴」という言葉を書いただけで、「歴史」を印刷しているということを忘れていました。 idkどこの感嘆符が – HCL212

+0

から来ているのですか?なぜあなただ​​けの 'cin >> word1;シン>> word2; ...? – SingerOfTheFall

+1

コードを編集して問題の[mcve]に減らしてください。あなたの現在のコードには、問題の周辺にあるものが多く含まれています。通常、最小単位のサンプルは良い単位テストと似ています。 –

答えて

1

私は「歴史の人々」を書くとき、それはセグメンテーションフォールトをtheresのが、私は(末尾のスペースで)「歴史人」と入力すれば、それは

を正常に動作します私に語りました

まあ簡単です。 whileループはスペースを見つけるまで文字列をループします。しかし、スペースがない場合はどうなりますか?ループは終了しますか? Nope - メモリやクラッシュなどで空白文字が見つかるまで続きます(undefined behaviorなので、基本的にすべてが実行され、出力の最後に感嘆符が追加されます)。それを修正するには?文字列の最後にいるかどうかを確認します。

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

か(この答えhereを見て)最初の場所で文字列を分割するために完全に異なるアプローチを使用しています。

第2の問題点。ファイルからの読み込みは大丈夫ですが、ファイルの内容がどのように見えているかわからないと、私はあなたを本当に助けることができません。

あなたのコードによると、私は、ファイルが多少そのように見えることを期待したい:getline(inputfile, text, ' ')

noun1 noun2 noun3 noun4 etc. 

あなたはスペースであることをgetlineの区切り文字を設定以来。これは、ファイル内のすべての名詞がスペースで区切られ、すべて1行にリストされていることを意味します。これは本当ですか?いいえ?さて、区切り文字を、ファイル自体で使用している正しい区切り文字に変更してください。各名詞が別の行に記載されている場合は、区切り文字を指定する必要はありませんgetline(inputfile, text)

また、ファイルを開くことができなかったかどうかを確認しても、関数。

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


しかし、例えばアプリケーション、と他の問題が残っていますそれを処理する前にユーザの入力をチェックして、 ifstreamを閉じる必要はありません。そのデストラクタはそれを処理します。

または、int w1, w2, w3, w4 = 0は何と思いますか?すべての変数を0に設定しますか?何を想像してください。 w4は初期化され、0に設定されますが、他のすべての値は初期化されず、再度それらを使用する場所でUBが呼び出されます。したがって、このsent[w1]は未定義の動作です。このw1++は、w2 = w1 + 1です。

必ず正しい方法で実行してください。変数宣言ごとに1行を直接宣言します。

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

DRYの原則について聞いたことがありますか?あなたの4 whileループは似たように見えますが、そうではありませんか?あなたはそれを行うための関数を書くことができ、それを4回呼び出すことができます(あるいは、私が前に言ったように、まったく別の方法を使います)。

+0

アドバイスをありがとう、私はちょうどテキストファイルの関数との比較は良いですが、私のループは、問題を引き起こす元の文を解析しようとしていることを考え出した。ベクトルと配列を使用することは許されていないため、これを理解するのは苦労しています。 – HCL212

+0

実際にあなたのコメントは私の頭の中でそれをクリックするのを手伝ってくれました、ありがとう!私は昨夜何時間もこのことを私の脳の周りに包み込もうとしていました!再度、感謝します! – HCL212

+0

私が助けることができてうれしい;) – muXXmit2X

関連する問題