简体   繁体   中英

Reading arbitrary length strings in C

I've attempted to write a C program to read a string and display it back to the user. I've tested it with a lot of input and it seems to work properly. The thing is that I'm not sure whether or not the c != EOF condition is necessary inside the while expression, and since by definition, the size of a char is 1 byte, maybe I can remove the sizeof(char) expressions inside the malloc and realloc statements, but I'm not sure about this.

Here's the program, also, I manually added a null terminating character to the string:

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

int main(void)
{
    char *str = malloc(sizeof(char));

    if (!str)
        return 1;

    char c;
    char *reallocStr;
    size_t len = 0;
    size_t buf = 1;

    printf("Enter some text: ");

    while ((c = getchar()) != '\n' && c != EOF) {
        if (len == buf) {
            buf *= 2;

            reallocStr = realloc(str, buf * sizeof(char));

            if (!reallocStr)
                return 1;

            str = reallocStr;
        }

        str[len++] = c;
    }

    str[len] = '\0';

    printf("You entered: %s\n", str);

    free(str);
    
    return 0;
}

As mentioned in the comments, you have a buffer overflow in your code, so you would need to fix that at the very least. To answer your specific questions, sizeof(char) is guaranteed to be 1 (dictated by the c99 spec), so you don't need to multiply by sizeof(char) . It's good practice to check for EOF as if your input is coming from an alternate source that has no newline, you don't die (so if someone for example did printf %s hello | yourprogram from a bash prompt, you wouldn't die).

Problems include

Buffer overflow

@HardcoreHenry

Incorrect type

getchar() reruns an int with the values [0..UCHAR_MAX] and the negative: EOF . These 257 different values lose distinctiveness when saved as a char . Possible outcomes: infinite loop or premature loop end. Instead:

// char c;
int c;

Advanced: Arbitrary length

For very long lines buf *= 2; overflows when buf is SIZE_MAX/2 + 1 . An alterative to growing in steps of 1, 2, 4, 8, 16,..., consider 1, 3, 7, 15, .... That way code can handle strings up to SIZE_MAX .

Advanced: Reading '\0'

Although uncommon, possible to read in a null character . Then printf("You entered: %s\n", str); will only print to that null character and not to the end of input.

To print all, take advantage that code knows the length.

printf("You entered: ");
fwrite(str, len, 1, stdout);
printf("\n"); 

To be clear, text input here is not reading of strings , but of reading of lines . That input is saved and converted to a string by appending a null character . Reading a '\0' complicates things, but something robust code handles.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM