0

i wanted to read the text file by words and then apply each word for the linked list

but when i apply the whole content will goes to the first node of linked list

any idea what do i have to modify in the code

updated

i wander how can i iterate the word over the linked list i know i need another loop inside the while but i do not how do to it

it is build with C++

the file is working it showing by words but what i do not understand is how to take the words to be linked to each other

code:

 #include <bits/stdc++.h>
 #include <iostream>
 #include<string>
 using namespace std; 
  
class LinkedList{
    // Struct inside the class LinkedList
    // This is one node which is not needed by the caller. It is just
    // for internal work.
    struct Node {
        string x;
        Node *next;
    };

// public member
public:
    // constructor
    LinkedList(){
        head = NULL; // set head to NULL
    }

    // destructor
    ~LinkedList(){
        Node *next = head;
        
        while(next) {              // iterate over all elements
            Node *deleteMe = next;
            next = next->next;     // save pointer to the next element
            delete deleteMe;       // delete the current entry
        }
    }
    
    // This prepends a new value at the beginning of the list
    void addValue(string val){
        Node *n = new Node();   // create new Node
        n->x = val;             // set value
        n->next = head;         // make the node point to the next node.
                                //  If the list is empty, this is NULL, so the end of the list --> OK
        head = n;               // last but not least, make the head point at the new node.
    }

    // returns the first element in the list and deletes the Node.
    // caution, no error-checking here!
    string popValue(){
        Node *n = head;
        string ret = n->x;

        head = head->next;
        delete n;
        return ret;
    }

// private member
private:
    Node *head; // this is the private member variable. It is just a pointer to the first Node
};

int main() { //linkedlist
    LinkedList list;
    //string usama="usama";
    //list.addValue(usama);
    //list.addValue("h");
    //list.addValue("u");

    //cout << list.popValue() << endl;
    //cout << list.popValue() << endl;
    //cout << list.popValue() << endl;
    // because there is no error checking in popValue(), the following
    // is undefined behavior. Probably the program will crash, because
    // there are no more values in the list.
    // cout << list.popValue() << endl;
    
    //file
     // filestream variable file 
    fstream file; 
    string word, t, q, filename; 
  
    // filename of the file 
    filename = "file.txt"; 
  
    // opening file 
    file.open(filename.c_str()); 
  
    // extracting words from the file 
    while (file >> word) 
    { 
        list.addValue(word);
        cout<<list.popValue()<<endl;
        // displaying content 
        //cout << word << endl; 
    } 
    return 0;
}

i know maybe something wrong with the while loop but i am stuck at it

black snow
  • 47
  • 7
  • You CAN'T both `add` and `pop` in same loop. You are adding and then deleting the node. You never iterate over the list, you just add, print that node and delete it. There is no list left at the end of the loop. Also... [Why should I not #include ?](https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h/31816096) – David C. Rankin Jul 15 '20 at 08:03
  • What is the question exactly? What do want to achieve here? – Serge Ballesta Jul 15 '20 at 08:03
  • what i want to achieve is iterate the word from the file over the linked list – black snow Jul 15 '20 at 08:07
  • see the update please – black snow Jul 15 '20 at 08:08

1 Answers1

1

You have several problems. The first is popValue() does not handle the case where head == nullptr. This will likely cause a segfault when you attempt string ret = n->x; You can add a check on head and initialize ret to avoid this issue (the empty ret will be used to terminate the iteration later)

    string popValue(){
        Node *n = head;
        string ret {};
        
        if (!head)          /* validate head not nullptr */
            return ret;
        
        ret = n->x;

        head = head->next;
        delete n;
        return ret;
    }

Next, as addressed in the comment, you use 1 loop to addValue and popValue. That defeats the purpose of your list because every node you add is deleted when you popValue() leaving your list empty at the end of the loop. Use 2 loops, e.g.:

    // extracting words from the file 
    while (file >> word)
        list.addValue(word);
    while ((t = list.popValue()).length())
        cout << t << '\n';

