关于指向指针数组的指针

时间:2018-10-21 03:34:25

标签: c++

我目前正在从事一项作业,我想我已经成功地制作了一个周期表中从文件中读取的元素的链表(元素的数量会有所不同)。

但是我现在尝试创建一个指向Element指针数组的指针(Element **ptr = new Element *[n]在主文件中找到并传递到read_table中)。我不确定该怎么做。我做的对吗?还是应该ptr[i] -> *head.pElement

元素结构已在另一个文件中创建,表将是该文件中的原型。

struct Node {
    Element *pElement;
    Node *next;
};

int table(Element **ptr) { // Was originally Element **&ptr, but that might have been supposed to be for my prototype
    Node *head = new Node; // starts off the linked list
    Node *temp = new Node; // temp node to make switch for head node
    Element e; 

    int counter = 0; // counter to keep track of num of elements

    // open input file
    ifstream infile;
    infile.open(file_path_will_be_placed_here);

    // loop to read file and create linked list
    while(infile >> e.atomicNumber) {
        infile >> e.name;
        infile >> e.abbreviation;
        infile >> e.mass;

        head -> pElement = new Element; // the node's pElement points to a new Element
        *head -> pElement = e; // sets node's pElement to the read data stored in e
        *temp -> next = head; // might have to point to &head
        head = temp; // head points to where temp does
        temp = new Node; // temp points to new node

        counter++; // increment counter every time for every element
    }

    for(int i = 0; i < counter; i++) {
                // confused !@!@?
            ptr[i] -> head.pElement;
    }

1 个答案:

答案 0 :(得分:2)

while(infile >> e.atomicNumber) {
    infile >> e.name;
    infile >> e.abbreviation;
    infile >> e.mass;

首先,您希望从infile提取的所有内容都能成功地保持循环运行:

while (infile >> e.atomicNumber >> e.name >> e.abbreviation >> infile >> e.mass) {

然后让我们看看您的“列表”:

    head->pElement = new Element;  // ok
    *head->pElement = e;           // ok
    *temp->next = head;
    head = temp;                   // now you have a head with a pElement pointing to garbage
                                   // and a next pointing to the node with pElement pointing
                                   // to the Element you just read, the next of that Node
                                   // points to garbage, though *)                                     
    temp = new Node;               

    counter++;
}

*),因此当您尝试浏览列表时,您将不得不忽略头部的pElement,但也不会知道何时到达列表末端,因为您从未设置next-pointer到nullptr,以便可以从指向下一个节点的指针中区分出来。

int table(Element **&ptr) // should return std::size_t
{
    ifstream infile{ "test.txt" };
    int num_elements{}; // should be std::size_t
    Element e;
    Node *head{};
    Node *current{};
    while (infile >> e.atomicNumber >> e.name >> e.abbreviation >> e.mass) {

        if (!head) {
            head = new Node;
            head->next = nullptr;
            head->pElement = new Element;
            *head->pElement = e;
            current = head;
        }
        else {
            current->next = new Node;
            current = current->next;
            current->next = nullptr;
            current->pElement = new Element;
            *current->pElement = e;
        }
        ++num_elements;
    }

    Element **array = new Element*[num_elements];

    current = head;
    Node *temp;
    for (int i = 0; i < num_elements && current; ++i) {
        array[i] = current->pElement;
        temp = current;
        current = current->next;
        delete temp;
    }

    ptr = array;
    return num_elements;
}

int main()
{
    Element **elements;
    int num_elements = table(elements);

    // do something with elements

    for(int i{}; i < num_elements; ++i)
        delete elements[i];
    delete [] elements;
}


Real tm 解决方案:

#include <vector>
#include <string>
#include <iterator>
#include <fstream>

struct Element {
    int atomicNumber;
    std::string name;
    std::string abbreviation;
    double mass;
};

std::istream& operator>>(std::istream& is, Element &element)
{
    Element e;
    if (!(is >> e.atomicNumber >> e.name >> e.abbreviation >> e.mass))
        return is;
    element = e;
    return is;
}

std::vector<Element> read_elements()
{
    std::ifstream infile{ "test.txt" };
    std::vector<Element> elements{ std::istream_iterator<Element>{ infile },
                                   std::istream_iterator<Element>{} };
    return elements;
}