'C++, Linked list with user inputs and have it add to one head?

So I need help with having the user input into just one head of the linked list and once the user types '+' into the program, the linked list will insert a new node to the list and start again and once the user types the '=', the two heads add with each other.

Thank you for the help in advance.

I'll provide my current code, output and desired output:

Code:

#include<iostream>
#include<string>
using namespace std;

struct Node {
    string data;
    Node* next;
};

void addToList(Node* head);

int main() {
    bool quit = false;
    int choice;
    Node* head = new Node;
    head->next = NULL;

    while (!quit) {
        cout << "1. add to list" << endl
            << "2. quit" << endl;
        cin >> choice;
        switch (choice) {
        case 1: addToList(head);
            break;
        case 2: quit = true;
            break;
        default:
            cout << "That is not a valid input, quitting program";
            quit = true;
        }
    }
}

void addToList(Node* head) {
    bool quit = false;
    string temp;
    Node* current;

    while (!quit) {

        cout << "Enter a word(quit to stop)";
        cin >> temp;

        if (temp == "quit") {
            quit = true;
        }
        else {
            // Allocate the new node here:
            current = new Node;
            current->data = temp;

            // the new node is inserted after the empty head
            // because head is an empty node in your implementation:
            current->next = head->next;
            head->next = current;

            // set current to head->next, because the head is empty in your implementation:
            current = head->next;
            while (current)
            {
                cout << current->data << endl;
                current = current->next;
            }
        }
    }
    return;
}

Current Output:

Enter a number(quit to stop)3
3
Enter a number(quit to stop)4
4
3
Enter a number(quit to stop)5
5
4
3

Desired Output:

Enter a number(quit to stop)3   
3    
Enter a number(quit to stop)4
34
Enter a number(quit to stop)5
345
Enter a number(quit to stop)+
Enter a number(quit to stop)1
1
Enter a number(quit to stop)2
12
Enter a number(quit to stop)=
357
c++


Solution 1:[1]

  • If you want to keep a pile of nodes (a list where you always insert at the end), it will be useful to have a tail pointer apart from the head pointer.
  • head and tail can be null pointers in a beginning; you don't need to have an empty node.
  • You'll need to pass them as references to addToList, since they can be modified (made to point to a new node).
  • If you use raw pointers, remember to delete the nodes you allocate via new.

[Demo]

#include <iostream>  // cin, cout
#include <string>

struct Node {
    std::string data{};
    Node* next{nullptr};
};

void addToList(Node*& head, Node*& tail) {
    bool quit{false};
    std::string temp{};
    Node* current{nullptr};

    while (!quit) {
        std::cout << "\tEnter a word (quit to stop):\n";
        std::cin >> temp;

        if (temp == "quit") {
            std::cout << "\tQuitting submenu.\n";
            quit = true;
        }
        else {
            // Allocate the new node here
            current = new Node;
            current->data = temp;

            if (tail) {
                tail->next = current;
                tail = current;
            }
            else {
                head = current;
                tail = current;
            }

            std::cout << "\t[";
            for (current = head; current; current = current->next) {
                std::cout << current->data << (current->next ? ", " : "");
            }
            std::cout << "]\n";
        }
    }
}

int main() {
    bool quit = false;
    int choice = 0;
    Node* head = nullptr;
    Node* tail = nullptr;

    while (!quit) {
        std::cout << "1. add to list, 2. quit:\n";
        std::cin >> choice;        
        switch (choice) {
            case 1:
                addToList(head, tail);
                break;
            case 2:
                std::cout << "Quitting main menu.\n";
                quit = true;
                break;
            default:
                std::cout << "That is not a valid input, quitting program.\n";
                quit = true;
        }
    }
    for (auto tmp{head}; tmp;) {
        tmp = tmp->next;
        delete head;
        head = tmp;
    }
}

// Input:
//
//   1
//   hello
//   quit
//   1
//   joe
//   quit
//   1
//   bye
//   quit
//   2
//
// Output:
//
//   1. add to list, 2. quit:
//      Enter a word (quit to stop):
//      [hello]
//      Enter a word (quit to stop):
//      Quitting submenu.
//   1. add to list, 2. quit:
//      Enter a word (quit to stop):
//      [hello, joe]
//      Enter a word (quit to stop):
//      Quitting submenu.
//   1. add to list, 2. quit:
//      Enter a word (quit to stop):
//      [hello, joe, bye]
//      Enter a word (quit to stop):
//      Quitting submenu.
//   1. add to list, 2. quit:
//   Quitting main menu.

Should you be able to use a std::vector instead of a list of Nodes, things would simplify a lot:

  • Adding a new element to the end would just require a push_back.
  • Printing the whole vector would also be a one-liner.
  • And, most importantly, you would forget about allocating and deallocating memory.

[Demo]

#include <fmt/ranges.h>
#include <iostream>  // cin, cout
#include <string>
#include <vector>

void addToList(std::vector<std::string>& list) {
    bool quit{false};
    std::string temp{};

    while (!quit) {
        std::cout << "\tEnter a word (quit to stop):\n";
        std::cin >> temp;

        if (temp == "quit") {
            std::cout << "\tQuitting submenu.\n";
            quit = true;
        }
        else {
            list.push_back(temp);
            fmt::print("\t{}\n", list);
        }
    }
}

int main() {
    bool quit = false;
    int choice = 0;
    std::vector<std::string> list{};

    while (!quit) {
        std::cout << "1. add to list, 2. quit:\n";
        std::cin >> choice;        
        switch (choice) {
            case 1:
                addToList(list);
                break;
            case 2:
                std::cout << "Quitting main menu.\n";
                quit = true;
                break;
            default:
                std::cout << "That is not a valid input, quitting program.\n";
                quit = true;
        }
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1