【发布时间】:2021-11-11 19:31:53
【问题描述】:
我最近正在研究一个问题,教 C++ 的新用户,我自己就是,如何使用 cstrings 以及与 C++ 中导入的字符串对象相比它们的不同实现。当我处理这个问题时,我遇到了一个错误,尽管将 cstring 的大小初始化为正在执行的操作的适当长度,但 cstring 的输出却很奇怪。
当我使用 cout 打印出 cstring 时,它会正确打印一些 cstring,但通常前几个字符是随机字符,与对 cstring 执行的操作无关。但是,我找到了一种方法可以明确地阻止这些字符被打印出来。但是,我很好奇为什么这样做以及这里的问题是什么。
我发现在打印 cstring 之前在其自己的行上添加 cout << ""; 解决了打印 cstring 时输出随机字符的问题。然而,这似乎只是一个临时解决方案,我正在寻找一种更有教育意义的方法来解决这个问题。
下面我包含了导致错误的代码。
#include <iostream>
#include <vector>
#include <string>
#include <cstring>
using namespace std;
int main() {
vector<string> words = {"Hello,", "and", "welcome", "to", "the", "world", "of", "C++!"};
// Calculate the total number of characters in the words vector
// (including an additional character for space)
int length = 0;
for(int i = 0; i < words.size(); i++) {
length += words.at(i).length() + 1;
}
cout << ""; // Removing this line of code will cause the output to do strange things
// Initialize the cstring to be of size length
char cstring[length];
// Build the cstring using cstring library functions
for(int i = 0; i < words.size(); i++) {
strcat(cstring, (words.at(i) + " ").c_str());
}
// Null-terminate the cstring
cstring[length-1] = '\0';
// Output the cstring
cout << cstring << " " << strlen(cstring) << endl;
return 0;
}
如果删除包含cout << "";的代码行,输出看起来像这样,每次输出的开头都是随机数量和随机字符集:
`k+��你好,欢迎来到 39 岁的世界
但是,通过包含该行,我能够实现所需的输出:
您好,欢迎来到 C++ 世界! 39
【问题讨论】:
-
char cstring[length];不受标准 C++ 支持。 -
您不会将
cstring初始化为任何特定的东西,因此它的内容是任意的。然后你strcat进入它,所以它会在其中找到第一个 null 并附加文本。将数组的第一个元素初始化为零。 -
大概
char cstring[length]没有初始化为零,strcat从现有字符串中的第一个空字符开始复制。但是char cstring[length]不是标准的 C++,它是一个扩展。它不应该教给新的 C++ 用户。总而言之,您应该停止使用 c 字符串并坚持使用std::string。您绝对应该不向新用户介绍 c 字符串。它不是应该常用的东西,很难正确使用,并且主要是为了向后兼容而存在的。它应该被认为是语言中更高级的部分。 -
您可能应该找到一个更现代的资源来学习 C++。如果有帮助,2011 年之前的任何东西都应该被认为是过时的。
-
这并没有解决问题,但在那些 for 循环中,您知道
i是一个有效索引,因为您是这样编写的。您无需浪费时间使用words.at(i)进行检查。只需使用words[i]。
标签: c++ loops for-loop c-strings string-concatenation