網站首頁 編程語言 正文
前言
在C++中std::cin>>x,這是一條從std::cin中讀取輸入到x中的語句。而>>操作數是從標準輸入中讀取一個字符串,并把它保存在x對象中。
讀取操作包括:
1、從輸入流緩沖區緩存的輸入字節快中提取對應于右操作數數據類型的字節字塊。如果緩存為空,則等待輸入設備提交字節塊。
2、再將字節子塊轉換為右操作數對應類型的編碼存放在右操作數中。
對于cin之類的流對象有good和not good兩種狀態,cin>>x讀取數據成功時,會返回good狀態;cin>>x讀取數據失敗時,會返回not goot狀態。注意good狀態的流才能讀/寫流緩沖區的數據;not good狀態的流會忽略即不執行讀/寫操作。
反過來,流的讀/寫操作也會影響流的狀態,成功的讀/寫操作會使流保持good狀態;失敗的讀/寫操作會設置流的狀態變量的錯誤標志,表示流在讀/寫操作后處于某種錯誤(not good)的狀態。
流的錯誤狀態可以分為failbit、eofbit和badbit三種錯誤狀態。
常量 | failbit | eofbit | badbit | 轉為10進制 |
ios::failbit | 1 | 0 | 0 | 4 |
ios::eofbit | 0 | 1 | 0 | 2 |
ios::badbit | 0 | 0 | 1 | 1 |
ios::goodbit | 0 | 0 | 0 | 0 |
基本讀取狀態的函數rdstate(),其余狀態讀取函數是good()、fail()、eof()、bad()等。
三種錯誤狀態:
- fail():讀取值與期望接受值的類型不兼容即錯誤格式,狀態變量的failbit被置位,fail()為真,進入fail狀態。這種錯誤是可恢復的,可重新設置流為good狀態,繼續讀取數據,但需要丟棄前面輸入的數據。
- eof():讀取值為文件結束標記eof,此時cin會記錄該標記,狀態變量的eodbit和failbit被同時置位,eof()為真,進入eof狀態。
- bad():由于輸入設備故障導致的數據丟失,狀態變量的badbit和failbit被置位,bad()為真,進入bad狀態,這種錯誤不可恢復,流對象將不可再用。
注意:當流處于錯誤狀態時,狀態變量的failbit總是被置位(true),因此有時候也可以將表達式!fail()作為判斷流是否為good的條件來使用。
介紹一下cin的三個函數:
- cin.clear():是用來更改cin的狀態標識符的,將cin的所有狀態值重設為有效值。
- cin.sync():是用來清除緩存區的數據流的。
- cin.ignore(n,ch):從輸入流中提取字符,提取的字符被忽略,不被使用,每拋棄一個字符,它都要計數和比較字符,如果計數值達到n或者被拋棄的字符是ch,則cin.ignore()函數執行終止,否則繼續等待。
注意:當cin出錯時,先要用cin.clear()重置cin狀態值后,后面兩個函數才能起到作用,但cin.ignore()要比cin.sync()更加靈活。
一、下面給幾個案例
#include <iostream>
using namespace std;
int main()
{
int x;
cout << "請輸入一個整數:";
cin >> x;
cout << " cin.good(): " << cin.good() << endl;
cout << " cin.rdstste(): " << cin.rdstate() << endl;
cout << " cin.fail(): " << cin.fail() << endl;
cout << " cin.eof(): " << cin.eof() << endl;
cout << " cin.bad(): " << cin.bad() << endl;
return 0;
}
1、輸入正確且類型匹配的情況:
2、輸入一個字符時,類型不匹配的情況:
3、以eof結尾:
(在Windows下是輸入Ctrl+z,Linux下是輸入Ctrl+d,都要進行換行后再輸入)
二、當我們對這個程序進行改進后
#include <iostream>
using namespace std;
int main()
{
int x;
int sum = 0;
cout << "請輸入一串整數:";
while (cin>>x)
{
sum += x;
}
cout <<"sum = " << sum << endl;
cout << " cin.good(): " << cin.good() << endl;
cout << " cin.rdstste(): " << cin.rdstate() << endl;
cout << " cin.fail(): " << cin.fail() << endl;
cout << " cin.eof(): " << cin.eof() << endl;
cout << " cin.bad(): " << cin.bad() << endl;
cout << endl;
cin.clear();
char y;
cin >> y;
int z;
cin>>z;
cout <<"y = " << y << endl;
cout <<"z = " << z << endl;
cout << " cin.good(): " << cin.good() << endl;
cout << " cin.rdstste(): " << cin.rdstate() << endl;
cout << " cin.fail(): " << cin.fail() << endl;
cout << " cin.eof(): " << cin.eof() << endl;
cout << " cin.bad(): " << cin.bad() << endl;
return 0;
}
在代碼中用了一個循環輸入,提示輸入一串整數,在前面四個數都是整數的情況下,而第五個數輸入了一個字符,后面兩個數仍然是整數,但是當執行時,sum的值卻是14,也就是說x成功保存了四個數,這就是上面說的fail錯誤狀態,x不能再讀出流緩沖區的數據,這是因為第五個數是字符類型的,與x類型不匹配,再用clear()函數重置cin狀態,由于y是char類型,z是int類型,后面的cin>>y和cin>>z又可以繼續讀出流緩沖區里的數據。
#include <iostream>
using namespace std;
int main()
{
int x;
int sum = 0;
cout << "請輸入一串整數:";
while (cin>>x)
{
sum += x;
}
cout <<"sum = " << sum << endl;
cout << " cin.good(): " << cin.good() << endl;
cout << " cin.rdstste(): " << cin.rdstate() << endl;
cout << " cin.fail(): " << cin.fail() << endl;
cout << " cin.eof(): " << cin.eof() << endl;
cout << " cin.bad(): " << cin.bad() << endl;
cout << endl;
cin.clear();
cout << " clear后:" << endl;
cout << " cin.good(): " << cin.good() << endl;
cout << " cin.rdstste(): " << cin.rdstate() << endl;
cout << " cin.fail(): " << cin.fail() << endl;
cout << " cin.eof(): " << cin.eof() << endl;
cout << " cin.bad(): " << cin.bad() << endl;
cout << endl;
int y;
cin >> y;
int z;
cin>>z;
cout <<"y = " << y << endl;
cout <<"z = " << z << endl;
cout << " cin.good(): " << cin.good() << endl;
cout << " cin.rdstste(): " << cin.rdstate() << endl;
cout << " cin.fail(): " << cin.fail() << endl;
cout << " cin.eof(): " << cin.eof() << endl;
cout << " cin.bad(): " << cin.bad() << endl;
return 0;
}
這里只是將上面的char y改成了int y,可以看運行結果的不同,此時的cin.clear()雖然起作用,但由于流緩沖區里還有數據,y和z會嘗試去讀取里面的數據,而y的類型不匹配再次讓流的狀態變成fail狀態,y和z就都不能讀取數據了,輸入y和z的值是程序自動初始化的。
#include <iostream>
using namespace std;
int main()
{
int x;
int sum = 0;
cout << "請輸入一串整數:";
while (cin>>x)
{
sum += x;
}
cout <<"sum = " << sum << endl;
cout << " cin.good(): " << cin.good() << endl;
cout << " cin.rdstste(): " << cin.rdstate() << endl;
cout << " cin.fail(): " << cin.fail() << endl;
cout << " cin.eof(): " << cin.eof() << endl;
cout << " cin.bad(): " << cin.bad() << endl;
cout << endl;
cin.clear();
cin.sync();
int y;
cin >> y;
int z;
cin>>z;
cout <<"y = " << y << endl;
cout <<"z = " << z << endl;
cout << " cin.good(): " << cin.good() << endl;
cout << " cin.rdstste(): " << cin.rdstate() << endl;
cout << " cin.fail(): " << cin.fail() << endl;
cout << " cin.eof(): " << cin.eof() << endl;
cout << " cin.bad(): " << cin.bad() << endl;
return 0;
}
當在cin.clear()后面加上cin.sync()函數后,sync()函數會清除緩存區的數據,此時緩存區里面就沒有數據了,對于cin>>y和cin>>z,就需要我們自己輸入數據了。
總結
對于cin的錯誤狀態,我們可以用cin的其他幾個函數將其恢復成good狀態,cin.clear()一般和cin.sync()一起使用。
參考書籍:Accelerated C++和Cpp_Primer_5
原文鏈接:https://blog.csdn.net/m0_63070387/article/details/127233466
相關推薦
- 2022-04-02 Python字符串與正則表達式詳細介紹_python
- 2022-06-16 C語言通過案例講解并發編程模型_C 語言
- 2023-04-18 Python之split函數的深入理解_python
- 2022-07-04 PyTorch搭建LSTM實現多變量時序負荷預測_python
- 2022-03-31 C#判斷語句的表達式樹實現_C#教程
- 2022-07-10 redis主從配置+sentinel哨兵模式
- 2022-04-26 Jquery實現多選下拉列表左右移動_jquery
- 2022-05-13 windwos11 小愛音箱鏈接上但是沒有聲音
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支