C++部分程序忽略第一个字符

博客详细分析了C++ Primer第五版P943.17练习题中cin的工作原理,指出问题在于如何正确处理输入结束。通过实例展示了cin.get()与cin在读取输入时的区别,并解释了如何避免丢失输入或提前结束循环的问题。文章还探讨了键盘输入如何进入缓冲区以及cin.get()如何影响读取过程。最终,作者通过修改代码解决了程序不输出最后一个元素的错误,并提供了验证结论的输入示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最后总结:这是一个“不了解cin工作原理”而导致的问题。把cin看做指针,从缓冲区逐位读取数据。

问题背景:所用教材《C++ Primer》第五版,P94 3.17练习题,从cin读入一组词并输入一个vector对象中,再把所有词改为大写形式,输出结果,每个单词单独一行显示。本次准备改进一下,程序以输入回车结束。

主程序如下:

int main()
{
    vector<string>A;
    string B;
    int N=0;
    while(cin)
    {
        if(cin.get()=='\n')
            break;
        else
            {
                cin>>B;
                A.push_back(B);
                N++;

            }
    }
    
    for(int i=0;i<=N;i++)
    {
        for(auto &a:A[i])
        {
            a=toupper(a);
        }
        cout<<A[i]<<endl;
    }
    
    return 0;
}


运行后:

把程序更改为如下:

int main()
{
	vector<string>A;
	string B;
	int N=0;
	while(cin)
	{

				cin>>B;
				A.push_back(B);
				N++;
				if(cin.get()=='\n')
					break;

	}
	
	for(int i=0;i<=N;i++)
	{
		for(auto &a:A[i])
		{
			a=toupper(a);
		}
		cout<<A[i]<<endl;
	}
	
	return 0;
}

 运行结果符合预期:

 原因正在分析中。

———————————————————————————————————————————

原因分析:

        首先while(cin>>A)实际上是

        

int main()
{
	int A;
	while(cin)
	{
		if(cin>>A)
			cout<<A<<endl;
		else
			break;
	}	
	return 0;
}

        即while(cin>>A)和while(cin)是等价的,检测的对象都是流的状态,即cin里边有没有东西,只要有东西就进入循环,若cin里边的内容和A同一类型,则进行循环中的下一步操作;如不是同一类型跳出循环,如图1.1,图1.2和图1.3,当碰见无效输入(和A类型不一致的输入)跳出循环,执行下一语句。所以while(cin)还是while(cin>>A)不会导致程序忽略第一个字符,但是会出现程序不输出最后一个元素的新问题,这个问题见下一篇“不输出最后一个元素”文章。

#include<iostream>

using namespace std;

int main()
{
	int A;
	while(cin>>A)
		cout<<A<<endl;
		
	return 0;
}

  图1.1

 图1.2

 图1.3

        其次,键盘的输入内容先放在缓冲区,当输入完成后按下回车,cin再从缓冲区读入。此时,这个回车就具有两个功能了,一个是表示输入完成,cin开始读入;另一个是自己设定的循环结束标志,这会不会出问题呢?这就是第二个踩坑记录,部分程序最后一个元素不输出。

        最后,总结以上经验,cin.get()检测完成后会扔掉所检测的字符,它不参与后续操作。即aaa中第一个a用于检测,检测完成后扔掉,用后边的

        我们输入aaa bbb ccc,第一个a检测完成后扔掉,只有aa进入了字符串B。紧接着的这个空格,触发了两个操作,一个是字符串碰见空白会停止,完成输入,得到第一个字符串aa,返回循环开头,空格也算输入,cin为真,循环再次;第二个操作就是空格进行了cin.get()检测,检测完成后被扔掉,bbb输入字符串,以此类推。综上所述,第一个a被cin.get()检测,用完扔了,所以输出aa;之后的检测用到的是空格,所以bbb,ccc能完整的输出。

        验证:输入   (空格)aaa(空格)bbb(空格)ccc   。结论成立。

图1.4 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值