Search code examples
cpointersfgets

Can't understand the fgets output


In this code I'm letting the users enter how many characters they want to input.

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

int main(void) {

    // Ask the user to enter how many characters you want to write.
    printf("Enter how many characters you want to write. \n");
    int n;
    int itemsRead = scanf_s("%d", &n);

    if (itemsRead != 1) {
        // scanf didn't read the expected input, handle the error
        printf("Error: Input is not in the expected format.\n");
        return 1; // Return a non-zero value to indicate an error
    }
    
    // Clear the input buffer
    int c;
    while ((c = getchar()) != '\n' && c != EOF);

    char *string = NULL;
    string = (char *)malloc(n * sizeof(char));

    if (string != NULL) {
        printf("Enter the string \n");
        fgets(string, n, stdin);
        printf("string is: %s\n", string);
    }

    free(string);
    string = NULL;
}

The problem is: if the user enters 3 characters and subsequently tries to enter 3 characters it only displays the first 2 characters.


Solution

  • Consult the fgets documentation.

    Reads at most count - 1 characters from the given file stream and stores them in the character array pointed to by str. Parsing stops if a newline character is found, in which case str will contain that newline character, or if end-of-file occurs. If bytes are read and no errors occur, writes a null character at the position immediately after the last character written to str.

    Your call is reading at most n-1 characters. A char array with room for three bytes can only hold a string with two characters owing to the need for a null terminator to make it a valid string.

    #include<stdlib.h>
    #include<stdio.h>
    #include<string.h>
    
    int main(void) {
        // Ask the user to enter how many characters you want to write.
        printf("Enter how many characters you want to write. \n");
        int n;
        int itemsRead = scanf_s("%d", &n);
    
        if (itemsRead != 1) {
            // scanf didn't read the expected input, handle the error
            printf("Error: Input is not in the expected format.\n");
            return 1; // Return a non-zero value to indicate an error
        }
    
        // Increment n by one to allow for the null terminator.
        ++n;
        
        // Clear the input buffer
        int c;
        while ((c = getchar()) != '\n' && c != EOF);
    
        char* string = NULL;
        string = (char*)malloc(n * sizeof(char));
        // Equivalent to:
        // string = (char*)malloc(n);
        // Because sizeof(char) == 1
    
        if (string != NULL) {
            printf("Enter the string \n");
            fgets(string, n, stdin);
            printf("string is: %s\n", string);
        }
    
        free(string);
        string = NULL;
    }