在 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