简体   繁体   English

使用 scanf 将输入输入读入 char 指针

[英]Reading input input into a char pointer with scanf

What I want to do here is, I want to read input from a user with scanf into a char pointer and dynamically allocate memory as more input is read.我想在这里做的是,我想用 scanf 将用户的输入读入 char 指针,并在读取更多输入时动态分配 memory。

#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;
}

My code is like this, however it either throws a segmentation error (when the number of character in one line is more than 8) or does not even print any characters.我的代码是这样的,但是它要么引发分段错误(当一行中的字符数超过 8 个时),要么甚至不打印任何字符。 What am I missing?我错过了什么? Thanks in advance.提前致谢。

scanf(" %[^\n]c", &temp) does not read a character that is not a new-line ( '\n' ). scanf(" %[^\n]c", &temp)不会读取不是换行符 ( '\n' ) 的字符。 The [ is a conversion specifier by itself, and c does not go with it. [本身是一个转换说明符, c不包含 go 。

%[^\n] says to read any number of characters until a new-line is seen. %[^\n]表示读取任意数量的字符,直到看到换行符。 The c is not part of the conversion, and its presence causes a matching failure in scanf . c不是转换的一部分,它的存在会导致scanf中的匹配失败。

To read one character that is not a new-line character, use %1[^\n] , as in scanf(" %1[^\n]", &temp);要读取一个不是换行符的字符,请使用%1[^\n] ,如scanf(" %1[^\n]", &temp);

Another solutions are:另一个解决方案是:

  • Use %c in the scanf.在 scanf 中使用%c Afterward, test the character and ignore it if it is a new-line character.之后,测试该字符,如果它是换行符则忽略它。
  • Change the code to use getchar instead of scanf .更改代码以使用getchar而不是scanf

Avoid testing with scanf(...) != EOF .避免使用scanf(...) != EOF进行测试。 scanf returns EOF only if an input failure occurs before the first conversion has completed.只有在第一次转换完成之前发生输入故障时, scanf才会返回EOF Otherwise, it returns the number of input items assigned.否则,它返回分配的输入项数。 This may work in simple uses of scanf with only one item to assign.这可能适用于scanf的简单使用,只有一项要分配。 However, in general, you want to at least test whether scanf assigned the desired number of items, scanf(...) == 1 .但是,通常,您至少要测试scanf是否分配了所需数量的项目scanf(...) == 1 Even better would be to save the return value and handle the multiple possible returns: EOF , a number less than the desired number of items, or the desired number of items.更好的是保存返回值并处理多个可能的返回: EOF ,小于所需项目数的数字,或所需的项目数。

Adding to Eric's answer, your code could be better without scanf() .添加到 Eric 的答案中,如果没有scanf() ,您的代码可能会更好。 Here is a getchar() solution:这是一个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;
}

I would like add that multiple realloc() calls, isn't really a sufficient practice.我想补充一点,多次realloc()调用,实际上并不是一个足够的做法。 The better approach, would be initially allocate an X amount of memory with malloc() and if you need more, then use realloc() with an appropriate size.更好的方法是,最初使用malloc()分配X数量的 memory,如果需要更多,则使用适当大小的realloc()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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