所以我想引用 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 的地址时,它是相同的。
任何对此结论的确认将不胜感激。
好的,按照你的新问题,我想我明白你的困惑来自哪里。
如果不了解工作流程,代码的行为就很难理解。当您执行
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
没有剩余的“空间”来保存它。