I have an array which I have to initialize into a list What I try to do
#include <stdio.h>
#include <string.h>
struct data_t
{
unsigned int id_;
char name_ [50];
};
struct node_t
{
node_t * next_;
data_t data_;
};
void initialize(node_t **, const char **, const unsigned int);
int main()
{
node_t * first = NULL;
const char * data [3] = {"Alpha", "Bravo", "Charlie"};
initialize(&first, data, 3);
return 0;
}
void initialize(node_t ** head, const char ** data, const unsigned int n) {
node_t * current = NULL;
node_t * previous = NULL;
for (size_t i = 0; i < n; i )
{
current = new node_t;
current->next_ = previous;
current->data_.id_ = i 1;
strcpy(current->data_.name_, data[i]);
if (i == 1)
{
*head = previous;
previous->next_ = current;
} else {
previous = current;
}
}
};
next_
just loops and changes between 2 values. I tried many different options but nothing works. Please help.
Why is this happening?
CodePudding user response:
You need to do something special in the case of 'first' vs 'not first', you knew this but had it wrong.
- On the first one (i==0) you need to set head so the caller gets the pointer to the first node
- on subsequent ones you have to set the prior ones next pointer to point at current. For the first one there is no prior
Plus you set the current->next
to point to previous
, thats wrong too, that made your loop
So this is what you need
for (size_t i = 0; i < n; i )
{
current = new node_t;
current->next_ = NULL; <<<======
current->data_.id_ = i 1;
strcpy(current->data_.name_, data[i]);
if (i == 0)
*head = current;
else
previous->next_ = current;
previous = current;
}
CodePudding user response:
Since you can't use std::string
s, I suggest that you add a constructor to data_t
that can copy the char
array:
struct data_t {
data_t(unsigned id, const char* name) :
id_{id} // can be copied automatically
{
// the char array needs to be copied manually:
std::strncpy(name_, name, sizeof name_ - 1);
name_[sizeof name_ - 1] = '\0';
}
unsigned int id_;
char name_[50];
};
With that, your initialize
function could be simplified to
// last in `data`, first in the list:
void initialize(node_t*& head, const char** data, const unsigned int n) {
for (unsigned int i = 0; i < n; i ) {
// create a new `node_t` with `next_` pointing at the current `head`
// `data_` will be initialized by calling the added constructor
// assign the returned `node_t` to `head`
head = new node_t{head, {i 1, data[i]}};
}
}
or
// first in `data`, first in the list:
void initialize(node_t*& head, const char** data, const unsigned int n) {
for (unsigned int i = n; i > 0; --i) {
head = new node_t{head, {i, data[i - 1]}};
}
}
Note that initialize
takes head
by reference (&
) to make calling it simpler:
int main() {
node_t* first = nullptr;
const char* data[3] = {"Alpha", "Bravo", "Charlie"};
initialize(first, data, 3); // not &first here
}