檔案處理

社展專案組

什麼是檔案處理?

​​​​​​​

  • 讀取檔案 (文字檔)

  • 寫入檔案 (文字檔)

先來認識什麼是 "流" (stream)

  • 資料的移動
  • 程式在執行時會有三個標準流
    • stdin 標準輸入流
    • stdout 標準輸出流
    • stderr 標準錯誤流

在 c++ 裏面

  • cin 會讀取 stdin 的資料
  • cout 會輸出資料到 stdout
  • cerr 會輸出資料到 stderr

先來認識什麼是 "流" (stream)

一般的情況下
stdin、stdout、stderr

都會從終端機開始 / 結束

也就是說會全部顯示在終端機上面

但有些時候我們希望將輸出結果存起來

或是以檔案方式提供輸入內容,不要用手打

這時候我們就會讓stdin和stdout改導入檔案當中

how to set stdin from a file?

in terminal

./run.exe < inputfile.txt

cin 時的所有內容會從 inputfile.txt 讀取

how to set stdout to a file?

in terminal

./run.exe > outputfile.txt  #取代原本檔案
./run.exe >> outputfile.txt  #添加內容到檔案後面

cout 時的所有內容會存到 outputfile.txt

合體

in terminal

./run.exe < input.txt > output.txt  # 讀取 & 輸出到檔案

cout 時的所有內容會存到 output.txt

cin 時的所有內容會從 input.txt 讀取

在 OJ 上就是這樣將測資導入你的程式碼的

C++ 裏面的"流"

stream 類別

istream

ostream

iostream

ifstream

ofstream

stringstream

istringstream

ostringstream

fstream

<<

>>

>>

>>

>>

>>

<<

<<

<<

<<

std::cin

std::cout

基礎類別

istream

ostream

輸入 (資料流進程式)

輸出 (資料流出程式)

可用 << 運算子

可用 >> 運算子

fstream

包含三種

ifstream   ofstream    fstream

     (只讀) (只寫)(可讀可寫)

使用方法

記得先 #include <fstream>

ifstream

std::string inputFilePath = "/path/to/file";
std::ifstream fin; // 宣告fin物件
fin.open(inputFilePath); // 開啟檔案
if (!fin.is_open()) { 
    std::cerr << "file can's open\n";
    exit(0);
} 

int n;
fin >> n; // 輸入資料

fin.close(); // 關閉檔案

使用方法

記得先 #include <fstream>

ofstream

std::string outputFilePath = "/path/to/file";
std::ofstream fout; // 宣告ofstream物件
fout.open(outputFilePath); // 開啟檔案
if (!fout.is_open()) { 
    std::cerr << "file can's open\n";
    exit(0);
} 

int n;
fout << n; // 輸出資料

fout.close(); // 關閉檔案

直接取代檔案內容

使用方法

記得先 #include <fstream>

ofstream

std::string outputFilePath = "/path/to/file";
std::ofstream fout; // 宣告ofstream物件
fout.open(outputFilePath, std::ios::app); // 以append模式開啟檔案
if (!fout.is_open()) { 
    std::cerr << "file can's open\n";
    exit(0);
} 

int n;
fout << n; // 輸出資料

fout.close(); // 關閉檔案

增加檔案內容

stringstream

要記得 

#include <sstream>

 

字串流在幹嘛?

把留裡面的東西

存到字串裡

因為可以input又可以output

常常當作暫存區

用來轉換型別之類的

常配合.str()函數使用

#include <iostream>
#include <sstream>
#include <string>

using namespace std;

int main() {
    int n = 1558;
    string k;
    stringstream ss;
    
    
    ss << n;
    ss >> k; // k = "1558"
    
    ss << "erjejrjrjrjrjrj";
    ss << " 121212 23";
    
    cout << ss.str(); // 1558erjejrjrjrjrjrj 121212 23
    
    
}

Read CSV

範例程式

#include <iostream>
#include <fstream>
#include <vector>
#include <sstream>
#include <map>

using std::cout; using std::cerr;
using std::endl; using std::string;
using std::ifstream; using std::ostringstream;
using std::istringstream;

string readFileIntoString(const string& path) {
    auto ss = ostringstream{};
    ifstream input_file(path);
    if (!input_file.is_open()) {
        cerr << "Could not open the file - '"
             << path << "'" << endl;
        exit(EXIT_FAILURE);
    }
    ss << input_file.rdbuf();
    return ss.str();
}

int main()
{
    string filename("grades.csv");
    string file_contents;
    std::map<int, std::vector<string>> csv_contents;
    char delimiter = ',';

    file_contents = readFileIntoString(filename);

    istringstream sstream(file_contents);
    std::vector<string> items;
    string record;

    int counter = 0;
    while (std::getline(sstream, record)) {
        istringstream line(record);
        while (std::getline(line, record, delimiter)) {
            items.push_back(record);
        }

        csv_contents[counter] = items;
        items.clear();
        counter += 1;
    }

    exit(EXIT_SUCCESS);
}
Made with Slides.com