Как мне прочитать несколько переменных в узел? - PullRequest
0 голосов
/ 05 апреля 2020

Итак, мой проект - получить файл с именем "contacts.txt", прочитать данные и поместить данные в узел. Затем я помещаю этот узел в список. Я удаляю дубликаты и распечатываю полученный список. Я пытаюсь сначала прочитать данные и часть печати, но у меня проблемы с печатью моего списка.

Линия контакта выглядит следующим образом: Анджелина М. Пьер 306 420 1235

И каждая часть линии (имя, отчество, фамилия, номер телефона ) должен иметь свою собственную переменную. Я не совсем уверен, что я делаю неправильно, и я был бы признателен за помощь. Мой код:

#include <iostream>
#include <bits/stdc++.h>
#include <stdlib.h>
#include <fstream>
using namespace std;


class Node
{
public:
  string firstName;
  string middleI;
  string lastName;
  string phoneNum;
    Node *next;
};


// This function prints contents of linked list
// starting from the given node
void printList(Node* n)
{
    while (n != NULL) {
        cout << n->firstName->middleI->lastName->phoneNum << endl;
        n = n->next;
    }
}

//This function reads the data from a file called "contacts"
//And streams each line into a new node.
void readData(Node* &p)
{
  Node *newNode = new Node; /* Initializing the node*/

  ifstream fin("C:\\Users\\owner\\Documents\\contacts.txt");


  p = newNode;
  while(!EOF){
//fin >> firstName >> middleI >> lastName >> phoneNum; 
  //while(getline(fin,newNode->contacts)){
newNode->firstName;
newNode->middleI;
newNode->lastName;
newNode->phoneNum;
     newNode->next = new Node;
     newNode = newNode->next;
  }
}

// Driver code
int main()
{
    Node *head;
    readData(head);
    printList(head);
    return 0;
}

1 Ответ

0 голосов
/ 05 апреля 2020

Есть пара вещей, которые, я думаю, в основном умаляют производительность вашей программы. В вашей функции printList у вас есть строка cout << n->firstName->middleI->lastName->phoneNum << endl;, и я предполагаю, что вы намереваетесь напечатать всю информацию для пользователя. Однако здесь происходит то, что программа берет указатель n, пытается найти свойство firstName объекта, на который указывает объект, затем принимает это свойство и пытается найти свойство middleI этого свойства, затем свойство lastName , свойство и т. д. c. Эти поля, конечно, не существуют, поэтому ваша программа, скорее всего, будет иметь sh. Скорее, я думаю, что использование что-то вроде cout << n->firstName << " " << n->middleI << " " << n->lastName << " " << n->phoneNum << endl; будет работать лучше.

Кроме того, в вашей функции readData ваше время, пока l oop будет продолжать обновлять единственный узел p вместо создания новых узлов. поэтому (при условии, что ваш входной файл правильно отформатирован и все такое джазовое) ваш головной узел, который передается в эту функцию при вызове main(), будет равен только последнему контакту в вашем файле и вашему список будет иметь длину 1.


Кстати, я вижу, что у вас есть только Node класс. Если вы хотите работать со списками, вам, вероятно, следует создать второй класс (например, LinkedList), который принимает еще один уровень абстракции. Ваш класс Node затем будет обрабатывать установку / отчетность по своим данным и отвечать на то, какой узел следует за ним, а ваш класс LinkedList будет следить за списком (помня, где находится голова), добавляя / удаляя из list и поиск указанных c узлов в списке.


Некоторые другие соображения:

  1. Переменные, содержащиеся в классе, почти всегда должны быть private вместо публикации c. Причина инкапсуляции информации, в первую очередь, помимо ее организации, заключается в том, чтобы другие части программы, не имеющие отношения к изменению этой части вашего кода, не могли ее коснуться, и вы теряете эту защиту, когда вы все публикуете. c.
  2. Функции, которые вы используете для создания / добавления узлов, списков печати и т. Д. c., Должны быть методами (т. Е. Функциями определенного класса). Скажем, у меня есть некоторый класс Foo, который имеет функцию, которая действует на него с именем bar. Чтобы реализовать это, я мог бы написать что-то вроде:
class Foo {
    private:
        //Foo's variables
    public:
        void bar() {
            //bar's implementation
        }
    }

Вы сможете использовать метод bar() в другом месте, потому что он помечен public, и bar() будет нести ответственность за обработку любых необходимых манипуляций с информацией Foo.

Использование using namespace std; считается плохой практикой, поскольку иногда это может привести к неоднозначным вызовам функций, а добавление std:: является более явным. См. здесь для получения дополнительной информации. Использование ключевого слова NULL очень C -стиль, тогда как nullptr считается более правильным (и даже более безопасным) в C ++. Если вам любопытно, этот , кажется, дает довольно подробное объяснение этого изменения. Использование while(!fin.eof()) также считается неправильным, поскольку !fin.eof() вернет только true после вы закончили чтение входного файла. Таким образом, вы попытаетесь прочитать файл за концом, и это довольно опасно. См. здесь для получения дополнительной информации.

Немного долго, но я надеюсь, что это немного прояснит вам! Не стесняйтесь комментировать, если у вас есть какие-либо вопросы.

...