Capturing a variable length string from the command-line in C

后端 未结 4 1619
耶瑟儿~
耶瑟儿~ 2021-01-16 06:03

I\'ve looked everywhere for an answer to my question, but I have yet to find a solid answer to my problem.

I\'m currently in the process of writing a program in C, s

4条回答
  •  暗喜
    暗喜 (楼主)
    2021-01-16 06:20

    I think the answer about assuming a maximum command length is the correct one: typically you'll want to keep commands within a reasonable length.

    But if you really can't make assumptions about the maximum length of a command, then you'll need to buffer.

    Keep:

    • a fixed buffer that you always fgets the same number of characters into, and
    • a command that you append to, and realloc when necessary.

    The following code probably lacks some error handling:

    #define BUFFER_SIZE 20
    #define COMMAND_BLOCK_SIZE 50
    
    void get_command()
    {
        char *buffer = malloc(sizeof(char) * (BUFFER_SIZE + 1));
    
        char *command = malloc(sizeof(char) * (COMMAND_BLOCK_SIZE + 1));
        int commandSize = 50;
    
        // tmp pointer for realloc:
        char *tmp = NULL;
        char *retval = NULL;
    
        if ((buffer == NULL) || (command == NULL))
            return_error("Error allocating memory");
    
        retval = fgets(buffer, BUFFER_SIZE, stdin);
    
        while (retval != NULL)
        {
            if (strlen(buffer) + strlen(command) > commandSize)
            {
                tmp = realloc(command, commandSize + (COMMAND_BLOCK_SIZE + 1));
                if (tmp == NULL)
                    return_error("Error allocating memory");
                else
                {
                     command = tmp;
                     commandSize += COMMAND_BLOCK_SIZE;
                }
            }
    
            // not using strncat because the check above should guarantee that
            //    we always have more than BUFFER_SIZE more bytes in command 
            strcat(command, buffer);
    
            if (buffer[strlen(buffer) - 1] == '\n')
                break;
    
            retval = fgets(buffer, BUFFER_SIZE, stdin);
        }
    
        printf("COMMAND: %s\n", command);
        free(buffer);
    }
    

    Also note that:

    • we don't do anything useful with command there, you'll probably want to pass in a char ** so that you can get command out of this function, and free it in the calling code, e.g. in your main loop.
    • that the '\n' is retained in command: you may want to discard that.

提交回复
热议问题