【问题标题】:Cannot read with `std::cin.read`: return key not recognized无法使用 `std::cin.read` 读取:无法识别返回键
【发布时间】:2021-12-31 15:02:27
【问题描述】:

我正在尝试使用std::cin.read() 函数从键盘读取字符串。 发生的情况是,当我键入字符串时,它看起来正在被读取,但 [Return] 字符被视为正常的换行符,而不是终止符。

这个函数的终结符是什么?可以修改吗?

#include <iostream>

char* text;
char text_length = 0;

int main() {

    std::cout << "Text length: ";
    std::cin.get(text_length);
    std::cout << "\nText length: " << text_length << std::endl;

    text = new char[1024];
    std::cout << "\n\nText: ";
    std::cin.read(text, text_length);
    std::cout << "\n\nText: " << text << std::endl;
    
    return 0;
}

测试代码:GCC 11,clang 13。操作系统:Linux。

【问题讨论】:

  • std::basic_istream::read 是一个未格式化的输入函数。它不会查看它正在复制的字符。要终止输入,您需要让控制台告诉应用程序它已到达输入的末尾。在 Windows 上是 ctrl-C;在 Unix 系统上它是 ctrl-D。要看到这一点,您可以尝试将输入输入到文件中,并将程序的输入重定向到从该文件中读取。
  • read 没有终结符;它会尝试读取您要求的尽可能多的字节。您可能正在寻找getline
  • @PeteBecker 在 Windows 控制台上,EOF 指示符是 Ctrl+Z(不是 Ctrl+C,它将调用信号处理程序例程,默认情况下将调用 ExitProcess)。但在 Windows 上 Ctrl+Z 的问题在于它必须是单独行的第一个字符(即,您必须按 Enter 然后按 Ctrl+Z,否则 Ctrl+Z 将不会被识别为 EOF )。这意味着换行符也将在 EOF 之前读取。
  • @heapunderrun — ctrl-Z 很好。

标签: c++ iostream cin carriage-return


【解决方案1】:

在 Windows 控制台上,EOF 指示符是 Ctrl+Z(不是 Ctrl+C,它将调用信号处理程序例程,默认情况下将调用ExitProcess)。但是 Ctrl+Z 在 Windows 上的问题是它必须是单独行的第一个字符(即,您必须按 Enter 然后 Ctrl+Z,否则 Ctrl+Z 将不会被识别为 EOF)。这意味着换行符也将在 EOF 之前读取。

std::cin.get(text_length); 行不符合您的预期。它将输入视为字符,而不是数字。因此,如果您按下 5Enter,则提取的值将是 53(字符 5 的 ASCII 码)。相反,请使用std::cin &gt;&gt; text_length;

此外,text_length 应声明为 std::streamsize,而不是 char。如果它应该适合 8 位,则只需在进一步处理之前钳位该值。

还有其他错误:您不会以空值终止缓冲区,并且您从未显式 delete 动态分配由 new 分配的内存(尽管它会在操作系统结束进程时被隐式释放,当然)。

总结一下,看看这段代码:

#include <algorithm>
#include <iostream>
#include <limits>

int main()
{
    constexpr std::streamsize min_text_length{ 0 };
    constexpr std::streamsize max_text_length{ 255 };

    char* text{ nullptr };
    std::streamsize text_length{ 0 };

    std::cout << "Enter text length: ";
    std::cin >> text_length;
    std::cin.clear();
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    std::cout << "Text length entered: " << text_length << '\n';

    text_length = std::clamp(text_length, min_text_length, max_text_length);
    std::cout << "Text length to be used: " << text_length << '\n';

    text = new char[max_text_length + 1]{}; // Note this zero-fills the buffer
    std::cout << "Enter text: ";
    std::cin.read(text, text_length);
    std::cout << "Text entered BEGINS-->" << text << "<--ENDS\n";

    delete[] text;
}

输入长度后,输入一些文本,完成后按Enter,然后按Ctrl+Z,再按再次输入。 (如前所述,不幸的是,Ctrl+Z 之前的换行符也会被读入,但至少 Ctrl+Z 允许您终止输入。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-25
    • 2019-10-07
    • 1970-01-01
    • 2013-03-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多