如何修复C++中的随机字符输出?

How to fix the random character outputs in C++?

本文关键字:字符 输出 随机 何修复 C++      更新时间:2023-10-16

当我使用 char 数组获取字符串输入并使用 for 循环遍历它们时,我的代码总是具有不应该存在的随机字符输出。

我已经尝试通过检查各个阶段的输出来调试我的代码,但我找不到正在发生的事情的原因。

int k, s, counter = 0;
char word[21];
std::cin>>k;
std::cin.getline(word,21);
for (int i = 0; word[i] != ' '; i++)
{
s = 3*(i + 1) + k;
std::cout<<s;
for (int k = 0; k < s; k++)
{
word[i]--;
if (word[i] < 'A')
word[i] = 'Z';
}
std::cout<<word[i];
}

当我输入 3 来获取 k 的值时,我已经得到了输出"URORIFCFWOQNJCEBFVSPMJNKD",而我不应该得到任何输出。

问题是在使用getline之前没有刷新缓冲区。
因此,当您在输入数字后按回车键时,该回车(字符"")将传递给getline(),此时getline通过将word留空来结束他的工作。

解决方案很简单:在获取线之前刷新缓冲区。

以下是完整的解决方案:

#include <iostream>
int main() {
int k, s, counter = 0;
char word[21];
std::cin>>k;
// Clear the buffer
std::cin.clear();
while (std::cin.get() != 'n') 
{
continue;
}
std::cin.getline(word,21);
std::cout<<"TEST>"<<word<<"<TEST"<<std::endl<<std::flush;
for (int i = 0; word[i] != ' '; i++)
{
s = 3*(i + 1) + k;
std::cout<<s;
for (int k = 0; k < s; k++)
{
word[i]--;
if (word[i] < 'A')
word[i] = 'Z';
}
// Use std::flush to forcefully print current output.
std::cout<<word[i]<<std::flush;
}
}

笔记:

  • 我使用了那里描述的缓冲区清除机制。你可能会使用另一个,但想法是一样的
  • 如果您注释该缓冲区清除部分的 4 行,您会注意到,只要您键入"3"并按回车键,您就会看到类似"TEST><TEST"的输出,这意味着其中的word为空。
  • 如果要在 for 周期结束之前强制打印输出,请考虑在使用 cout 时使用std::flush

std::cin >> k;只读取整数。它读取尾随换行符。>>运营商的文件说

如果满足以下条件之一,提取将停止:

  • 找到空格字符 [...] 。不提取空格字符。

正如Just Shadow指出的那样,这个换行符导致getline()调用返回一个空字符串。

您可以通过调用来忽略任意数量的换行符

std::cin.ignore(std::numeric_limits<std::streamsize>::max(), 'n');

顺便说一句:看看你的外部for循环,我会担心如果字符串不包含任何空格,你可能会读到word末尾。以下解决方案也可以解决此问题:

#include <iostream>
#include <limits>
int main() {
int k, s, counter = 0;
char word[21];
std::cin >> k;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), 'n');
std::cin.getline(word, 21);
for (int i = 0; i < sizeof(word) && word[i] != ' '; i++)
{
s = 3 * (i + 1) + k;
std::cout<<s;
for (int k = 0; k < s; k++)
{
word[i]--;
if (word[i] < 'A')
word[i] = 'Z';
}
std::cout << word[i];
}
}