【C++grammar】文件I/O流的基本用法

目錄

  • 1、輸入輸出類介紹
    • 1.C/C++文件操作對比
    • 2.什么是流?
    • 3.C++ I/O流類層次
    • 4.帶緩沖的輸入輸出
    • 5.gcc編譯器cin.in_avail()
  • 2、向文件寫入數據
    • 1.寫文件小練習
    • 2.如何將信息同時輸出到文件和屏幕?
  • 3、從文件讀數據
    • 1.檢測文件是否成功打開
    • 2.檢測是否已到文件末尾
    • 3.讀取文件小練習
    • 4.bad()函數能否用來判斷文件流是否成功打開?

1、輸入輸出類介紹

1.C/C++文件操作對比

在這里插入圖片描述

2.什么是流?

流是一個數據序列。
一個流是有兩個端點的,一邊是data source(數據源),一邊是程序。
一個I / O流表示輸入源或輸出目的地。流可以表示許多不同種類的源和目標,包括磁盤文件,設備,其他程序和內存陣列。
流支持許多不同類型的數據,包括簡單字節,原始數據類型,本地化字符和對象。一些流只是傳遞數據;其他則以有用的方式操縱和轉換數據。
無論它們在內部如何工作,所有流都向使用它們的程序提供相同的簡單模型:流是數據序列。
程序使用輸入流從源中一次讀取一項數據:
在這里插入圖片描述

程序使用輸出流將數據寫入目的地,一次寫入一項:
在這里插入圖片描述
摘自:I / O流

3.C++ I/O流類層次

在這里插入圖片描述

C++的流類主要有五類:

  1.  流基類(ios_base和ios)
    
  2.  標準輸入輸出流類(istream/ostream/iostream)
    
  3.  字符串流類(istringstream/ostringstream)
    
  4.  文件流類(ifstream/ofstream/fstream)
    
  5.  緩沖區類(streambuf/stringbuf/filebuf)
    

標準輸入輸出流對象 cin 和 cout 分別是類 istream 和 ostream 的實例

字符串流:將各種不同的數據格式化輸出到一個字符串中,可以使用I/O操縱器控制格式;反之也可以從字符串中讀入各種不同的數據。

4.帶緩沖的輸入輸出

C++的I/O流是有內部緩沖區的。
c = cin.get(void)每次讀取一個字符并把由Enter鍵生成的換行符留在輸入隊列中

#include<iostream>using namespace std;int main() {char c;int i = 0;do {c = cin.get();cout << ++i << " : " <<static_cast<int>(c) << endl;} while (c != 'q');return 0;}

在這里插入圖片描述

本部分要展示的內容如下:
1、鍵盤輸入一個字母后回車,實際進入緩沖區的是兩個字符
2、使用cin輸入信息后,有換行字符殘留在緩沖區,從而導致return語句前的cin.get()不起作用

#include <iostream>int main()
{//拿到cin對象的緩沖區指針auto p = std::cin.rdbuf();//從鍵盤讀入字符到緩沖區,保留所有字符在緩沖區auto x = std::cin.peek();std::cout << "x= " << x << std::endl;//顯示緩沖區中的字符數量//由于每次讀取返回值都不一樣,所以先將初始值保存auto count = p->in_avail();std::cout << "There are " << count << "characters in the buffer." << std::endl;//把緩沖區的字符都取出來并顯示for (int i = 0; i < count; i++){std::cout << i + 1 << ":" << std::cin.get() << std::endl;}std::cin.get();return 0;
}

5.gcc編譯器cin.in_avail()

在使用gcc編譯器的時候,存在這樣一種意外的情況:

無論輸入多少個字符, cin.in_avail()函數返回值永遠是0。

這是由于GCC編譯器中配套的libstdc++實現中的問題(可以看作是標準庫gcc實現的一個bug,或者一個特性)。

解決辦法是,在使用cin之前,插入下面一行代碼

cin.sync_with_stdio(false);

簡單解釋原因:GCC的libstdc++默認是保證C++的cin與C的stdin同步的。

2、向文件寫入數據

ofstrem可向文本文件中寫數據.
輸出數據的流程:
在這里插入圖片描述
文件已存在,則直接清除內容。
Writing Data to a File – Auto type recognition (自動類型識別)

1.寫文件小練習

本部分要展示的內容如下:
1、創建文件輸出流
2、向文件寫數據
output << “Lilei” << " " << 90.5 << endl;
output << “HanMeimei” << " " << 85 << endl;
3、關閉文件
4、用文本編輯器打開文件,對比代碼語句檢查結果

