【问题标题】:reading buffer C++读取缓冲区 C++
【发布时间】:2023-04-17 20:40:01
【问题描述】:

我正在尝试一次读取 C++ 中的一个字符直到 '\n' 的缓冲区,并使用 do-while 循环使用这些字符初始化 char 数组。我知道我可以使用 cin.getline(),但我想自己尝试一下。

int main()
{
    char buffer [1024];
    int index = 0;
    char temp;

    do 
    {
        cin.get( temp );
        buffer [ index ] = temp;
        index ++;
    }
    while ( temp != '\n' );

    cout << buffer << endl;

    return 0;
} 

它给了我不正确的结果——正确的文本由几行方括号与其他奇怪的符号混合而成。

【问题讨论】:

  • 顺便说一句,std::getline()std::istream::getline() 更易于使用,因为后者需要您提前选择缓冲区大小。

标签: c++


【解决方案1】:

首先,在整个文本之后,您必须将'\0' 附加为字符串的结尾

它应该看起来像 buffer[ index ] = 0;,因为你应该重写你也附加的 \n 字符。

当然,您还应该检查其他事项,但它们不是您的主要问题

  • 输入的长度,因为缓冲区有限 - 最大长度为 1023 + 空字节
  • 标准输入结束cin.eof()

【讨论】:

  • +1 我会这样做,因为它更明确地表明 ZT 已经完成(您无需查找已将整个缓冲区设置为 0
【解决方案2】:

您没有对缓冲区进行空分隔。

尝试将第一行改为

char buffer[1024] = "";

这会将buffer 中的所有字符设置为0。或者,也可以将最后一个字符设置为0,方法是

buffer[index] = 0;

在循环之后。

此外,(正如其他人正确指出的那样)如果文本长度超过 1024 个字符,则会出现缓冲区溢出错误 - 这是软件安全问题最常被利用的原因之一。

【讨论】:

  • 您确定 char buffer[1024] = ""; 将所有字符设置为 0 吗?不等于char buffer[0] = 0;吗?我不知道,我在问。我敢肯定,这会将所有字符设置为 0 char buffer[1024] = { 0 };
  • 是的,我确定。 “如果大括号括起来的列表中的初始值设定项少于聚合的元素或成员,或者用于初始化已知大小数组的字符串文字中的字符少于数组中的元素,则聚合的其余部分应隐式初始化与具有静态存储持续时间的对象相同。”参见例如*.com/questions/453432/…
  • (对已删除评论的回应)不,它没有。请阅读我引用的内容并谷歌一些。这会将 整个数组 设置为零。准确地说:字符串字面量中的字符或更少(这是真的,因为有 0 用于初始化已知大小的数组 (=1024) 聚合的其余部分应与具有静态存储持续时间的对象隐式初始化相同(为零,因为静态数组被初始化为全零)。
【解决方案3】:

两件事:

  1. 如果你是行的长度 读数超过 1024 你写过去 缓冲区不好。
  2. 如果长度在 限制,你没有终止 带有空字符的字符串。

您可以尝试以下方式。这样,如果您发现罚款超过缓冲区大小,我们会将其截断并在循环外的末尾添加空字符。

#define MAX 1024

int main()
{
 char buffer [MAX];
 int index = 0;
 char temp;

 do 
 {
  // buffer full.
  if(index == MAX-1)
   break;

  cin.get( temp );
  buffer [ index ] = temp;
  index ++;

 }
 while ( temp != '\n' );

 // add null char at the end.
 buffer[index] = '\0';

 cout << buffer << endl;

 return 0;
} 

【讨论】:

    【解决方案4】:

    我注意到的几个问题:

    (1) 输入的字符编码是什么。您可能正在阅读 8,16 或 32 位字符。你确定你读的是 ASCII 码吗?

    (2) 您正在搜索“\n”,行尾字符可能是“\r\n”或“\r”或“\n”,具体取决于您的平台。也许 \r 字符本身就是你的方括号?

    【讨论】:

    • 主要问题是在结束字符序列的字符串中缺少零字节。这些注释很有用,但现在它们并不重要
    【解决方案5】:

    当您到达换行符时,您会停止填充缓冲区,因此其余部分未初始化。您可以通过使用以下内容定义缓冲区来对缓冲区进行零初始化:char buffer[1024] = {0}; 这将解决您的问题。

    【讨论】:

      【解决方案6】:

      您没有在字符串末尾添加 '\0'。此外,您应该真正检查缓冲区溢出情况。当索引达到 1024 时停止读取。

      【讨论】: