【问题标题】:How to search line by line in a text file如何在文本文件中逐行搜索
【发布时间】:2019-04-25 15:09:09
【问题描述】:
123 Michael
456 Calimlim
898 Mykfyy
999 Kyxy
657 mykfyy
898 Help

我正在创建一个学生考勤系统。我的系统的一个特点是学生需要先注册(他/她的身份证和姓名)才能访问系统(用他/她的身份证登录)

问题是我不知道,我不希望我的学生有类似的 ID 号 Like(例如 898 Mykfyy 和 898 Help)

我在我的系统中使用 fstream。我一直在想,如果我想避免重复,我需要在注册(outstream)之前读取(ifstream).txt 文件。但我不知道如何逐行读取并检查 ID(898) 是否已被使用/存在

【问题讨论】:

  • 请不要将文字作为图片发布。将文本作为文本发布。
  • 不好意思,第一次发图问题~谢谢
  • 您不能只将 ID 创建为增量编号,而不是允许用户选择 ID#吗?这很容易,不需要搜索。它只需要您知道文件中有多少行(少于 10 行代码)。

标签: c++ ifstream ofstream


【解决方案1】:

在 C++ 中,人们不会处理行,而是处理对象:

#include <limits>
#include <cstdlib>
#include <vector>
#include <string>
#include <fstream>
#include <iostream>
#include <iterator>
#include <algorithm>

struct student_t
{
    unsigned id;
    std::string name;
};

bool operator==(student_t const &lhs, student_t const &rhs)
{
    return lhs.id == rhs.id;
}

std::ostream& operator<<(std::ostream &os, student_t const &student)
{
    return os << student.id << ' ' << student.name;
}

std::istream& operator>>(std::istream &is, student_t &student)
{
    unsigned id;
    if (!(is >> id))
        return is;

    std::string name;
    if (!std::getline(is, name)) {
        return is;
    }

    student = student_t{ id, name };
    return is;
}

int main()
{
    char const *filename{ "test.txt" };
    std::ifstream input{ filename };
    if (!input.is_open()) {
        std::cerr << "Couldn't open \"" << filename << "\" for reading :(\n\n";
        return EXIT_FAILURE;
    }

    std::vector<student_t> students{ std::istream_iterator<student_t>{ input }, std::istream_iterator<student_t>{} };
    input.close();

    std::copy(students.begin(), students.end(), std::ostream_iterator<student_t>{ std::cout, "\n" });

    student_t new_student;  
    while (std::cout << "New Student?\n", !(std::cin >> new_student)) {
        std::cerr << "Input error :(\n\n";
        std::cin.clear();
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    }

    auto it{ std::find(students.begin(), students.end(), new_student) };
    if (it != students.end()) {
        std::cerr << "Sorry, but a student with id " << new_student.id << " already exists :(\n\n";
        return EXIT_FAILURE;
    }

    std::ofstream output{ filename, std::ios::app };
    if (!output.is_open()) {
        std::cerr << "Couldn't open \"" << filename << "\" for writing :(\n\n";
        return EXIT_FAILURE;
    }

    output << new_student << '\n';
    std::cout << "New student [" << new_student << "] added :)\n\n";
}

【讨论】:

  • 如果文件很大,std::unsorted_map 可能是std::vector 的一个不错的选择。
  • 分叉。我总是这样做,并在所有格“它”中加上撇号。至少unordered_map 只是嘲笑我几年。 “它”几十年来一直在我的背上。
【解决方案2】:

最简单的方法可能是使用 std::getline 将当前行作为字符串获取:

using namespace std;
ifstream in(fileName);

string line;
while(getline(in, line))
{
    // --do something with the line--
}

然后您需要解析每一行以获得正确的 ID

编辑:更新以删除 eof()

【讨论】:

  • 这没有回答问题。
  • 它并没有完全解决问题,而是提供了一个起点,帮助原发者自己解决问题
  • 查看我之前的评论。
  • 公平点,更新了原始代码 - 我相信 eof 可以与 getline 一起使用,字符串只是空的
【解决方案3】:

取决于你如何实现它。

我想人数不会太多,所以我会在添加新 ID 之前检查 ID。

类似的东西 如果 ID 存在,则不添加。

【讨论】:

    猜你喜欢
    • 2022-08-18
    • 2011-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-19
    • 1970-01-01
    相关资源
    最近更新 更多