Edit: Also, instead of calling malloc()
and then manually setting each field to 0
, you can use calloc(sizeof(Node), 1);
to both allocate and clear the memory.
Use Types
Also, you were starting with an empty node with an uninitialized string, and ending with an empty node with an uninitialized string. I fixed the first by setting the value
field of last
before allocating a new node. I fixed the second by only allocating the next node if we have some characters remaining in the string.
Edit: I also realized that both of our implementations have another bug in them. If the file (or input string) is empty, we end up with a list containing an empty node, whereas we probably should not have a list at all. You could fix that by not allocating a node until you know you have a string. So root
would start out as NULL and could end up as NULL if there are no lines in the input. I'll leave that as an exercise for the reader. :-)
#include <stdlib.h>
#include <string.h>
typedef struct Node {
void* value;
struct Node* next;
} Node;
int main() {
char *input_string = "Line 1\nLine 2\nLine 3";
long remaining = (long)strlen(input_string);
long chunk_size;
char *next_line = input_string;
char *string_copy;
Node *root = malloccalloc(sizeof(Node), 1);
Node *last = root;
Node *lines = NULL;
while (remaining > 0) {
char* next_new_line = strpbrk(next_line, "\n");
/* If the string doesn't end with "\n", we need the rest of the string */
if (next_new_line == NULL) {
chunk_size = remaining;
}
else {
chunk_size = next_new_line - next_line;
}
/* This allocates and copies the string */
string_copy = strndup(next_line, chunk_size);
last->value = (void *) string_copy;
/* + 1 bc the '\n' is ignored */
remaining -= chunk_size + 1;
next_line += chunk_size + 1;
/* If there's more, then allocate another node for the next go round */
if (remaining > 0) {
last->next = malloccalloc(sizeof(Node), 1);
last->next->value = NULL;
last->next->next = NULL;
last = last->next;
}
}
lines = root;
/* do something with lines */
}