在 C++ 中逐字讀取檔案

Jinku Hu 2023年1月30日 2021年4月29日
  1. 使用 std::ifstream 在 C++ 中逐字讀取檔案
  2. 使用 std::ispunctstd::string::erase 函式來解析 C++ 中的標點符號
在 C++ 中逐字讀取檔案

本文將演示有關如何在 C++ 中逐字讀取檔案的多種方法。

使用 std::ifstream 在 C++ 中逐字讀取檔案

std::ifstream 類可用於進行基於檔案的流的輸入操作。即,std::ifstream 型別用於與檔案緩衝區介面並使用提取運算子對其進行操作。請注意,I/O 庫中還提供了 std::fstream 型別,該型別與提取(>>)和插入運算子(<<)相容。

首先,我們需要通過呼叫其建構函式之一來建立型別為 ifstream 的物件。在這種情況下,僅將檔名字串傳遞給建構函式。建立 ifstream 物件後,應呼叫其方法之一-is_open 以驗證呼叫是否成功,然後繼續讀取檔案內容。

為了逐字讀取檔案,我們在 ifstream 物件上呼叫提取運算子。我們將其重定向到字串變數,該字串變數會在遇到第一個空格字元之前自動讀取第一個單詞。由於我們需要讀取每個單詞直到檔案末尾,因此我們將提取語句插入 while 迴圈表示式中。此外,我們宣告瞭一個字串向量,以在每次迭代中儲存每個單詞,並在以後使用單獨的迴圈塊進行列印。

#include <iostream>
#include <fstream>
#include <vector>

using std::cout; using std::cerr;
using std::endl; using std::string;
using std::ifstream; using std::vector;

int main()
{
    string filename("input.txt");
    vector<string> words;
    string word;
    
    ifstream input_file(filename);
    if (!input_file.is_open()) {
        cerr << "Could not open the file - '"
             << filename << "'" << endl;
        return EXIT_FAILURE;
    }

    while (input_file >> word) {
        words.push_back(word);
    }
    
    for (const auto &i : words) {
        cout << i << endl;
    }
    input_file.close();

    return EXIT_SUCCESS;
}

使用 std::ispunctstd::string::erase 函式來解析 C++ 中的標點符號

前一種方法的唯一缺點是它將標點符號儲存在目標詞向量中與單詞接近的位置。最好解析每個單詞,然後將它們儲存在 vector 容器中。我們正在使用 ispunct 函式,該函式將單個字元作為 int 引數,並且如果該字元為標點符號,則返回非零整數值;否則-返回零。

注意,如果給定的引數不能表示為 unsigned char,則 ispunct 函式的行為是不確定的。因此,建議將字元轉換為相應的型別。在下面的示例中,我們實現了兩個簡單的 if 條件,以檢查每個單詞的第一個和最後一個字元。如果找到了標點符號,我們將呼叫內建的字串函式 erase 來刪除找到的字元。

#include <iostream>
#include <fstream>
#include <vector>

using std::cout; using std::cerr;
using std::endl; using std::string;
using std::ifstream; using std::vector;

int main()
{
    string filename("input.txt");
    vector<string> words;
    string word;
    
    ifstream input_file(filename);
    if (!input_file.is_open()) {
        cerr << "Could not open the file - '"
             << filename << "'" << endl;
        return EXIT_FAILURE;
    }

    while (input_file >> word) {
        if (ispunct(static_cast<unsigned char>(word.back())))
            word.erase(word.end()-1);
        else if (ispunct(static_cast<unsigned char>(word.front())))
            word.erase(word.begin());
        
        words.push_back(word);
    }
    
    for (const auto &i : words) {
        cout << i << endl;
    }
    input_file.close();

    return EXIT_SUCCESS;
}
Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn

相關文章 - C++ File