简体   繁体   English

访问指针向量

[英]Accessing a vector of pointers

this is for a CS assignment. 这是用于CS分配的。 I've looked at similar problems/questions, but can't seem to find an answer for this. 我看过类似的问题/问题,但似乎找不到答案。

A little background info: We need to sort c-strings in a list and count how many times each word occurs. 一些背景信息:我们需要对列表中的c字符串进行排序,并计算每个单词出现的次数。 Needed for the problem: Write a program Problem2_A.cpp that inputs several lines of text from the keyboard as C-strings and prints an alphabetical listing of each word in the text and how many times it occurred. 解决问题的必要条件:编写一个程序Problem2_A.cpp,该程序从键盘以C字符串形式输入多行文本,并按字母顺序列出该单词的每个单词及其出现的次数。 To do this, keep a pointer to each word in an array of pointers. 为此,请将指针指向数组中每个单词。 Use the qsort() function to sort the array of pointers and then count the number of occurrences of each word. 使用qsort()函数对指针数组进行排序,然后计算每个单词的出现次数。 Terminate input by signaling end-of-file from the keyboard. 通过发信号通知键盘结束文件来终止输入。 Ignore any case differences (eg, “Cat” and “cat” are the same word). 忽略大小写差异(例如,“ Cat”和“ cat”是同一个词)。 As a minimum requirement, you may assume there will be no punctuation marks and that exactly one space will separate words in the input lines. 最低要求是,您可以假定将没有标点符号,并且仅一个空格将输入行中的单词分隔开。 You may remove this limitation as an extension. 您可以删除此限制作为扩展。

Edit- I understand I will need to have user input one line with a bunch of words. 编辑-我知道我需要用户输入一行单词。 For now, I will just input each word manually as I am more concerned about accessing the vector and retrieving what I want to retrieve. 现在,我将只手动输入每个单词,因为我更关心访问向量和检索要检索的内容。

Here is what I have so far 这是我到目前为止的

Word.H 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 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 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;
}

I was never too good with pointers, but if I'm understanding this right, what I currently have is a vector of pointers pointing to the locations of my Word objects, which I have dynamically assigned. 我对指针从来都不是太擅长,但是如果我理解正确的话,我目前拥有的是指向我动态分配的Word对象位置的指针向量。

Part of my confusion possibly comes from the question -- Do I need to put objects into the vector of pointers? 我的部分困惑可能来自这个问题-我是否需要将对象放入指针向量中? Or do I make pointers to the objects and put those pointers in the vector of pointers? 还是我将指针指向对象并将这些指针放在指针向量中?

Anyways, as you can see i'm trying to figure out the correct way to output the word. 无论如何,如您所见,我正在尝试找出输出单词的正确方法。 When I call it as 当我称它为

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

this outputs a location address for each word (pointer of word?). 这将为每个单词(单词的指针?)输出一个位置地址。 Using 运用

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

will output a different location (pointer to the index of the vector?) 将输出一个不同的位置(指向向量索引的指针?)

and using 和使用

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

and

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

will print out the same junk. 将打印出相同的垃圾。

I am most likely doing this wrong because 我很可能做错了,因为

pWordList[i]->getWord()

should print out the c-string in question, but I think it is somewhere getting lost in transit and the pointer location becomes invalid. 应该打印出有问题的c字符串,但是我认为它在传输中丢失了,并且指针位置变为无效。 Really any advice or input would be offered. 确实会提供任何建议或意见。

Edit2-- As noted by Colin Basnett and T33C, I have changed the function to Edit2--如Colin Basnett和T33C所述,我已将功能更改为

/*
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;
}

and I am now able to output the right thing. 现在我可以输出正确的内容。 Still wondering about the two different locations coming from &pWordList[i] and (void*)pWordList[i]->getWord() 仍然想知道来自&pWordList [i]和(void *)pWordList [i]-> getWord()的两个不同位置

Edit3-- Here is my method containing my non-working map. Edit3--这是我的方法,其中包含无效的地图。 It should sort the vector and create a map with the word (which is actually the pointer to the word) and the amount of times it occurrs. 它应该对向量进行排序,并使用单词(实际上是指向单词的指针)及其出现的次数来创建映射。 However, it just sorts it. 但是,它只是对其进行排序。 It prints out each word with an occurrence of 1, even if the same word was entered multiple times. 即使多次输入相同的单词,也会打印出出现的每个单词1。 This is because it's actually inserting the pointer to the word, not the word itself, into the key section. 这是因为它实际上是将指向单词的指针而不是单词本身插入键部分。

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;
    }

}

I have tried changing 我尝试改变

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

to

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

However, that gives an error stating 但是,这说明了错误

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

Edit4-- I emailed my professor again seeing if creating a map of strings and converting the char* to a string and he said that I could, so here is the updated measureVector method incase anyone else was following this. Edit4--我再次给我的教授发电子邮件,看看是否创建字符串映射并将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;
    }
}

Thanks for the guidance, all! 谢谢大家的指导!

There are many issues in this code but key to your question is that you are returning a pointer to a buffer on the stack which no longer exists after the function returns. 这段代码中有很多问题,但问题的关键在于,您正在返回一个指向堆栈缓冲区的指针,该缓冲区在函数返回后不再存在。 Function returns unwind their stack frame. 函数返回展开其堆栈帧。

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

I hesitate to say declare the buffer on the heap and return a pointer to that because the whole code is quite far from where it should be for modern C++. 我会犹豫地说,在堆上声明缓冲区并返回指向该缓冲区的指针,因为整个代码与现代C ++的位置相去甚远。

I recommend using: 我建议使用:

  1. std::string and returning that instead of a char* std :: string并返回它而不是char *
  2. never use new outside of a smart pointer (or something that will guarantee to call delete) see std::unique_ptr but std::string will be a better option in your case. 切勿在智能指针(或保证调用delete的东西)之外使用new,请参阅std :: unique_ptr,但在您的情况下,std :: string是更好的选择。

All the best with your studies. 一切顺利。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM