C/C++ 文件操作

2022-01-06 彌補流年

1. 文件操作

通過文件將數據持久化

C++ 對文件操作需要包含頭文件<fstream>

文件類型分為兩種:

操作文件的三大類:

ofstream  --- 寫操作

ifstream   --- 讀操作

fstream    --- 讀寫操作

2. 文本文件

1)寫文件步驟

1. 包含頭文件#include <fstream>2. 創建流對象ofstream ofs;3. 打開文件ofs.open("文件路徑", 打開方式);4. 寫數據ofs << "寫入數據";5. 關閉文件ofs.close();

文件打開方式:

打開方式         解釋ios::in         為讀文件而打開文件ios::out        為寫文件而打開文件ios::ate        初始位置:文件尾ios::app        追加方式寫文件ios::trunc      如果文件存在先刪除,再創建ios::binary     二進位方式

註:文件打開方式可以配合使用,利用 | 操作符

例如用二進位方式寫文件  ios::binary | ios::out

2)讀文件步驟

1. 包含頭文件#include<fstream>2. 創建流對象ifstream ifs;3. 打開文件並判斷文件是否打開成功ifs.open("文件路徑",打開方式);4. 讀數據四種方式讀取5. 關閉文件ifs.close();

判斷是否打開成功   ifs.is_open()

void test(){    ifstream ifs;    ifs.open("text.txt",ios::in);    if(!ifs.is_open())    {        cout << "文件打開失敗" << endl;        return;    }            char buf[1024] = { 0 };    while (ifs >> buf)    {        cout << buf << endl;    }
char buf[1024] = { 0 }; while (ifs.getline(buf, sizeof(buf))) { cout << buf << endl; }
string buf; while (getline(ifs, buf)) { cout << buf << endl; }
char c; while ((c = ifs.get()) != EOF) { cout << c; }}

3. 二進位文件

以二進位方式對文件進行讀寫操作

打開方式要指定為 ios::binary

寫文件:

利用流對象調用成員函數 write

ostream& write(const char *buffer,int len);

class Person {public:  char m_Name[64];  int m_Age;};
void test(){ ofstream ofs; ofs.open("person.txt", ios::out | ios::binary); Person p = { "張三",20 }; ofs.write((const char*)&p, sizeof(Person)); ofs.close();}

讀文件:

利用流對象調用成員函數read

istream& read(char *buffer, int len);// 字符指針buffer指向內存中一段存儲空間。len是讀寫的字節數

class Person {public:  char m_Name[64];  int m_Age;};
void test(){ ifstream ifs("person.txt", ios::in | ios::binary); if (!ifs.is_open()) { cout << "文件不存在" << endl; return; } Person p; ifs.read((char*)&p, sizeof(Person)); cout << "name = " << p.m_Name << " ,age = " << p.m_Age << endl; ifs.close();}

3. 流處理

C++引入 istringstream(串流的輸入)、ostringstream(串流的輸出)、stringstream(串流的輸入輸出),使用時要包含sstream.h的頭文件。

當 cin 讀取數據時,它會傳遞並忽略任何前導白色空格字符(空格、制表符或換行符)。一旦它接觸到第一個非空格字符即開始閱讀,當它讀取到下一個空白字符時,它將停止讀取。

int main(){    string name;    string city;    cout << "Please enter your name: ";    cin >> name;    cout << "Enter the city you live in: ";    cin >> city;    cout << "Hello, " << name << endl;    cout << "You live in " << city << endl;    return 0;}輸入:Jone Merry輸出:Hello, Jone      You live in Merry

getline 此函數可讀取整行,包括前導和嵌入的空格,並將其存儲在字符串對象中。

getline(istream &is,string &str,char delim)

從stringstream流中的數據輸入字符串到一個變量裡,是以遇到空格跳到下一個字符串的這樣的形式連續讀取的。

輸入形式:a c bbf ddddnowcoder
using namespace std;int main(){    string str;    while(getline(cin, str))// getline 按行讀取 { vector<string>s; string tmp; stringstream ss(str); while(ss>>tmp){ s.push_back(tmp); } sort(s.begin(),s.end()); for(int i=0;i<s.size()-1;i++){ cout<<s[i]<<" "; } cout<<s[s.size()-1]<<endl; str.clear(); }}

輸入形式:a,c,bbf,ddddnowcoder
#include<bits/stdc++.h>using namespace std;int main(){ string str; while(getline(cin, str)){ stringstream ss(str); vector<string>s; string tmp; while(getline(ss, tmp, ',')){ s.push_back(tmp); } sort(s.begin(),s.end()); for(int i=0;i<s.size()-1;i++){ cout<<s[i]<<','; } cout<<s[s.size()-1]<<endl; }}

C語言文件操作

1. 文件類型:

    文本文件和二進位文件

數據在內存中是怎麼存儲的?

字符一律以ASCII形式存儲,數值型數據既可以用ASCII形式存儲,也可以使用二進位形式存儲

文件緩衝區:

標準C採用「緩衝文件系統」處理數據文件。緩衝文件系統 是指系統自動地在內存中為程序中每一個正在使用的文件開闢一塊「文件緩衝區」。緩衝區的大小根據C編譯系統決定。

文件指針:

緩衝文件系統中,關鍵的概念是「文件類型指針」,簡稱 文件指針。

每個被使用的文件都在內存中開闢了一個相應的文件信息區,用來存放文件的相關信息(如文件名,文件狀態,文件的當前位置等)。這些信息是保存在一個結構體變量中的。該結構體類型是由系統聲明的,取名 FILE

每當打開一個文件時,系統會根據文件的情況自動創建一個FILE結構的變量,並填充其中的信息,使用者不必關心細節。

定義pf是一個指向FILE類型數據的指針變量。可以使pf指向某個文件的文件信息區(是一個結構體變量)。通過該文件信息區中的信息就能夠訪問該文件。即,通過文件指針變量能夠找到與它關聯的文件

2. 文件讀寫操作

在編寫程序時,打開文件的同時,都會返回一個FILE*的指針變量指向該文件,也相當於建立了指針和文件的關係。

標準C(ANSIC)規定使用fopen打開文件,fclose關閉文件

FILE *fopen(const char *fileName, const char *mode);int fclose(FILE *stream);

打開方式:

文件使用方式           含義                       若指定文件不存在"r"(只讀)      為了輸入數據打開已存在的文本文件     出錯"w"(只寫)      為了輸出數據打開一個文本文件         新建"a"(追加)      向文本文件尾添加數據                出錯"rb"(只讀)     為了輸入數據打開一個二進位文件       出錯"wb"(只寫)     為了輸出數據打開一個二進位文件       新建"ab"(讀寫)     向一個二進位文件尾添加數據           出錯"r+"(讀寫)     為了讀和寫 打開一個文本文件          出錯"w+"(讀寫)     為了讀和寫 建立一個新的文件          新建"a+"(讀寫)     打開一個文件 在文件尾進行讀寫        新建"rb+"(讀寫)    為了讀和寫 打開一個二進位文件        出錯"wb+"(讀寫)    為了讀和寫 新建一個二進位文件        新建"ab+"(讀寫)    打開一個二進位文件 在文件尾進行讀和寫  新建

#define _CRT_SECURE_NO_WARNINGS 1#include <errno.h>#include <string.h>
int main(){ FILE* pf = fopen("test.txt", "r"); if (pf == NULL) { printf("%s\n", strerror(errno)); return 0;  }  fclose(pf);  pf = NULL; return 0;}

文件的順序讀寫:

功能              函數名      適用於字符輸入函數       fgetc      所有輸入流字符輸出函數       fputc      所有輸出流文本行輸入函數     fgets      所有輸入流文本行輸出函數     fputs      所有輸出流格式化輸入函數     fscanf     所有輸入流格式化輸出函數     fprintf    所有輸出流二進位輸入         fread      文件二進位輸出         fwrite     文件

int main(){  FILE* pfWrite = fopen("test.txt", "w");  if (pfWrite == NULL)  {    printf("%s\n", strerror(errno));    return 0;  }  fputc('b', pfWrite);  fputc('w', pfWrite);  fclose(pfWrite);  pfWrite = NULL;  return 0;}

鍵盤  屏幕  int main(){    int ch = fgetc(stdin);// 從標準輸入流輸入    fputc(ch,stdout);// 輸出到標準輸出流    return 0;}

int main(){  FILE* pfRead = fopen("test.txt", "r");  if (pfRead == NULL)  {    printf("%s\n", strerror(errno));    return 0;  }  char buf[1024] = { 0 };  fgets(buf, 1024, pfRead);  printf("%s", buf);  fgets(buf, 1024, pfRead);  printf("%s", buf);  fclose(pfRead);  pfRead = NULL;  return 0;  }

struct S {  int n;  float score;  char arr[10];};
int main(){ struct S s = { 100,3.14f,"hello" }; FILE* pf = fopen("test.txt", "w"); if (pf == NULL) { printf("%s\n", strerror(errno)); return 0; } fprintf(pf, "%d %f %s", s.n, s.score, s.arr); fclose(pf);  pf = NULL; return 0;}

struct S {  int n;  float score;  char arr[10];};
int main(){ struct S s = { 100,3.14f,"hello" }; struct S tmp = { 0 }; char buf[1024] = { 0 };    sprintf(buf, "%d %f %s", s.n, s.score, s.arr);   sscanf(buf, "%d %f %s", &(tmp.n), &(tmp.score), tmp.arr); printf("%d %f %s\n", tmp.n, tmp.score, tmp.arr); system("pause"); return 0;}

scanf/printf    針對標準輸入流/輸出流的 格式化輸入/輸出語句fscanf/fprintf  針對所有輸入流/輸出流的 格式化輸入/輸出語句sscanf/sprintf  從字符串中讀取格式化的數據/把格式化數據輸出成字符串

文件的隨機讀寫:

fseek:根據文件指針的位置和偏移量來定位文件指針

int fseek(FILE *stream, long int offset, int origin);

ftell:返回文件指針相對於起始位置的偏移量

long int ftell(FILE *stream);

int main(){  FILE* pf = fopen("test.txt", "r");  if (pf == NULL)    return 0;  fseek(pf, -2, SEEK_END);  int pos = ftell(pf);  printf("%d\n", pos);  fclose(pf);  pf = NULL;  return 0;}

rewind:讓文件指針的位置回到文件的起始位置

void rewind(FILE *stream)

feof:

在文件讀取過程中,不能用feof函數的返回值直接判斷文件是否結束

而是 應用於當文件讀取結束時,判斷是讀取失敗結束,還是遇到文件尾結束

文本文件讀取是否結束,判斷返回值是否為EOF(用fgetc函數時判斷EOF),或者NULL(fgets)

二進位文件的讀取結束判斷,判斷返回值是否小於實際要讀取的個數

int main(){  int c;  FILE* pf = fopen("test.txt", "r");  if (pf == NULL)  {    perror("File open failed");    return 0;  }    while ((c = fgetc(pf)) != EOF)  {    putchar(c);  }    if (ferror(pf))    puts("I/O error when reading");  else if (feof(pf))    puts("End of file reached success");
fclose(pf); pf = NULL; system("pause"); return 0;}

相關焦點

  • python+C、C++混合編程的應用
    有的語言專注於簡單高效,比如python,內建的list,dict結構比c/c++易用太多,但同樣為了安全、易用,語言也犧牲了部分性能。在有些領域,比如通信,性能很關鍵,但並不意味這個領域的coder只能苦苦掙扎於c/c++的陷阱中,比如可以使用多種語言混合編程。
  • c++的輸入與輸出
    c++輸入與輸出C++ 標準庫提供了一組豐富的輸入/輸出功能,本章將討論 C++ 編程中最基本和最常見的 I/O 操作。輸入輸出並不是c++語言的正式組成成分,c和c++沒有為輸入輸出提供專門的結構。在c語言中輸入輸出是通過調用scanf和printf 實現的,在c++中是通過調用流對象cin和cout實現的。
  • C/C++中const關鍵字詳解
    :Rational a,b;Radional c;(a*b) = c;一般用const修飾返回值為對象本身(非引用和指針)的情況多用於二目操作符重載函數並產生新對象的時候。(1) 內連接:編譯器只對正被編譯的文件創建存儲空間,別的文件可以使用相同的表示符或全局變量.C/C++中內連接使用static關鍵字指定.
  • C/C++優勢究竟在哪裡?是什麼讓他們經久不衰?看看這個你就懂了
    c語言誕生於1972年,是一個通用型命令式計算機程式語言,其支持結構化編程,詞彙變量範圍與遞歸,同時也是一種能夠預防各類未預期操作的靜態類型系統,最初的目標在於構建編寫系統軟體。相較於C語言,c++誕生於1983年,緊隨c語言的步伐,c++是C語言的超集,大家所知道的C語言是面向過程的,java是面向對象的,那麼C語言為了面向對象,所以誕生出現在大家所熟知的c++,被廣泛視為大規模應用構建軟體。
  • c語言文件操作整理
    推薦《c陷阱與缺陷》FILE *fp;fp = fopen(file, "r+");編程者也許認為,程序一旦執行上述操作完畢,就可以自由地進行讀取和寫入的操作了。遺憾的是,事實總難遂人所願,為了保持與過去不能同時進行讀寫操作的程序的向下兼容性,一個輸入操作不能隨後直接緊跟輸出操作,反之亦然。
  • c++ fstream + string 處理大數據
    (4)上面兩點算是自己的誤解吧,因為c++裡面也有也有與之對應的fstream類,c++map容器類,詳見c++ map簡介(5)c++裡面也有相對比較成熟的string類,裡面的函數也大部分很靈活,沒有的也可以很容易的實現split,strim等,詳見c++string實現(6)最近從網上,看到了一句很經典的話,c++的風fstream類 + string
  • 乾貨|C語言文件的基本操作!
    本文轉載自【微信公眾號:手機電腦雙黑客,ID:heikestudio】經微信公眾號授權轉載,如需轉載與原文作者聯繫c語言對文件的操作主要分為:按字符操作,按行操作,按內存塊操作主要的函數:fopen():FILE * fopen(_In_z_ const char * _Filename, _In_z_ const char
  • 兩道騰訊 C/C++ 面試題及答案
    C語言實現了對硬體的編程操作,也適合於應用軟體的開發;C語言還具有效率高,可移植性強等特點。在C語言的基礎上進行擴充和完善,使C++兼容了C語言的面向過程特點,又成為了一種面向對象的程序設計語言。可以使用抽象數據類型進行基於對象的編程。可以使用多繼承、多態進行面向對象的編程;可以擔負起以模版為特徵的泛型化編程。C++與C語言的本質差別:在於C++是面向對象的,而C語言是面向過程的。
  • 【C語言-52】文件操作
    const char * mode操作模式輸出:如果文件創建或打開成功,則返回一個指針。這個指針指向一個記錄文件信息的結構體FILE。其他各種文件操作函數,需要這個結構體指針才能操作對fopen打開或創建的文件進行操作。我們無需過多地關注這個結構體的具體組成,僅需要將這個結構體指針傳遞給各種文件操作函數即可。
  • C++ 文件操作看這篇文章就夠了
    :ofstream: 寫操作(輸出)的文件類 (由ostream引申而來)ifstream: 讀操作(輸入)的文件類(由istream引申而來)fstream: 可同時讀寫操作的文件類 (由iostream引申而來)打開文件(Open a file)對這些類的一個對象所做的第一個操作通常就是將它和一個真正的文件聯繫起來
  • C語言——文件的基本操作
    C語言進階合集,點我點我~~~C語言高級:01.C語言實現字符串的加密和解密02.C語言數據結構——鍊表C語言中文件的基本操作包括就可以對文件進行讀寫操作,C語言中提供了多種文件操作函數,接下來我們具體的看一下。
  • c++ fstream + string處理大數據
    (4)上面兩點算是自己的誤解吧,因為c++裡面也有也有與之對應的fstream類,c++map容器類,詳見c++map簡介(5)c++裡面也有相對比較成熟的string類,裡面的函數也大部分很靈活,沒有的也可以很容易的實現split,strim等,詳見c++string實現(6)最近從網上,看到了一句很經典的話,c++的風fstream類+string
  • C 語言會比 C++ 快?
    細節真的不那麼重要,但它有助於理解結構和大小:整個算法在一個獨立的 .cpp 文件中實現,該文件幾乎有一千行代碼(撰寫本文時為 1004 行),包括注釋,空行,帶括號的行等。該算法基本上只使用堆分配的數組作為數據結構,並使用原始指針。
  • python3使用ctypes在windows中訪問C和C++動態連結庫函數示例
    )http://ffmpeg.club/python二 C/C++部分代碼1 首先完成C/C++的動態連結庫,與做python擴展庫不同,ctypes調用的c++庫其實與python沒有代碼關聯,只是提供了開放公共標準。
  • C/C+編程筆記:const 變量詳解!一文了解具體用法
    由於分文件編寫,不好呈現,所以在這裡不為大家提供c語言全局const變量默認為外部聯編的案例。如果各讀者有興趣,可自行嘗試。 在這裡解釋一下上述代碼:第二行代碼,使用了const(expression),顯示轉換,這是由於c++比c類型轉換更嚴格。
  • C++ 的幾個for 循環,範圍for語句
    C++新標準提供的範圍for語句.這種語句遍歷給定序列中個元素並對序列中每一個值執行某種操作,其語法形式是:for(declaration : expression)   statement例子:#include <iostream>using namespace std;int main(){ string str("this is a c++"); //每行輸出str中的一個字符 for(
  • 簡要記錄丨VSCode 搭建基礎 C/C++ 編譯環境
    參考我的文件夾示例如下:3.4.1 C++ 編譯環境配置  首先在 C++ 的程序文件夾下,新建一個名為 .vscode 的隱藏文件夾,然後分別新建如下三個文件與tasks.json的label相對應24    }]25} 1{ 2    "files.defaultLanguage": "c++", // ctrl+N新建文件後默認的語言 3    "editor.formatOnType": true,  // 輸入分號(C/C++的語句結束標識)後自動格式化當前這一行的代碼 4
  • C 2 C++進階篇(1)
    首先談談筆者的水平,只學過c和數據結構,接觸過指針,對於取地址&從來沒有接觸過(因為據說是老師說不符合嚴謹的c....), python
  • c++入門教程-1
    一、C++程序的命名規則C++頭文件一般採用.h後綴,也用有.hpp的。C++程序文件一般採用.cpp後綴,也有用.cc的,建議採用.cpp,C++對程序文件的命名沒有強制要求,採用.cpp為後綴是大部分程式設計師的習慣。
  • C++知識點補充5(類型轉換、異常、流)
    c++相比c語言處理異常的優勢:函數的返回值可以忽略,但異常不可忽略。ios是抽象基類,由它派生出istream類和ostream類,兩個類名中的第一個字母i和o分別代表輸入(input)和輸出(output).istream 類支持輸入操作,ostream類支持輸出操作,iostream支持輸出和輸出操作