2016-05-06 6 views
2

これはCS割り当てのためのものです。私は同様の問題や質問を見てきましたが、これに対する答えを見つけることはできません。ポインターのベクトルにアクセスする

少し背景情報: リスト内のc-stringsをソートし、各単語が何回出現するかをカウントする必要があります。問題に必要なもの:キーボードから数行のテキストをC-ストリングとして入力し、テキスト中の各単語のアルファベット順のリストとそれが何回起こったかを示すProblem2_A.cppプログラムを書く。これを行うには、ポインタの配列内の各単語へのポインタを保持します。 qsort()関数を使用してポインタの配列をソートし、各単語のオカレンス数を数えます。キーボードからファイルの終わりを知らせて、入力を終了します。大文字と小文字の違いを無視します(「Cat」と「cat」は同じ単語です)。最低限の要件として、句読点がないと仮定し、入力行の単語を区切るスペースが1つだけあることがあります。この制限を拡張機能として削除することができます。

編集 - ユーザーの入力に1行の単語を入力する必要があることを理解しています。今のところ、私はベクトルへのアクセスと検索したいものを取得することをより心配しているので、手動で各単語を入力します。ここで

がWord.H

これまでのところ、私が持っているものである
#pragma once 
#ifndef __WORD_H__ 
#define __WORD_H__ 
#define _CRT_SECURE_NO_WARNINGS 

class Word { 
public: 
    Word(char * word); 

    ~Word(); 

    /* Returns the inputted word */ 
    const char* getWord(); 

private: 
    char word[51]; 
}; 

#endif 

Word.cpp

#define _CRT_SECURE_NO_WARNINGS 
#include <iostream> 
#include "Word.h" 

Word::Word(char * word) { 
    strcpy(this->word, word); 
} 

Word::~Word() { 

} 

const char* Word::getWord() { 
    char* clone = new char[50]; 
    strcpy(clone, word); 
    return clone; 
} 

Problem2.cpp

#include <iostream> 
#include <vector> 
#include "Word.h" 

using namespace std; 

const int MAX_WORDS = 2; 
const int MAX_WORD_LENGTH = 15; 

char* promptWord(); 


int main() { 
    char inputWord[MAX_WORD_LENGTH]; 
    vector<Word*> pWordList; 
    pWordList.reserve(MAX_WORDS); 

    cout << "Please type each word and press enter: "; 

    for (int i = 0; i < MAX_WORDS; i++) { 
     Word* newWord = new Word(promptWord()); 
     pWordList.push_back(newWord); 
    } 

    cout << "Printing &pWordList[i]" << endl; 
    for (size_t i = 0; i < pWordList.size(); i++) { 
     cout << &pWordList[i] << endl; 
    } 

    cout << "Printing (void*)pWordList[i]->getWord()" << endl; 
    for (size_t i = 0; i < pWordList.size(); i++) { 
     cout << (void*)pWordList[i]->getWord() << endl; 
    } 

    cout << "Printing pWordList[i]->getWord()" << endl; 
    for (size_t i = 0; i < pWordList.size(); i++) { 
     cout << pWordList[i]->getWord() << endl; 
    } 

    cout << "Printing (*pWordList[i]).getWord()" << endl; 
    for (size_t i = 0; i < pWordList.size(); i++) { 
     cout << (*pWordList[i]).getWord() << endl; 
    } 

    /* Delete our dynamic objects */ 
    while (!pWordList.empty()) { 
     delete pWordList.back(); 
     pWordList.pop_back(); 
    } 




    system("pause"); 
    return 0; 
} 

/* 
Ask the user to enter their desired word 
@params inputWord[MAX_WORD_LENGTH] -> Desired word to be inputted 
@return Returns the user's inputted word 
*/ 
char* promptWord() { 
    char inputWord[MAX_WORD_LENGTH]; 
    cin.getline(inputWord, MAX_WORD_LENGTH); 
    return inputWord; 
} 

私はあまりにも良いことはなかったです私はこのことを理解している私が現在持っているのは、私が動的に割り当てたWordオブジェクトの場所を指すポインターのベクトルです。

私の混乱の一部は、おそらく質問から来る - 私はポインタのベクトルにオブジェクトを入れる必要がありますか?または、私はオブジェクトへのポインタを作成し、それらのポインタをポインタのベクトルに入れますか?

あなたがわかるように、私は単語を出力する正しい方法を理解しようとしています。私は

cout << &pWordList[i] << endl; 

としてそれを呼び出したときに、これは、各単語(単語のポインタ?)の場所アドレスを出力します。意志出力異なる位置(ベクトルのインデックスへのポインタ?)

cout << pWordList[i]->getWord() << endl; 

cout << (*pWordList[i]).getWord() << endl; 

を使用しては同じ出力します

cout << (void*)pWordList[i]->getWord() << endl; 

を使用 ジャンク。

私が最も可能性が高い。この間違ったをやっている

pWordList[i]->getWord() 

は、問題のC文字列をプリントアウトする必要がありますが、私はそれがどこかで輸送中に迷子にされ、ポインタの位置が無効になると思うので。本当にアドバイスやインプットが提供されます。コリン・BasnettとT33Cで述べたように

Edit2--は、私が

/* 
Ask the user to enter their desired word 
@return Returns new dynamic char containing inputted word 
*/ 
char* promptWord() { 
    char* inputWord = new char[MAX_WORD_LENGTH]; 
    cin.getline(inputWord, MAX_WORD_LENGTH); 
    return inputWord; 
} 