//std::c++latest
#include <fstream>
#include <iostream>
#include <filesystem>using std::ifstream;
using std::ofstream;
using std::cout;
using std::endl;
namespace fs = std::filesystem;int main()
{//第一步,關聯文件fs::path p{ "scores.txt" };//第二步,創建一個流輸出對象ofstream output{ p };double lileiScore{ 90.5 };int hanmeimeiScore{ 84 };output << "Lilei " << lileiScore << endl;output << "HanMeimei " << hanmeimeiScore << endl;output.close();cout << "size of " << p << " is " << fs::file_size(p) << endl;std::cin.get();return 0;
}

打開一個輸出文件流的方法包括:
在這里插入圖片描述

2.如何將信息同時輸出到文件和屏幕?

在軟件的調試技術中,很重要的一個技術是將軟件運行過程中的一些信息寫入到“日志文件”中。但是同時還要將信息顯示到屏幕上,以方便程序員實時查看這些信息。
最簡單的一種辦法是這樣的:

std::ofstream output("debug.log", ios::out);
output << __FILE__ << ":" << __LINE__ << "\t" << "Variable x = " << x;
cout << __FILE__ << ":" << __LINE__ << "\t" << "Variable x = " << x;

下面使用streambuf構造一個自己的類,來實現這個功能

#include <streambuf>
#include <iostream>
#include <fstream>//Linux tee命令用于讀取標準輸入的數據,并將其內容輸出成文件。
//tee指令會從標準輸入設備讀取數據,將其內容輸出到標準輸出設備,同時保存成文件。
class teebuf : public std::streambuf
{
public:// Construct a streambuf which tees output to both input// streambufs.teebuf(std::streambuf* sb1, std::streambuf* sb2): sb1(sb1), sb2(sb2){}
private:// This tee buffer has no buffer. So every character "overflows"// and can be put directly into the teed buffers.virtual int overflow(int c){if (c == EOF){return !EOF;}else{int const r1 = sb1->sputc(c);int const r2 = sb2->sputc(c);return r1 == EOF || r2 == EOF ? EOF : c;}}// Sync both teed buffers.virtual int sync(){int const r1 = sb1->pubsync();int const r2 = sb2->pubsync();return r1 == 0 && r2 == 0 ? 0 : -1;}
private:std::streambuf* sb1;std::streambuf* sb2;
};class teestream : public std::ostream
{
public:// Construct an ostream which tees output to the supplied// ostreams.teestream(std::ostream& o1, std::ostream& o2);
private:teebuf tbuf;
};teestream::teestream(std::ostream& o1, std::ostream& o2): std::ostream(&tbuf), tbuf(o1.rdbuf(), o2.rdbuf())
{
}int main()
{std::ofstream output("debug.log");//1、創建文件/屏幕輸出流對象teeteestream tee(std::cout, output);auto x = 1.1;tee << __FILE__ << ":" << __LINE__ << "\t" << "Variable x = " << x;return 0;
}

效果:
在這里插入圖片描述

3、從文件讀數據

ifstrem可從文本文件中讀數據,并檢測文件是否成功打開。
在這里插入圖片描述
了解數據格式
若想正確讀出數據,必須確切了解數據的存儲格式。
用流提取運算符從文件流中讀數據,所讀入的信息的長度與流提取運算符右側的變量的類型有關。

1.檢測文件是否成功打開

可能出現錯誤:

1、讀文件時文件不存在
2、寫文件時介質只讀

檢測文件是否正確打開的方法:

1、open()之后馬上調用fail()函數
2、fail()返回true, 文件未打開

ofstream output("scores.txt");
if (output.fail())  {cout << R"(Can't open file "scores.txt"!)";}

2.檢測是否已到文件末尾

若你不知道文件有多少行,還想把他們全讀出來,用eof()函數檢查是否是文件末尾
由于get函數返回值是int,所以需要強制類型轉換再進行屏幕輸出。

ifstream in("scores.txt");
while (in.eof() == false) {cout << static_cast<char>(in.get());
}

3.讀取文件小練習

本部分要展示的內容如下:
1、創建文件輸入流,打開文件score.txt
2、用>>從文件讀取數據
3、使用fail()函數檢測文件是否打開
4、將讀文件語句放入循環中,使用eof()作為循環條件
5、關閉文件

