用%[^/n]扫描一个没有已知极限的字符串。

问题描述 投票:-1回答:1

在一个uni作业中,我必须捕获一个字符串(以后会是一个命令)。老师建议使用fgets,但由于我不知道限制,我决定使用scanf。

问题是,它的priting不对。

这是我的测试代码。

int main()
{
    char *name1;
    printf("go:");
    scanf(" %[^\n]", name1);
    printf("%s xx %s", name1);
}

如果你有任何关于fgets的建议,那就太好了!

c scanf fgets
1个回答
0
投票

如果你是为PC编程(而不是为一些嵌入式设备),只需分配一个 真正的大缓冲区 (例如,1 MB,或10,或100),你确信它能满足所有可以想象的使用情况。现在的内存是非常便宜的,为了节省内存而花费资源和复杂的程序是不值得的。举个例子。你需要多长时间才能100%确定 David的解决方案完全没有错误?I 可能 如果在生产代码中使用的话,我想为它写一个测试)。)

不过要动态或静态分配内存,自动变量的堆栈空间可能还是有限的。然后使用fgets。不过,一定要优雅地处理过长的行。没有必要像David的答案那样,将它们从分块中连接起来。这些长行要么是测试用例,要么是数据错误。你可以简单地用错误信息退出。如果你想满足David Ranieri的良好秩序感和原则,你也可以显式地释放任何分配的内存,尽管在PC上这完全是多余的)。


1
投票

在标准的C库中,没有任何函数可以安全地读取一个无边界的字符串。这是我亲手写的一个函数(不能保证它有所有的安全功能,我试着加入了我想到的东西)。

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

char* get_string(FILE* stream)
{
    #define INITIAL_BUF_SIZE 100
    size_t size = INITIAL_BUF_SIZE, i = 0;
    int c;
    char* s = malloc(size * sizeof *s);
    if (s == NULL)
        return NULL;
    while ((c = getc(stream)) != '\n' && c != EOF)
    {
        s[i++] = c;
        if (i == size)
        {
            size *= 2;
            char* p = realloc(s, size * sizeof *p);
            if (p == NULL)
            {
                free(s);
                return NULL;
            }
            s = p;
        }
    }
    s[i++] = '\0';
    if (i == size)
        return s;
    char* p = realloc(s, i * sizeof *p);
    if (p == NULL)
    {
        free(s);
        return NULL;
    }
    return p;
    #undef INITIAL_BUF_SIZE
}

int main(void)
{
    char* name1 = get_string(stdin);
    printf("The string is: %s\n", name1);
    free(name1);
}

请注意,返回的字符串必须由调用者使用 free() 以避免内存泄漏。

© www.soinside.com 2019 - 2024. All rights reserved.