に機能を変更したと私は今、正しいことを出力することができるしています。それでも & pWordListから来る2つの異なる場所に疑問を抱い[i]を と (void *型)pWordList [I] - > getWord()

Edit3--はここに私の非稼働マップを含む私の方法です。それはベクトルをソートして、単語(実際には単語へのポインタ)とそれが発生する時間の量でマップを作成する必要があります。ただし、ソートするだけです。同じ単語が複数回入力された場合でも、出現する単語が1つずつ出力されます。これは実際には、単語自体ではなく単語へのポインタをキーセクションに挿入するためです。

void measureVector(vector<Word*> ourVector, int numOfElements) { 
    int count = 0; 
    bool isDone = false; 
    qsort(&ourVector[0], ourVector.size(), sizeof(Word*), wordCompare); 

    map<Word*, int> wordCount; 
    for (int i = 0; i < ourVector.size(); i++) { 
     wordCount[ourVector[i]]++; 
    } 

    for (auto const& wc : wordCount) { 
     cout << wc.first->getWord() << " appears " << wc.second << " times." << endl; 
    } 

} 

私があれば見て再び私の教授にメール

'[': no operator found which takes a right-hand operand of type 'const char *' (or there is no acceptable conversion) 

Edit4--を示すエラーを与えること、しかし

for (int i = 0; i < ourVector.size(); i++) { 
    wordCount[ourVector[i]->getWord()]++; 
} 

for (int i = 0; i < ourVector.size(); i++) { 
    wordCount[ourVector[i]]++; 
} 

を変更しようとしています文字列と変換のマップを作成する文字列にchar *をつけて、私ができると言ったので、ここに更新されたmeasureVectorメソッドがあります。

/* 
    Sorts our vector of pointers and puts all words into a map and 
    keeps track of each word's occurrence. 
    @params inputVector -> The vector of pointers to utilize. 

*/ 
void measureVector(vector<Word*> inputVector) { 
    /* Sort our vector of pointers */ 
    qsort(&inputVector[0], inputVector.size(), sizeof(Word*), wordCompare); 
    map<string, int> wordCount; 
    string ourString; 

    /* For each word in our vector, insert it into our map. */ 
    for (auto word : inputVector) { 
     ourString = word->getWord(); 
     wordCount[ourString]++; 
    } 

    /* For each unique word in our map, print out the word and how many times it occurred.*/ 
    for (const auto &p : wordCount) { 
     cout << p.first << " appears " << p.second << " time" << (p.second > 1 ? "s." : ".") << endl; 
    } 
} 

すべてのガイダンスのおかげで!

+0

あなたは要件を誤解しています。ユーザーは、一度に1単語だけでなく、複数の単語で任意の長さの文字列を入力できる必要があります。まず最初に作業して、コードに関する無数の問題に取り組むことができます。 –

+0

これについては後で心配します。今のところ、私の主な質問は、ベクトルのアクセスに関するものです。なぜなら、私が後でC文字列を切り取ったとき、最終的にベクトルに入れられるからです。私は今のところ簡単にするために単体で入力します。 – Carousser

+1

あなたの 'promptWord'関数はスタック位置へのポインタを返していますので、値はスタックが巻き戻されるとすぐにガベージになります。その関数から 'new'd' char'配列を返したいと思うでしょう。 –

答えて

3

このコードには多くの問題がありますが、あなたの質問の鍵は、関数が復帰した後にもはや存在しないスタック上のバ​​ッファへのポインタを返すことです。関数はスタックフレームを巻き戻します。

char* promptWord() { 
    char inputWord[MAX_WORD_LENGTH]; 
    cin.getline(inputWord, MAX_WORD_LENGTH); 
    return inputWord; 
} 

は、私は、ヒープ上のバッファを宣言言うと、全体のコードは、それが現代のC++のためにあるべき場所からかなり離れているので、それへのポインタを返すことを躊躇します。

私が使用することをお勧めします:

  1. のstd :: stringとCHARではなく*
  2. スマートポインタ(または削除呼び出すことが保証されます何か)の新しい外を使用しないことを返すのSTDを参照してください。 :unique_ptrではなく、std :: stringがあなたのケースではより良いオプションになります。

あなたの研究では最高です。

+1

ありがとうございます。 Colin Basnettはこれを指摘し、正しく単語を出力するようにしました。私はstd :: stringを使用することはできません。なぜなら、単語はC文字列でなければならないからです。私はコードが "原始的"であると理解していますが、私はこれまでのコースで学んだことのすべてをやっています。これは最初のレベルのC++コースであることに留意してください。私は研究をすることからいくつかのことを取ったが、そのほとんどはそれが私たちに教えられた方法である。 – Carousser

+1

@Carousser - あなたは私の答えを受け入れることに感謝します。 const char *を返すc_str()メソッドを呼び出して、std :: stringからCの文字列へのポインタを得ることができます。 C++は最近、多くの変更を経て、より安全で簡単なプログラミング言語になっています。 Scott MeyersとBjarne Stroustrupの最新の本を読んで、競争を先取りして読むことを強くお勧めします。 :) – T33C

+0

私は教授に電子メールで私がそれをすることができるかどうか尋ねました。しかし、私はそれをすべて動作させ、ポインタのベクトルをソートします。私の最後のことは、出現数を数えることです。マップを調べましたが、ポインタだけでなく、単語の実際の出現回数を数えるのに苦労しています。私はメインスレッドを更新するつもりです。あなたに瞬間があるなら、そのことについてより多くの洞察を提供できますか?そして私は間違いなくその本を私のリストに追加します! – Carousser

関連する問題