如何为字符串动态分配内存空间并从用户获取该字符串?

Din*_*esh 43 c string malloc memory-management dynamic

我想用C程序读取用户的输入.我不想使用数组,

char names[50];
Run Code Online (Sandbox Code Playgroud)

因为如果用户给出长度为10的字符串,那么剩余的空间就会被浪费掉.

如果我使用字符指针,

char *names;
Run Code Online (Sandbox Code Playgroud)

那么我需要以这样的方式为它分配内存,

names = (char *)malloc(20 * sizeof(char));
Run Code Online (Sandbox Code Playgroud)

在这种情况下,也存在内存浪费的可能性.

所以,我需要的是为字符串动态分配内存,该字符串与字符串的长度完全相同.

让我们假设,

如果用户输入是"stackoverflow",那么分配的内存应该是14(即字符串的长度= 13和'\ 0'的1个额外空间).

我怎么能实现这个目标?

cni*_*tar 43

一次读取一个字符(使用getc(stdin))并随时增长字符串(realloc).

这是我前段时间写的一个函数.请注意,它仅用于文本输入.

char *getln()
{
    char *line = NULL, *tmp = NULL;
    size_t size = 0, index = 0;
    int ch = EOF;

    while (ch) {
        ch = getc(stdin);

        /* Check if we need to stop. */
        if (ch == EOF || ch == '\n')
            ch = 0;

        /* Check if we need to expand. */
        if (size <= index) {
            size += CHUNK;
            tmp = realloc(line, size);
            if (!tmp) {
                free(line);
                line = NULL;
                break;
            }
            line = tmp;
        }

        /* Actually store the thing. */
        line[index++] = ch;
    }

    return line;
}
Run Code Online (Sandbox Code Playgroud)

  • 什么是"CHUNK"? (29认同)
  • 除非您知道您的数据来自固定大小的记录,否则通过乘法因子(即1.5倍或两倍大小)增加大小通常更有效. (9认同)

tek*_*agi 6

你可以有一个以10个元素开头的数组.逐字符读取输入.如果它结束,再重新分配另外5个.不是最好的,但是之后你可以释放其他空间.


Jyt*_*tug 6

您还可以使用正则表达式,例如以下代码:

char *names
scanf("%m[^\n]", &names)
Run Code Online (Sandbox Code Playgroud)

将从stdin获取整行,动态分配所需的空间量.在那之后,当然,你必须自由names.

  • `m``scanf`修饰符是非标准的.您的C库可能支持也可能不支持它. (4认同)

Big*_*ike 5

如果你应该节省内存,每次都要通过char和realloc读取char.性能会消失,但你会节省10个字节.

另一个很好的权衡是读入一个函数(使用局部变量)然后复制.所以大缓冲区将是功能范围.