(note: (t = list.popValue()).length() terminates the iteration when an empty-string is reached -- better to have popValue() return a node instead of string.

A short working example taking the filename to read as the first argument would be:

#include <iostream>
#include <fstream>
#include <string>

using namespace std; 

class LinkedList {
    struct Node {
        string x;
        Node *next;
    };

  public:
    LinkedList(){
        head = NULL; // set head to NULL
    }

    ~LinkedList(){
        Node *next = head;
        
        while(next) {              // iterate over all elements
            Node *deleteMe = next;
            next = next->next;     // save pointer to the next element
            delete deleteMe;       // delete the current entry
        }
    }
    
    void addValue(string val){
        Node *n = new Node();   // create new Node
        n->x = val;             // set value
        n->next = head;         // make the node point to the next node.
                                //  If the list is empty, this is NULL, so the end of the list --> OK
        head = n;               // last but not least, make the head point at the new node.
    }

    string popValue(){
        Node *n = head;
        string ret {};
        
        if (!head)          /* validate head not nullptr */
            return ret;
        
        ret = n->x;

        head = head->next;
        delete n;
        return ret;
    }

  private:
    Node *head; // this is the private member variable. It is just a pointer to the first Node
};

int main (int argc, char **argv) { //linkedlist
    
    LinkedList list;
    // filestream variable file 
    fstream file; 
    string word, t, q, filename; 

    // opening file 
    if (argc < 2)
        return 1;
    
    file.open(argv[1]); 
    if (!file.is_open()) {
        cerr << "file open failed.\n";
        return 1;
    }
    
    // extracting words from the file 
    while (file >> word)
        list.addValue(word);
    while ((t = list.popValue()).length())
        cout << t << '\n';

    return 0;
}

Example Input File

$ cat dat/captnjack.txt
This is a tale
Of Captain Jack Sparrow
A Pirate So Brave
On the Seven Seas.

Example Use/Output

$ ./bin/llwords dat/captnjack.txt
Seas.
Seven
the
On
Brave
So
Pirate
A
Sparrow
Jack
Captain
Of
tale
a
is
This

Lastly see Why is “using namespace std;” considered bad practice? and Why should I not #include <bits/stdc++.h>?

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
  • thanks for helping but i am getting an error in this line **string ret {};** **[Warning] extended initializer lists only available with -std=c++11 or -std=gnu++11** and secondly **[Error] in C++98 'ret' must be initialized by constructor, not by '{...}'** – black snow Jul 15 '20 at 08:38
  • 1
    You need to include `-std=c++11` for the initializer. See [Value initialization](https://en.cppreference.com/w/cpp/language/value_initialization) If your compiler doesn't support C++11, you can use `ret()` – David C. Rankin Jul 15 '20 at 08:39
  • sorry but what do you mean include **-std=c++11** it is my first time to see this – black snow Jul 15 '20 at 08:42
  • 1
    When you compile, you see the warning/error telling you you need `-std=c++11` or `-std=gnu++11` is needed? (which tells me you are using `g++` good). Just add that to your compile string. `g++ -Wall -Wextra -std=c++11 -O3 -o youroutputexe yoursource.cpp` – David C. Rankin Jul 15 '20 at 08:44
  • 1
    For example, I had the source in `llwords.cpp` and I compiled the code with `g++ -Wall -Wextra -pedantic -Wshadow -std=gnu++11 -Ofast -o bin/llwords llwords.cpp` which placed my executable called `llwords` in the `bin` directory under the current directory (keeps the source directory clean) You can create it if it doesn't exist with `mkdir -p bin` The `-Wall -Wextra -pedantic -Wshadow` enable (almost) full warnings -- you should compile with warnings enabled every time -- and don't accept code until it compiles without warning. – David C. Rankin Jul 15 '20 at 08:47
  • 1
    GNU hides the C++ `-std=` options under the same options for C, [3.4 Options Controlling C Dialect](https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#C-Dialect-Options). For all options, see [3.1 Option Summary](https://gcc.gnu.org/onlinedocs/gcc/Option-Summary.html) `-Ofast` (that's Oh-fast) is simply full optimization, the `fast` optimization became available with gcc 4.6, before that you had the standard optimization levels `-O0` (no optimization) to `-O3` full optimization. `fast` just gives the compiler a bit more freedom to optimize than `-O3` does. – David C. Rankin Jul 15 '20 at 08:54
  • iam not familiar with the compiler of c++ i am not advance now i missed – black snow Jul 15 '20 at 10:45
  • i solved -std=c++11 thanks but now it returns nothing the program is not returning anything i do not know how do you put the file – black snow Jul 15 '20 at 10:58
  • oh i understood you are using linux and running it from terminal please i am using linux – black snow Jul 15 '20 at 11:00
  • You pass the filename as he 1st argument to the program. So if you want to read and store the lines in the file `file.txt`, you run `./yourprogram file.txt` and it will read all words from `file.txt`. You never want to hard-code filenames. You pass them as a parameter to `main()` or take the filename to open as user-input. That way you do not have to re-compile your code every time you want to read a new file. – David C. Rankin Jul 15 '20 at 18:01