我在字符串中遇到问题,在使用 c 语言的 gets 函数时

I have problem in string, in using the gets function, in c language

我对c语言的字符串有问题 我们知道,字符串被称为空终止字符**数组,在字符串中,我们声明了这个字符串存储了多少个字符。字符的内存为1byte。当我们声明 char name[5];这意味着字符串存储至少 4 个字符值和空值。

但是 strong text gets 函数有问题。 当我们输入包含超过 5 个字符的名称时,它会被接受并打印所有字符。在这种情况下,编译器不会抛出警告。

请告诉我解决方法....... 代码如下。

#include<stdio.h>

int main()
{
    char name[4]="smti prajapati";

    printf("Print the name througth the initilizing : ");
    puts(name);


    printf("Enter the name : ");
    gets(name);
    printf("Print the name througth the user : ");
    puts(name);

    return 0;
}

在终端程序中出现类似这样的错误

rough.c: In function 'main':
rough.c:5:18: ***warning: initializer-string for array of chars is too long***
     char name[1]="smti prajapati";
                  ^~~~~~~~~~~~~~~~
Print the name througth the initilizing : s3
Enter the name : smit prajapati
Print the name througth the user : smit prajapati

当您在 C 中使用数组时,您使用的是固定内存 space。如果我想保存“Hello World!”在内存中,我必须保留一个长度为 13 的数组。在 C 中它看起来是:

char aString[13] = "Hello World!"

它可能高达 20,但不会低于 13。为什么?字符串有我们关心的字符,最后一个是空字符(它的值为 0)。所以,您需要预留十三个字符。

在您的代码中,您只保留了 1 个字节(1 个字符)。至少,你得预留15个字节。

试试这个代码:

#include<stdio.h>

int main()
{
    char name[15]="smti prajapati";

    printf("Print the name througth the initilizing : ");
    puts(name);


    printf("Enter the name : ");
    gets(name);
    printf("Print the name througth the user : ");
    puts(name);

    return 0;
}

我编译代码没有问题。此外,您可以不指定长度,它会正常工作。最好的解决方案是动态内存。避免获取()。它有安全问题。相反,使用 fgets().

声明和赋值:

char name[1] = "smti prajapati";

永远无法工作,因为您将一个包含 14 个字符的字符串加上空字节分配给一个只有 space 个字符的 char 数组。

你没有收到一些格式错误的代码的错误或警告的原因可以解释为 C 给程序员的余地,编译器没有被强制发出警告,因为某些类型的格式错误的代码像你自己的,这属于 undefined behavior 的范畴,程序员应该避免它。

您可以使用:

char name[] = "smti prajapati";

这样数组的大小会在初始化时推导出来。

或者如果您想明确使用尺寸:

char name[15] = "smti prajapati";

请注意,我为空字节添加了一个额外的 space,如果您想将 name 作为适当的字符串处理,则必须这样做。另请注意,一旦为 char 数组指定大小,它就不会更改,因此当您将其他字符串存储在 name 中时,请记住这一点。


另一个问题是gets,你不应该使用它,这是一个非常危险的函数,它不检查目标缓冲区的边界,因此很容易导致缓冲区溢出并且can cause all kinds of trouble.最近的编译器甚至不再支持它,因为它已被弃用,后来从 C 标准中删除。

即使那些仍然支持它的人也经常发出类似于以下的警告:

warning: the `gets' function is dangerous and should not be used.

Here are two examples 两个现代编译器的输出结果。

总结总结,改用fgets

fgets(name, sizeof name, stdin);

您已声明 name 数组只有一个元素;它不够大,无法容纳字符串 "smti prajapati" 的内容。您需要将 name 声明为 至少 15 个元素宽 - 字符串中的 14 个字符加上零终止符。

可以省略声明中的尺寸,写

char name[] = "smti prajapati";

并且数组大小将从初始化程序的大小中获取。

注意 name 的大小在定义后是固定的,并且不能存储比初始值设定项更长的字符串。

不要使用gets;如果你输入的字符串对于数组来说太长,它会将这些额外的字符写入数组后面的任何内容。这称为缓冲区溢出,可能导致数据损坏、运行时错误或跳转到程序中的随机位置等任何问题。缓冲区溢出是一种常见的恶意软件攻击。请改用 fgets,因为它允许您限制写入目标的字符数。

你的误解有很多。让我们按顺序来看。

in the c language we know, the string is known as a null-terminated character** array

在 C 中,字符串是 char 的空终止数组。使用字符指针 char * 来引用字符串是很常见的。当你说“字符**”时,它可能是一个错字,但类型 char ** 是一个指向指针的指针,这是另外一回事。

when we declare char name[5]; it means the string store at least 4 characters value and null value.

正确。

char name[1]="smti prajapati";

这是不正确的。您的编译器正确警告您:warning: initializer-string for array of chars is too long

when we have entered a name that contains more than 5 characters it is accepted and prints all characters.

没错。有时,当您违反规则时,您会逃脱惩罚。

In this case, the compiler does not throw the warning.

没错。 C 并不总是检测或抱怨缓冲区溢出。一般来说,有责任确保为您的数组分配足够大的空间以容纳您尝试在其中存储的字符串。