如何在不知道C大小的情况下读取输入?

时间:2013-11-03 20:19:45

标签: c string input

我试图通过使用scanf运算符来获取输入,但我也需要它的长度,我无法定义char name[number],因为我不知道从用户获得的输入的大小。

如何在不使用string.h的情况下执行此操作?

这是我试图做的,但由于我定义了数组的长度,这是非法的:

char string1[30];
printf("Enter string1:");
scanf("%s",string1);

2 个答案:

答案 0 :(得分:3)

您可能无法知道用户的输入字符串将提前多长时间。所以你只能提供一些大小的缓冲区,并希望输入比那个大小短;如果输入太长,那么你的程序不会立即获得所有输入。

假设您提示用户输入他/她的名字。我的名字是"史蒂夫"所以我只需要5个字母,但其他名字更长。我刚刚在谷歌搜索了#34;最长的名字"我发现的一个例子是" Lydiakalanirowealeekundemondisha"这需要32个字母。好吧,让我们把输入缓冲区写成128个字母,并且可能已经足够长了。

#include <stdio.h>

char first_name[128];

printf("Please enter your first name: ");
fgets(first_name, sizeof(first_name), stdin);

所以我们在这里使用fgets()来获取用户输入。我们告诉fgets()将输入存储在缓冲区(first_name)中,然后告诉它缓冲区的大小。注意:我们在这里使用sizeof()运算符,以便在有人编辑文件并更改缓冲区大小时程序仍然正确。

现在,无论用户输入什么(或从剪贴板粘贴),我们的程序只会读取前127个字符。如果用户键入的内容少于此值,我们就可以获得所有内容。

现在我们可以检查一下我们得到了多少:

if (strlen(first_name) >= sizeof(first_name) - 1)
{
    printf("That input is too long, sorry.\n");
}

在这里,我们检查字符串实际上有多长。如果时间太长,我们会向用户发出错误消息。从理论上讲,用户可以输入正好127个字符并且输入完全匹配,但是我们无法知道用户输入的字符是否恰好是127个字符或更多。在实践中,我们不希望名字在任何地方接近那么久,因此将这种情况视为错误是安全的。

现在,这是不怎么做的。永远不要这样做。

char short_buffer[16];

printf("Please enter your first name: ");
gets(short_buffer);

函数gets()无法知道缓冲区中有多少个字符。如果用户键入&#34; Lydiakalanirowealeekundemondisha&#34;然后gets()将注销缓冲区的末尾并可能导致错误。切勿使用gets()

答案 1 :(得分:1)

如果没有定义最大尺寸,你可能不会相处。

不定义尺寸,但事后了解并尊重它并不重要。

获取用户输入的最简单方法是fgets()

char string1[50];
fgets(string1, sizeof string1, stdin);

当然,你应该检查它的返回值。

如果您想接受(差不多)任何长度,可以尝试the solution I gave here

这是防止给定阵列溢出所必需的。为了使用字符串,您可以使用strlen()使其长度枯萎,或者,如果您不允许使用它或者继续使用字符串,则通过计算字符直到您点击NUL字节为止。

这样做的背景是C中的字符串由NUL字节终止。它们是char s的序列,NUL字节(0,而不是'0'将是48)终止此序列。


如果您唯一的任务是验证您阅读的字符串是否足够小,并且如果不是,则进行投诉,那么就这样做: - )

int main(int argc, char ** argv)
{
    char string2[50]; // larger than required; in order to be able to check.
    char string1[30]; // if all is ok, you have maximum length of 29, plus the NUL terminator. So 30 is ok.
    char * ret = fgets(string2, sizeof string2, stdin);
    if (!ret) {
        fprintf(stderr, "Read error.\n")
        return 1; // indicate error
    }
    if (strlen(string2) >= sizeof string1) { // we can take this size as a reference...
        fprintf(stderr, "String 1 too long.\n")
        return 1; // indicate error
    }
    strcpy(string1, string2); // as we have verified that this will match, it is ok.
    // Otherwise, we would have to use strncpy.

    // Now read the 2nd string by the same way:
    ret = fgets(string2, sizeof string2, stdin);
    if (!ret) {
        fprintf(stderr, "Read error.\n")
        return 1; // indicate error
    }
    if (strlen(string2) >= sizeof string1) { // we can take this size as a reference...
        fprintf(stderr, "String 2 too long.\n")
        return 1; // indicate error
    }
    // Now we know that both strings are ok in length an we can use strcmp().
    int c = strcmp(string1, string2);
    printf("strcmp() result: %d.\n", c);
    return 0; // indicate success
}

我现在还不清楚你是否应该实施strcmp()。如果是这样的话,我会把它留作练习。