不同的缓冲区但相同的地址

问题描述 投票:0回答:1

所以我想引用 C++ 文档中关于 cin.ignore 的内容:

它从关联的流缓冲区对象中提取字符

现在我尝试了一下,想确认以下示例中的某些内容。

#include<iostream>      
using namespace std;

int main() {
    char strArr1[6];
    char strArr2[6];
    cin.get(strArr1, 6, 'c'); // did this in order to get c in the buffer
    cout << "strArr1 is" << endl; // ENTER Issac
    cout << strArr1 << endl; // Issa
    cin.ignore(3, 'p') >> strArr2; // ENTER Howard
    cout << "strArr2 is" << endl; 
    cout << strArr2 << endl; // oward
    return 0;
}

在本例中,strArr1 是“Issa”,它将“c”留在缓冲区中。现在,在

cin.ignore
中,我们包含缓冲区中的“c”、strArr1 的空结束字符以及作为“Howard”的第一个字母的“H”。这是我的结论,但我想与 C++ 专家确认我的结论的正确性。我假设两个 cin 使用相同的流缓冲区,因为当我计算两个 cin 的地址时,它是相同的。

任何对此结论的确认将不胜感激。

c++ stream
1个回答
0
投票

好的,按照你的新问题,我想我明白你的困惑来自哪里。

如果不了解工作流程,代码的行为就很难理解。当您执行

cin.get(strArr1, 6, 'c')
时,您告诉它在
'c'
处停止。但这不是最后一个字符,因为您稍后按下了 Enter。第三个字符是
'h'
,正如Ted所说

如果不了解工作流程,代码的行为就很难理解。

cin.ignore(3, 'p') >> strArr2;
返回一些东西,但是什么?
void
int
NULL
nullptr
std::cout
std::cin
?他们全部?没有任何?如果是这样,为什么?

让我们看一下 C++ Reference 上的文档(相对于 cplusplus.com,我更喜欢它),因为它是一个社区维护的 wiki,并且具有较少的 wooden 语言,而且我个人发现它作为网站的结构更好(一旦你理解了推理)后面)。

摘自

[std::basic_istream<CharT,Traits>::ignore][2]

从输入流中提取并丢弃字符,直到并包括 delim。

ignore 表现为 UnformattedInputFunction。构造并检查哨兵对象后,它从流中提取字符并丢弃它们,直到发生以下任何条件:

    已提取
  • count 个字符。当计数等于 std::numeric_limitsstd::streamsize::max() 时,此测试在特殊情况下被禁用。

  • 输入序列中出现文件结束条件,在这种情况下函数调用 setstate(eofbit)。

  • 输入序列中的下一个可用字符 c 是 delim,由 Traits::eq_int_type(Traits::to_int_type(c), delim) 确定。分隔符被提取并丢弃。如果 delim 是 Traits::eof(),则禁用此测试。

参数

count - 要提取的字符数

delim - 停止提取的定界字符。也提取出来了

返回值

*这个

正如您所看到的,由于它是一个成员函数,因此当调用它时,它会返回调用它的当前对象。所以

std::cin.ignore()
将返回
cin
本身。

这个:

cin.ignore(3, 'p') >> strArray2
基本上就是在做

cin.ignore(3, 'p');
cin >> strArray2;

...正如此处所见。

这应该澄清变量、

stdin
stdout
之间的关系,但是现在,您可能会尝试遵循这一点并将其应用到我们在评论中讨论的内容,但可能会感到困惑。到目前为止,很明显
strArray1
strArray2
已不在等式中。但是
std::cin
"Isaac"
"Howard"
'c'
'p'
呢?

请记住,我确实说过,为流存储或使用的数据分配了内存,您可以将其视为一种缓冲区(在谈论 C 和 C++ 时要非常小心如何使用这个术语)。

您的帖子听起来是将

ignore()
的行为归因于或关联到
get()
。程序做出这样的反应的原因是因为您可以将输入流视为馈送器。为了让它被消耗,他们需要连续的数据(提示提供了),但它也需要被“吃掉”。
get()
只“吃了”4个字符,因为你告诉它在
c
处停止。
ignore()
忽略了它和接下来的 2 个字符。相比之下,看看这段代码:

#include<iostream>      

int main() {
    char strArr1[6];
    char strArr2[6];
    std::cin.get(strArr1, 3); // did this in order to get c in the buffer
    std::cout << "strArr1 is " << strArr1 << std::endl; // Is
    std::cin.ignore(3, 'p') >> strArr2; // ENTER Howard
    std::cout << "strArr2 is " << strArr2 << std::endl; // Howar
    return 0;
}

请注意,即使我给了它 5 个字符(并终止

'\0'
),它“吃掉”了 2 个(+
\0
),而第二个 var 只保存了前 5 个字符(+
'\0
)。为什么?为什么不忽略也“计算”你名字中缺失的部分?那是因为我告诉他只“使用”3个字符,所以他认为当前的“吃”会话在执行后就终止了,因此它跳转到下一个处理
"Howar"
的输入会话。
'd'
丢失了,因为
strArray2
没有剩余的“空间”来保存它。

© www.soinside.com 2019 - 2024. All rights reserved.