1

I am trying to solve this exercise but I couldn't find my errors.. The exercise asked us to manipulate a positive integer of any size. For this purpose, we choose a representation in the form of a simply linked list of numbers by storing the low weights number first.

I am asked to complete the lecture_nombre and display_nombre function.... However, the problem is in the main, the program did not enter the if( n != nullptr ) loop.

Here's my code:

#include <iostream>
#include <cctype>
#include <fstream>
using namespace std;

struct Chiffre {
    unsigned int chiffre_;   /**< single number between 0 et 9 */
    Chiffre * suivant_;      /**< pointer towards the next number with a heavier weight (for example 2 for 25 ou nullptr */
};

typedef Chiffre* Nombre;
void insertNode(unsigned int n, Nombre head, Nombre tail);
Nombre lecture_nombre( std::istream & in );
void display_nombre( Nombre n, std::ostream & out );

// The main is given by the teacher
int main(){
    while( true ) {
        Nombre n = lecture_nombre( std::cin );
        if( n != nullptr ) {
            std::cout << "lu : ";
            display_nombre( n, std::cout );
            std::cout << "\n";
            //detruit_nombre( n );
        }
        else break;
    }
    return 0;
}
 // d is a single digit number and I have to add it into the chained list and return the results
    Nombre lecture_nombre( std::istream & in )
    {
    *//Nombre res = nullptr;
    Nombre head = nullptr;
    Nombre tail = nullptr;

    while( in.good() ) {
        char c = in.get();
        if( std::isdigit( c )) {
            unsigned int d = c - '0';
            // my code starts here :
            insertNode(d,head,tail);

        }
        else break;
    }
    return head;
}
// my code starts here
void insertNode(unsigned int n, Nombre head, Nombre tail){
    struct Chiffre *newChiffre = new Chiffre;
    newChiffre->chiffre_ = n;
    newChiffre->suivant_ = nullptr;
    cout << "Insert Node :" << newChiffre->chiffre_ << endl;
    if (head==nullptr){
        head = newChiffre;
        tail = newChiffre;
    }else{
        tail->suivant_ = newChiffre;
        tail = tail->suivant_;
    }
}

void display_number( Nombre n, std::ostream & out ){
    if(n==nullptr){
        cout << n << endl;
    }else{
        cout << n->chiffre_ <<endl;
        display_number(n->suivant_,out);
    }
}

I verified that the nodes are created but I can't display the number, the program took n as nullptr so it never went into the if( n != nullptr ) loop...

Vlad from Moscow
  • 224,104
  • 15
  • 141
  • 268
rocknoos
  • 35
  • 4
  • Where is the problematic code? Could you perhaps try to minimize the code to only the parts needed to replicate the problem (i.e. create a [mcve] to show us)? Also make sure that the code you show us only replicates the problem you ask about and doesn't contain any unrelated errors (your shown code does), and preferably doesn't need any external data (like files) to work (hard-code the data if you need to). – Some programmer dude Sep 16 '19 at 13:40
  • On an unrelated note, please read [Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons) Doing `while (in.good())` is just as bad. – Some programmer dude Sep 16 '19 at 13:42
  • By the way, I think you should read a chapter in your text-book about *references* and how to *pass arguments by reference*. Perhaps even take a step back and read about passing of arguments in general. – Some programmer dude Sep 16 '19 at 13:43
  • in the main, I don't understand why n is always equals to nullptr... – rocknoos Sep 16 '19 at 13:43
  • C-shaped C++ and pointers hiding behind typedefs, yum – Quentin Sep 16 '19 at 13:44
  • If the pointer typedef is not required by the exercise, I recommend you remove it. It makes it harder to see any pointer problems in the code. – hyde Sep 16 '19 at 13:44
  • Additionally, use smart pointers if possible (or, if this is Turbo C++, add that tag to let people know...). – hyde Sep 16 '19 at 13:45
  • @hyde It's probably not, given the `.h`-free header names ... – L. F. Sep 16 '19 at 13:46
  • 1
    @hyde the typedef is given by the teacher and we're asked to complete the lecture_nombre and display_nombre function... – rocknoos Sep 16 '19 at 13:47

2 Answers2

2

The parameters of the function insertNode are local variables of the function that are initialized by copies of the values of the original arguments. Changing a copy of an object does not influence on the value of the original object.

So declare the parameters as having referenced types as for example

void insertNode(unsigned int n, Nombre &head, Nombre &tail){
    struct Chiffre *newChiffre = new Chiffre;
    newChiffre->chiffre_ = n;
    newChiffre->suivant_ = nullptr;
    cout << "Insert Node :" << newChiffre->chiffre_ << endl;
    if (head==nullptr){
        head = newChiffre;
        tail = newChiffre;
    }else{
        tail->suivant_ = newChiffre;
        tail = tail->suivant_;
    }
}

Also the function display_number does not use its parameter out. It can be defined the following way as it is shown in thg demonstrative program

#include <iostream>

struct Chiffre {
    unsigned int chiffre_;   /**< single number between 0 et 9 */
    Chiffre * suivant_;      /**< pointer towards the next number with a heavier weight (for example 2 for 25 ou nullptr */
};

typedef Chiffre* Nombre;

void insertNode(unsigned int n, Nombre &head, Nombre &tail)
{
    if ( head == nullptr )
    {
        head = tail = new Chiffre { n, nullptr };
    }
    else
    {
        tail = tail->suivant_ = new Chiffre { n, nullptr };
    }
}

std::ostream & display_number( Nombre n, std::ostream &out = std::cout )
{
    if ( n == nullptr )
    {
        return out << "nullptr";
    }
    else
    {
        out << n->chiffre_ << " -> ";
        return display_number( n->suivant_, out );
    }
}

int main() 
{
    Nombre head = nullptr, tail = nullptr;
    const int N = 10;

    for ( int i = 0; i < N; i++ ) insertNode( i, head, tail );

    display_number( head ) << '\n';

    return 0;
}

The program output

0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> nullptr
Vlad from Moscow
  • 224,104
  • 15
  • 141
  • 268
1

You do

void insertNode(unsigned int n, Nombre head, Nombre tail){

But nombre is typedef as Chiffre*. In this function you then set

head = newChiffre

This will not be reflected in the calling function. You pass a pointer, then changed the pointer to point elsewhere. It is normal that head stays null in the calling code.

Potential fixes include receiving a Nombre &head and Nombre &tail. But yikes. typedefs of pointers don't make for easy code to read.

Jeffrey
  • 7,814
  • 1
  • 16
  • 32
  • should I make head Nombre ? head Nombre = new Nombre? – rocknoos Sep 16 '19 at 13:51
  • nah, simplest fix from here is passing and receiving `Nombre` reference. (Ant BTW, next time, translate identifiers to english, will give you better answers, faster. I'm native french and yet bilingual code is somewhat annoying) – Jeffrey Sep 16 '19 at 13:53
  • okay noted ! btw, the code is now displaying an extra 0 in the end, is it because of the display_number? example ; input : 25 , output : 250 – rocknoos Sep 16 '19 at 14:00
  • What do you think this line does? `if(n==nullptr){ cout << n << endl; }` :-) – Jeffrey Sep 16 '19 at 14:03
  • Hahah omgg, it added a 0 because of the nullptr. Thanks !!!! – rocknoos Sep 16 '19 at 14:10
  • Remember to upvote useful answers, like Vlad's. – Jeffrey Sep 16 '19 at 14:11