使用 scanf 将输入读入字符指针

Reading input input into a char pointer with scanf

我想在这里做的是,我想使用 scanf 将用户的输入读取到字符指针中,并在读取更多输入时动态分配内存。

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

int main()
{
    char *ptr, temp;
    int i, ind = 0;

    ptr = malloc(sizeof(char) * 2);

    while (scanf(" %[^\n]c", &temp) != EOF)
    {
        ptr[ind] = temp;
        ind++;
        ptr = realloc(ptr, sizeof(char) * (ind + 1));
    }

    for (i = 0; i < 5; i++)
        printf("%c", *(ptr + i));

    return 0;
}

我的代码是这样的,但是它要么抛出一个分段错误(当一行中的字符数超过 8 个时),要么甚至不打印任何字符。我错过了什么?提前致谢。

scanf(" %[^\n]c", &temp) 不读取非换行符 ('\n')。 [ 本身就是一个转换说明符,c 不与之匹配。

%[^\n] 表示读取任意数量的字符,直到看到换行符。 c 不是转换的一部分,它的存在会导致 scanf.

中的匹配失败

要读取一个不是换行符的字符,请使用 %1[^\n],如 scanf(" %1[^\n]", &temp);

另一种解决方案是:

  • 在 scanf 中使用 %c。然后测试字符,如果是换行符就忽略。
  • 更改代码以使用 getchar 而不是 scanf

避免使用 scanf(...) != EOF 进行测试。 scanf returns EOF 仅当输入失败发生在第一次转换完成之前。否则,它 returns 分配的输入项数。这可能适用于仅分配一项的 scanf 的简单使用。但是,一般来说,您至少要测试 scanf 是否分配了所需数量的项目 scanf(...) == 1。更好的方法是保存 return 值并处理多个可能的 returns:EOF,一个小于所需项目数或所需项目数的数字。

添加到 Eric 的回答中,如果没有 scanf(),您的代码可能会更好。这是一个 getchar() 解决方案:

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

int main(void)
{
    int c = 0; /* int so it can hold the EOF value */
    size_t ind = 0, i = 0;
    char *buff = NULL, *tmp = NULL;

    buff = malloc(2); /* sizeof char is 1 */

    if (buff == NULL) /* malloc failed */
    {
        exit(EXIT_FAILURE);
    }

    while (1)
    {
        c = getchar();

        if (c == EOF || c == '\n')
        {
            break;
        }

        buff[ind++] = (char)c; /* maybe check for overflow here, for non ascii characters */

        /* can use ctype functions or just manually compare with CHAR_MIN and CHAR_MAX */

        tmp = realloc(buff, ind + 2);

        if (tmp == NULL) /* reallloc failed */
        {
            fprintf(stderr,"Out of memory\n");
            exit(EXIT_FAILURE);
        }

        buff = tmp;
    }

    /* --------- NULL terminate if you are looking for a string  */

    /* buff[ind] = 0;                                            */

    /* --------------------------------------------------------- */

    for (; i < ind; i++)
    {
        putchar(*(buff + i));
    }

    free(buff);

    return 0;
}

我想补充一点,多次 realloc() 调用并不是一个足够的练习。更好的方法是,最初使用 malloc() 分配 X 内存量,如果您需要更多内存,则使用适当大小的 realloc()