cstringc-strings

printf() is printing a character after the terminating character in C, how do I fix this?


I have a for loop in randomString() that puts a random character into the first x indexes of a string, where x < the string length. I then add a '\0' to the string and print it with printf() but it prints 1 more character than x and that character is always the same, I don't know why.

This is the code that I have:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

#define NELEMS(x) sizeof(x)/sizeof(x[0])
#define MAX_LENGTH 25

void randomChar();
void randomString();

int main()
{
    srand(time(NULL));
    int points = 0;

    randomString(&points, 3);

    return EXIT_SUCCESS;
}

void randomString(int *points, int length)
{    
    char input[MAX_LENGTH], output[MAX_LENGTH];
    do
    {
        int i;
        for (i = 0; i < length && i < NELEMS(output)-1; i++)
            output[i] = (char)(rand() % 26 + 97);
        output[i+1] = '\0';
        //output[i+2] = '\0';

        // for (int i = 0; i < NELEMS(output)-1; i++)
        //     output[i] = i < length ? (char)(rand() % 26 + 97) : '\0';

        
        printf("You have %d points, type %s:\n", *points, output);
        scanf("%s", &input);

        strcmp(input, output) == 0 ? *(points)++ : *(points)--;        
        getchar();
    } while (input[0] != '@');
}

I have been trying this function with a length of 3 and get a result:

You have 0 points, type opc♦:
a
You have 0 points, type lbu♦:
a
You have 14488832 points, type wal♦:
 

using output[i+1] = '\0' and output[i+2] = '\0' don't fix anything the commented out for loop works but I don't know why the first one isn't working

Do you know why its printing an extra character?

oh and if you know why 14488832 appears in the output i'd like to know that aswell.

EDIT:

dbush fixed the pointer bug with (*points)++ instead of *(points)++ but the first bug with printing another character after the 3 letter string like the following is still there:

You have 0 points, type opc♦:
a
You have 0 points, type lbu♦:


Solution

  • When you're building the string:

        for (i = 0; i < length && i < NELEMS(output)-1; i++)
            output[i] = (char)(rand() % 26 + 97);
        output[i+1] = '\0';
    

    A for loop performs the increment step first, then checks the condition. This means that i has been incremented one more time when the loop exits, so using i+1 as the loop index for the terminating character skips one. You need to use i instead:

        output[i] = '\0';
    

    As for the strange numbers in the output here's your problem:

    strcmp(input, output) == 0 ? *(points)++ : *(points)--; 
    

    You're incrementing / decrementing the pointer points instead what it points to. As a result, you're stepping on memory you shouldn't be which triggers undefined behavior.

    To increment / decrement what points points to, move the parenthesis to dereference first.

    strcmp(input, output) == 0 ? (*points)++ : (*points)--;