3

I'm building a text editor using doubly linked lists. These are my structs:

#define N 4
typedef struct node
{
    char data[N];
    int size;
    struct node* next;
    struct node* prev;
}node;

typedef struct text
{
    struct node* head;
    struct node* tail;
    int count;
    int size;
}text;

This is the piece of code that I use to fill the first node.

void push_text (text * t, char * s)
{
    int i;
    int len = strlen(s);
    node *newnode, *nextnode, *head;

    newnode = create_node();
    t->count++;
    head = newnode;
    for (i=0; i<len; i++)
    {
        if (newnode->size < 4)
        {
            newnode->data[newnode->size] = s[i];
            newnode->size++;
        }
    .
    .
    .

When I print the node through printf or through the debugger the output is 4 chars long, as expected. Note that, I print it as soon as the first node is filled so the problem lies in this piece of code. However, when I use strlen(newnode->data) I get an output of 5. This is causing me many problems later on.

What's wrong here?

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
user3484582
  • 557
  • 1
  • 6
  • 22

3 Answers3

13

You are not copying the nul terminator, a c string needs a '\0' at the end, so if it has 4 characters it uses 5 bytes, the last one being '\0' which is not copied in your loop.

You should however use strcpy() instead of copying they bytes one by one in a loop.

The strlen() function scans the bytes until it finds the '\0', so the missing '\0' is causing the Wrong Value!, also that's a reason not to call strlen() in a loop, which is a very common mistake.

Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97
  • Should I also change `N`, the length of the data string to 5 then and add the `\0` at the end of the string? Cause I want my `node->data` string to hold 4 `char`s exactly. – user3484582 May 26 '15 at 13:19
  • Yes exactly, that's what it means, and don't forget to copy the `'\0'` every time you copy the string. – Iharob Al Asimi May 26 '15 at 13:19
  • The thing is I want to split the string `s` into strings of 4 `char`s. How could I proceed about doing that without a loop? Maybe use `strncpy`, but on the second iteration I won't be able to copy the `char`s left off. Any ideas? – user3484582 May 26 '15 at 13:26
  • No if you are processing each `char` by itself, a loop is good. – Iharob Al Asimi May 26 '15 at 15:22
7

You cannot put a four-character C string into a four-element array of char, because you need space for null terminator. Change all declarations of data to

char data[N+1];

You should also use N in place of constant 4 in expressions that expect the length to be less than N (e.g. newnode->size < N instead of newnode->size < 4).

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
-1

All the answers explained before were correct but no one explain the mistake.

With an example you will see better the mistake

node.data[0] = 'a';
node.data[1] = 'b';
node.data[2] = 'c';
node.data[3] = 'd';
node.datasize = 4;

In a little endian machine the memory will be filled in that way:

Hex value of 'a', 'b', 'c','d' coded in a byte and four bytes to code the int

Memory: 'a''b''c''d'4000

Then you will obtain...

strlen(node.data) --> 5
printf(node.data) --> abcd (plus 4 ascii code).
pepinomax
  • 1
  • 1