我正在学习c ++,在博客中,他们介绍了复制功能的概念。当我在系统中尝试相同的结果时,结果与我期望的结果不匹配。请在下面的代码中告诉我我做错了什么。
#include <iostream>
main(){
std::string statement = "I like to work in Google";
char compName[6];
statement.copy(compName, 6, 18);
std::cout<<compName;
}
我期望Google
,但实际输出是Googlex
我正在使用Windows-(MinGW.org GCC-6.3.0-1)
答案 0 :(得分:2)
您正在混淆字符序列,C样式字符串和std::string
。让我们分解一下:
\0
结尾的字符数组。它是C的遗留物,因为这样的编译器会假设,即使您没有告诉它,否则字符数组也可能是这样的字符串。std::string
)是存储字符串的模板类。无需担心它在内部如何进行。尽管前两种功能具有互操作性,但这是完全不同的。现在,让我们弄清楚编译器如何看待您的代码:
char compName[6];
这将创建一个具有足够空间的字符数组,以存储6个符号。您可以在其中编写C样式字符串,只要它们不超过5个符号即可,因为您还需要在末尾写入'\0'
。由于在C ++中,C样式数组是不安全的,因此它们将允许您向其中写入更多字符,但是您无法预先预测将这些多余的字符写入内存的位置(即使您的程序将继续执行)。您还可以潜在地从数组中读取更多的字符...但是,您甚至不能问这个数据的来源,除非您只是在玩弄编译器。永远不要在您的代码中这样做。
statement.copy(compName, 6, 18);
此行写6个字符。它不会使它成为C样式的字符串,它只是一个数组中的6个字符。
std::cout<<compName;
您正试图将未提供给编译器的C样式字符串输出到控制台。因此,一个operator<<
会收到一个char []
,它假定您知道自己在做什么,并且就像给它C字符串一样工作。它显示一个接一个的字符,直到到达'\0'
。什么时候会出现这样的角色?我不知道,因为您从未给过它。但是由于C样式数组不安全,因此尝试读取数组末尾的字符,读取一些内存块并认为它们是您不存在的C样式字符串的延续是没有问题的。
在这里,您很幸运,并且只有一个字节显示为'x'
,然后又写入了一个字节,其中写入了0,并且输出停止了。如果您在不同的时间,使用不同的编译器或以不同的优化方式运行程序,则可能会显示完全不同的数据。
那你应该怎么做?
您可以尝试以下方法:
#include <iostream>
#include <string>
int main()
{
std::string statement = "I like to work in Google";
char compName[7]{};
statement.copy(compName, 6, 18);
std::cout<<compName;
return 0;
}
我改变了什么?我使一个数组能够容纳7个字符(为6个字符的C样式字符串留有足够的空间),并且提供了一个空的初始化列表{}
,它将用\0
个字符填充该数组。这意味着当您用数据替换前六个字符时,最后将有一个终止字符。
另一种方法是:
#include <iostream>
#include <string>
int main()
{
std::string statement = "I like to work in Google";
char compName[7];
auto length = statement.copy(compName, 6, 18);
compName[length] = '\0';
std::cout<<compName;
return 0;
}
这里,我没有初始化数组,但是我使用.copy
方法获得了写入其中的数据的长度,然后在正确的位置添加了所需的终止符。
哪种方法最好取决于您的特定应用。
答案 1 :(得分:1)
将指向字符的指针插入流插入运算符时,要求该指针指向以空终止的字符串。
@override
Widget build(BuildContext context) {
return _SomeInherited(
data: this,
child: MaterialApp(
navigatorKey: navigatorKey,
title: 'Some Title',
theme: someTheme,
home: FrontPage(),
),
);
}
不包含空终止符。因此,将其插入(指向元素的指针)插入字符流违反了上述要求。
请让我知道我在这里做错了
您违反了上述要求。因此,您的程序的行为是不确定的。
我希望有Google,但实际输出是Googlex
这是因为程序的行为是不确定的。
如何终止它?
首先,请确保数组中有空终止符:
navigatorKey.currentState.pushXXX
然后,分配空终止符:
compName