问题描述
我在c语言中遇到字符串问题 我们知道,字符串被称为以空字符结尾的字符**数组,在字符串中,我们声明这个字符串存储了多少个字符。字符的内存为1byte。当我们声明字符名称[5]时;表示字符串至少存储 4 个字符的值和空值。
但是强文本的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
解决方法
您已将 name
数组声明为具有单个元素;它不足以容纳字符串 "smti prajapati"
的内容。您需要将 name
声明为 至少 15 个元素宽 - 字符串中的 14 个字符加上零终止符。
可以省略声明中的大小而写
char name[] = "smti prajapati";
并且数组大小将取自初始化程序的大小。
注意 name
的大小在定义后就固定了,不能存储比初始化器长的字符串。
不要使用gets
;如果您输入的字符串对于数组来说太长,它会将这些额外的字符写入数组后面的任何内容。这称为缓冲区溢出,可能导致数据损坏、运行时错误或分支到程序中的随机位置等任何事情。缓冲区溢出是一种常见的恶意软件利用。请改用 fgets
,因为它允许您限制写入目标的字符数。
声明和赋值:
char name[1] = "smti prajapati";
永远无法工作,因为您将一个包含 14 个字符的字符串加上空字节分配给一个只有 1 个字符的空间的 char 数组。
对于某些格式错误的代码,您没有收到错误或警告的原因可以通过 C 给程序员的余地来解释,由于某些类型的格式错误的代码,例如您的自己的,这属于 undefined behavior 的类别,由程序员来避免。
您可以使用:
char name[] = "smti prajapati";
这样初始化时会推导出数组的大小。
或者如果你想明确使用一个尺寸:
char name[15] = "smti prajapati";
请注意,我为空字节添加了一个额外的空间,如果您想将 name
作为正确的字符串处理,这是强制性的。另请注意,一旦为 char 数组指定了大小,它就不会改变,因此当您在 name
中存储其他字符串时,请记住这一点。
另一个问题是gets
,你永远不应该使用它,这是一个非常危险的函数,它不检查目标缓冲区的边界,因此很容易导致缓冲区溢出,而can cause all kinds of trouble .最近的编译器甚至不再支持它,因为它已被弃用,后来从 C 标准中删除。
即使那些仍然支持它的人也经常发出类似于以下内容的警告:
警告:`gets' 函数很危险,不应使用。
Here are two examples 两个现代编译器在使用时的输出。
总结和总结,改用fgets
:
fgets(name,sizeof name,stdin);
,
当您在 C 中使用数组时,您使用的是固定的内存空间。如果我想保存“Hello World!”在内存中,我必须保留一个长度为 13 的数组。在 C 中它看起来像:
char aString[13] = "Hello World!"
它可能高达 20,但不会低于 13。为什么?字符串具有我们关心的字符,最后一个是空字符(其值为 0)。因此,您需要保留 13 个字符。
在您的代码中,您只保留了 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;
}
我编译代码没有问题。此外,您可以不指定长度,它会正常工作。最好的解决方案是动态内存。避免gets()。它有安全问题。而是使用 fgets()。
,你有很多误解。让我们按顺序查看它们。
在我们知道的 c 语言中,字符串被称为空终止字符**数组
在 C 中,字符串是以空字符结尾的 char
数组。使用字符指针 char *
来引用字符串是很常见的。当您说“字符**”时可能是一个错字,但类型 char **
是一个指向指针的指针,这是别的东西。
当我们声明字符名[5]时;表示字符串至少存储 4 个字符的值和空值。
正确。
char name[1]="smti prajapati";
这是不正确的。您的编译器正确警告您:warning: initializer-string for array of chars is too long
当我们输入的名称包含超过 5 个字符时,它会被接受并打印所有字符。
没错。有时,当您违反规则时,您就可以逃脱惩罚。
在这种情况下,编译器不会抛出警告。
没错。 C 并不总是检测或抱怨缓冲区溢出。通常,您有责任确保为您的数组分配足够大的空间以容纳您尝试在其中存储的字符串。