字符串数据似乎在 for 循环后被删除
String Data seems to be deleted after for loop
在下面的代码中,每当我去调试器,段落的值被删除,或者返回到0,我似乎想不通为什么,想法?
void getFreqLetter(string paragraph){
char alphabet[26] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };
int counter[26];
//set counter values to zero
for (int clear = 0; clear < sizeof(counter) - 1; ++clear){
counter[clear] = 0;
}
cout << paragraph;
int result = 0;
for (int i = 0; i < sizeof(paragraph); ++i){
//case:found
for (int j = 0; j < sizeof(alphabet) - 1; ++j){
if (alphabet[j] == paragraph[i]){
counter[j]++;
}
}
//go through array find largest value
for (int k = 0; k < sizeof(counter) - 1; ++k){
if (counter[k] > result){ result = counter[k]; }
}
cout << result;
}
}
总之,所有问题都是由于您滥用sizeof
.
sizeof(paragraph)
没有做你认为它正在做的事情:它返回 string
类的大小,而不是字符串实例中的字符数。
您应该使用 paragraph.size()
而不是假设它是std::string
类型。
sizeof(alphabet)
通过幸运的巧合返回数组中的元素数:sizeof(char)
由标准定义为 1。这样的"王牌"代码应该附上注释!
你没有那么幸运sizeof(counter)
.您返回的值是sizeof(int)
的倍数,该倍数因平台而异(2、4 和 8 是常见的(。你应该写sizeof(counter) / sizeof(int)
或sizeof(counter) / sizeof(counter[0])
.后者是一些人的首选,因为您不需要对类型进行硬编码,并且由于C++标准不允许零长度数组,因此counter[0]
定义良好。
(这里要记住的是,sizeof
是在编译时计算的(。
你在循环条件中的sizeof(counter)
实际上是sizeof(int) * 26
的,所以你的字母表被你的循环(从迭代 27 开始(和一些堆栈(特别是将返回地址设置为 0,以及 paragraph
参数的内部(压垮了。
而且你的- 1
不应该在那里,因为你使用的是严格的比较。
您可能希望跟踪第一个循环并观察 sizeof(counter)
的值。
如果你想要counter
数组中的元素数量,一种惯用的方法是sizeof(counter) / sizeof(counter[0])
。
此外,string
的长度应该由 paragraph.size()
获得,因为 sizeof(paragraph)
返回管理字符串的对象的大小,而不是字符串本身。
最后,sizeof(alphabet)
做正确的事情,因为sizeof(char)
被定义为 1。
现在,对于一些 C++11 魔法:
#include <array>
const std::array<char,26u> alphabet{ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };
std::array<int, 26u> counter;
//set counter values to zero
for (int clear = 0; clear < counter.size(); ++clear){
counter[clear] = 0;
}
这消除了许多(所有(sizeof
陷阱,同时同样高效。
此代码
//set counter values to zero
for (int clear = 0; clear < sizeof(counter) - 1; ++clear){
counter[clear] = 0;
}
无效,导致内存覆盖。
要么使用
for (int clear = 0; clear < sizeof( counter ) / sizeof( *counter ); ++clear){
counter[clear] = 0;
}
或
for (int clear = 0; clear < 26; ++clear){
counter[clear] = 0;
}
或
std::memset( counter, 0, 26 * sizeof( int ) );
或者简单地在声明数组时将其初始化为零
int counter[26] = {};
此循环
for (int j = 0; j < sizeof(alphabet) - 1; ++j){
if (alphabet[j] == paragraph[i]){
counter[j]++;
}
也是无效的。字符数组alphabet
不包含终止零。所以循环应该写成
for (int j = 0; j < sizeof(alphabet); ++j){
if (alphabet[j] == paragraph[i]){
counter[j]++;
}
并且此循环无效
for (int k = 0; k < sizeof(counter) - 1; ++k){
if (counter[k] > result){ result = counter[k]; }
}
见上文。
如果对幻数 26 使用命名常量,则不会出错。
例如
const int N = 26;
char alphabet[N] =
{
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
};
//...
for ( int j = 0; j < N; ++j )
{
if (alphabet[j] == paragraph[i]){
counter[j]++;
}
要找到最大的数字,您可以使用在标头 <algorithm>
中声明的标准算法std::max_element
。例如
int ewsult = *std::max_element( counter, counter + 26 );
- 如何从使用 for 循环中的矢量大小的矢量中删除元素
- 从嵌套循环中的 std::list 中删除将返回访问冲突
- 删除功能不适用于串行通信后多个循环中的多个实例
- 我正在尝试使用 while 循环从字符串中删除字母,直到没有字母。我在这里做错了什么?
- c++ 循环访问对象列表并删除对象
- 循环以从字符数组中删除过多的空格 (C++)
- C++循环链表删除,计数从下一个节点开始
- c++ 在循环中删除迭代器(映射的映射)
- 遍历 STL 映射(集/多集)的最佳方法,同时元素可能会在循环期间被删除并重新插入?
- 循环依赖:无法删除不完整的类型
- 如何在每次循环迭代期间生成向量,存储数据,然后删除该向量?
- 在循环-C 中重新删除对象
- 在循环访问嵌套向量时删除元素
- 如何在不使用循环或迭代器的情况下检查所有列表元素并在满足条件时删除一个
- 射击时从列表中删除外星人 - 找出循环;"表达式:无法递增结束列表迭代器"
- C++循环链接列表 - 删除所有节点
- C++删除 for 循环中的列表成员
- 在开关盒循环中使用未删除的标识符来解析 CSV 文件
- 如何在C++的循环中从矢量中删除元素
- 循环删除所有给定值