//std::c++latest
#include <fstream>
#include <iostream>
#include <filesystem>
#include <string>
using std::ifstream;
using std::ofstream;
using std::cout;
using std::endl;
using std::string;
namespace fs = std::filesystem;int main()
{//第一步,關聯文件fs::path p{ "scores.txt" };//第二步,創建一個流輸入對象ifstream input{ p };//第三步使用fail判斷流是否正常打開if (input.fail()){cout << "Can't open file " << p << endl;std::cin.get();return 0;}//第四步,定義一些變量去存這些數據string name{ "" };double score{ 0.0 };//讀取文件中的姓名和分數//input >> name >> score;//cout << name << " " << score << endl;//input >> name >> score;//cout << name << " " << score << endl;while (input.eof() == false){cout << static_cast<char>(input.get());}std::cin.get();return 0;
}

在這里插入圖片描述

4.bad()函數能否用來判斷文件流是否成功打開?

在ifstream和ofstream類中,除了fail()函數之外,還有bad()函數。

那么我們能否用bad()函數取代fail()函數判斷流是否成功打開?

不能,bad() 如果出現意外的問題,如文件受損或硬件故障,最后一次讀取數據的時候發生了這樣的問題,方法bad()將返回true.

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/377622.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/377622.shtml
英文地址,請注明出處:http://en.pswp.cn/news/377622.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

作業2 分支循環結構

書本第39頁 習題2 1.輸入2個整數num1和num2.計算并輸出它們的和&#xff0c;差&#xff0c;積&#xff0c;商&#xff0c;余數。 //輸入2個整數num1和num2.計算并輸出它們的和&#xff0c;差&#xff0c;積&#xff0c;商&#xff0c;余數。//#include<stdio.h> int main…

求一個序列中最大的子序列_最大的斐波那契子序列

求一個序列中最大的子序列Problem statement: 問題陳述&#xff1a; Given an array with positive number the task to find the largest subsequence from array that contain elements which are Fibonacci numbers. 給定一個具有正數的數組&#xff0c;任務是從包含菲波納…

十三、系統優化

系統整體框架圖 程序運行進入紡織面料庫存管理系統主頁面 用戶子系統功能演示&#xff1a; 1&#xff0c;點擊用戶登錄進入用戶登錄頁面&#xff0c;可以注冊和找回密碼 2&#xff0c;注冊新用戶&#xff0c;賬號、密碼、性別、手機號均有限制&#xff0c;用戶注冊需要按指定…

時間工具類[DateUtil]

