[英]Why doesn't the following statement work?
今天我进行了测试,其中写下了以下问题,并且由于我是C ++的新手,所以我对以下问题感到困惑。
为什么以下语句不起作用?
char str[ ] = "Hello" ;
strcat ( str, '!' ) ;
char str[] = "Hello";
strcat (str, '!') ;
strcat
第二个参数必须是指向字符串的指针,但是您正在传递字符常量。
正确的调用应该是strcat(str, "!");
(请注意, "
而不是“ '
),但您还需要在str
保留足够大的空间,该空间仅足以容纳"Hello"
字符串。例如,对于您的测试,可以使用char str[64] = "Hello";
保留更多字节char str[64] = "Hello";
strcat()
调用两个参数的指针。
'!'
将以实现定义的方式转换为(很多机会无效)指针,然后程序可能因Segmentation Fault崩溃。
注意
char str[ ] = "Hello" ;
strcat ( str, "!" ) ;
由于缺乏缓冲,效果也不佳。
char str[ ] = "Hello" ;
strcat ( str, '!' ) ;
^^^ --- this is of type char
strcat的签名是:
char * strcat ( char * destination, const char * source );
^^^^^^^^^^^^^^^^^^^
因此,第二个参数的类型为const char*
而不是char
。 您必须传递字符串文字或const char*
类型的变量。 实际上,字符串文字的类型为const char[]
但在分配给它们时会衰减为const char*
。
strcat
函数需要两个字符串。 '!'
是一个角色。 为了安全地进行连接,您的数组必须足够大以容纳另一个字符串,因此请更改'!'
到"!"
,并且str[]
到str[8]
或更多。
int main(void)
{
char str[20] = "Hello" ;
strcat ( str, "!" ) ;
printf("%s\n",str);
}
两个问题:
直接的问题是第二个参数必须是const char*
。 strcat
从该位置开始读取内存,直到达到\\0
。 如果无法达到\\0
则功能行为未定义。
您需要确保str
足够大以接收串联的字符串。 如果不是,则行为是不确定的。
在第二点上,您可以编写类似char str[100] = "Hello";
这将保留100个字节的内存,并用Hello\\0
填充前6个元素。
您为什么决定这些陈述
char str[ ] = "Hello" ;
strcat ( str, '!' ) ;
不工作?:)
一切都取决于函数strcat
的定义方式。
例如,可以通过以下方式定义
char * strcat( char *s, char c )
{
size_t n = std::strlen( s );
if ( n ) s[n-1] = c;
return s;
}
或以下方式
char * strcat( char *s, char c )
{
size_t n = std::strlen( s );
char *t = new char[n + 2];
std::strcpy( t, s );
t[ n - 2 ] = c;
t[ n - 1 ] = '\0';
return t;
}
如果您的示例中的strcat
是标准的C函数std::strcat
那么这并不意味着该语句将不起作用。 这意味着带有此类语句的程序将不会编译,因为第二个参数的类型错误。
但是,如果像这样为第二个参数指定正确的值
strcat ( str, "!" ) ;
那是使用字符串文字而不是字符文字,那么实际上这些语句将无法正常工作,因为数组str
没有足够的空间来附加字符串文字"!"
。
数组至少应定义为
char str[7] = "Hello" ;
^^^
该函数应该像
strcat ( str, "!" ) ;
^^^
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.