View Code 1 package com.ly.util;2 3 import java.text.DateFormat;4 import java.text.ParseException;5 import java.text.SimpleDateFormat;6 import java.util.Calendar;7 import java.util.Date;8 9 /**10 * 11 * 功能描述12 * 13 * authorAdministrator14 * Date Jul 19…

JQuery delegate多次綁定的解決辦法

我用delegate來控制分頁&#xff0c;查詢的時候會造成多次綁定 //前一頁、后一頁觸發 1 $("body").delegate("#tableFoot a:not(a.btn)", "click", function () { 2 _options.page $(this).attr("page"); 3 loadTmpl(_option…

leetcode 45. 跳躍游戲 II 思考分析

題目 給定一個非負整數數組&#xff0c;你最初位于數組的第一個位置。 數組中的每個元素代表你在該位置可以跳躍的最大長度。 你的目標是使用最少的跳躍次數到達數組的最后一個位置。 示例: 輸入: [2,3,1,1,4] 輸出: 2 解釋: 跳到最后一個位置的最小跳躍數是 2。 從下標為 …

C程序實現冒泡排序

Bubble Sort is a simple, stable, and in-place sorting algorithm. 氣泡排序是一種簡單&#xff0c;穩定且就地的排序算法。 A stable sorting algorithm is the one where two keys having equal values appear in the same order in the sorted output array as it is pre…

一、爬蟲基本概念

一、爬蟲根據使用場景分類 爬蟲&#xff1a; 通過編寫程序&#xff0c;模擬瀏覽器上網&#xff0c;讓其去互聯網上抓取數據的過程。 ① 通用爬蟲&#xff1a;抓取系統重要的組成部分&#xff0c;抓取的是一整張頁面的數據 ② 聚焦爬蟲&#xff1a;建立在通用爬蟲的基礎之上&am…

經營你的iOS應用日志(二):異常日志

如果你去4S店修車&#xff0c;給小工說你的車哪天怎么樣怎么樣了&#xff0c;小工有可能會立即搬出一臺電腦&#xff0c;插上行車電腦把日志打出來&#xff0c;然后告訴你你的車發生過什么故障。汽車尚且如此&#xff0c;何況移動互聯網應用呢。 本文第一篇&#xff1a;經營你的…

Discuz 升級X3問題匯總整理

最近一段時間公司的社區垃圾帖數量陡然上漲&#xff0c;以至于社區首頁的推薦版塊滿滿都是垃圾帖的身影&#xff0c;為了進一步解決垃圾帖問題我們整整花了1天時間刪垃圾貼&#xff0c;清除不良用戶&#xff0c;刪的手都酸了&#xff0c;可見垃圾帖的數量之多&#xff01;可恥的…

【C++grammar】格式化輸出與I/O流函數

目錄1、格式化輸出1. setw manipulator(“設置域寬”控制符)2. setprecision manipulator(“設置浮點精度”控制符)3. setfill manipulator(“設置填充字符”控制符)4. Formatting Output in File Operation(在文件操作中格式化輸入/輸出)5.小練習2、用于輸入/輸出流的函數1. g…

python 忽略 異常_如何忽略Python中的異常?

python 忽略 異常什么是例外&#xff1f; (What is an Exception?) An exception is an event, which occurs during the execution of a program that interrupts the normal execution of the application. Generally, any application when encountered with a situation t…

三、實戰---爬取百度指定詞條所對應的結果頁面(一個簡單的頁面采集器)

在第一篇博文中也提及到User-Agent&#xff0c;表示請求載體的身份&#xff0c;也就是說明通過什么瀏覽器進行訪問服務器的&#xff0c;這一點很重要。 ① UA檢測 門戶網站服務器會檢測請求載體的身份。如果檢測到載體的身份表示為某一款瀏覽器的請求&#xff0c;則說明這是一…

Spring MVC攔截器實現分析

SpringMVC的攔截器不同于Spring的攔截器&#xff0c;SpringMVC具有統一的入口DispatcherServlet&#xff0c;所有的請求都通過DispatcherServlet&#xff0c;所以只需要在DispatcherServlet上做文章即可&#xff0c;DispatcherServlet也沒有代理&#xff0c;同時SpringMVC管理的…

碩士畢業后去國外讀法學博士_法學碩士的完整形式是什么?

碩士畢業后去國外讀法學博士法學碩士&#xff1a;豆科大法師(拉丁)/法學碩士 (LLM: Legum Magister (Latin)/ Master of Law) LLM is an abbreviation of Legum Magister. It is in term of Latin which states the masters degree of Law. In the majority, LLM is generally …

android:layout_weight屬性的簡單使用

效果&#xff1a; style.xml <style name"etStyle2"><item name"android:layout_width">match_parent</item><item name"android:layout_height">wrap_content</item><item name"android:background"…

一、環境配置安裝

一、Anaconda Ⅰ下載 最新版的anaconda可能會需要各種各樣的問題&#xff0c;python3.6版本比較穩定&#xff0c;建議使用。 老鐵們可以通過&#xff0c;Anaconda以前版本所自帶Python版本&#xff0c;查看Anaconda所帶的python版本 我用的是這個&#xff0c;Anaconda3-5.2.0…

leetcode 35. 搜索插入位置 思考分析

目錄題目暴力二分迭代二分遞歸題目 給定一個排序數組和一個目標值&#xff0c;在數組中找到目標值&#xff0c;并返回其索引。如果目標值不存在于數組中&#xff0c;返回它將會被按順序插入的位置。 你可以假設數組中無重復元素。 示例 1: 輸入: [1,3,5,6], 5 輸出: 2 示例 2:…

java優秀算法河內之塔_河內塔的Java程序

java優秀算法河內之塔Tower of Hanoi is a mathematical puzzle where we have three rods and n disks. The objective of the puzzle is to move all disks from source rod to destination rod using the third rod (say auxiliary). The rules are: 河內塔是一個數學難題&a…

轉——C# DataGridView控件 動態添加新行

DataGridView控件在實際應用中非常實用&#xff0c;特別需要表格顯示數據時。可以靜態綁定數據源&#xff0c;這樣就自動為DataGridView控件添加相應的行。假如需要動態為DataGridView控件添加新行&#xff0c;方法有很多種&#xff0c;下面簡單介紹如何為DataGridView控件動態…