Một số thao tác đọc dữ liệu từ File trong C++

Ví dụ mình có file.txt gồm các dòng:
1 2 3 4
5 6 7 8
và mình chỉ muốn đọc dòng 1 chứ không đọc dòng 2 thì làm thế nào được ạ?

Bạn có thể dùng std::istream::getline. :slight_smile:

3 Likes

Ví dụ cụ thể được ko ạ?

std::vector<int> a;           // mảng int chứa các số nguyên dòng 1
std::string line;             // dòng 1
std::getline(std::cin, line); // đọc dòng 1
std::istringstream iss(line); // tạo 1 string stream từ dòng 1
for (int n; iss >> n;)        // đọc số nguyên từ stream vào mảng a
    a.push_back(n);

C++17 + đủ thứ :V

std::vector<int> a;
if (std::string line; std::getline(std::cin, line))
    if (std::istringstream iss{line})
        std::copy(std::istream_iterator<int>(iss),
                  std::istream_iterator<int>(), std::back_inserter(a));
5 Likes

Mình đọc ghi file gặp 2 cái hóc:

  1. Đọc file có đường dẫn tiếng Nhật (có thể tiếng khác cũng thế) thì không đọc ghi được do không tìm thấy đường dẫn.

  2. Mình cần phát hiện kiểu encode là ASCII hay Unicode… để đọc cho đúng.

Bạn nào giải quyết được vấn đề này chưa ?

3 Likes
  1. Phải dùng WinAPI thôi vì fstream nhận string chứ ko nhận wstring :smiley:
  2. Chỉ có thử xem có bị văng lỗi không, chứ đọc bằng code thì vẫn có khả năng chọn sai encoding.
3 Likes

Mình gặp rất nhiều rắc rối với đường dẫn wstring bao gồm cả đường dẫn file và registry.

Đến giờ mà mấy ông trùm vẫn thiết kế như vậy ai chơi cho lại @@.

2 Likes

windows nó xài 16bit string, nên tốt nhất khi code nên dùng WinAPI, nếu ko muốn banh não :))

3 Likes

đường dẫn thì xài wstring ngon lành mà :V
edit: dược mà :V

#include <iostream>
#include <fstream>
#include <string>

int main()
{
    std::wstring path = L"H:/nguyễn.txt";
    if (std::ifstream ifs{path})
    {
        std::string token;
        ifs >> token;
        std::cout << "Token = " << token << "\n";
    }
}

nếu lưu file cpp này ở utf-8 mode thì thêm flag /utf-8 vô cl:

cl /utf-8 /EHsc main.cpp

edit: có thể xài Boost.Nowide: http://cppcms.com/files/nowide/html/index.html#main

còn detect ascii hay unicode (utf-16?) thì chắc phải dựa vào 2 byte đầu tiên trong file là byte order mark (bom) 0xFEFF gì đó :V
http://unicode.org/faq/utf_bom.html#bom4

00 00 FE FF 	UTF-32, big-endian
FF FE 00 00 	UTF-32, little-endian
FE FF 		UTF-16, big-endian
FF FE 		UTF-16, little-endian
EF BB BF 	UTF-8

nếu ko thuộc trong đám này thì có cho là ascii file :V

3 Likes

ifstream, fstream, ofstream có có nhận wstring path đâu mà anh em làm nó chạy được hay vậy.

Để truyền wstring mình phải làm kiểu này:

ifstream str(string(wpath.begin(), wpath.end()),...)

Nhưng sẽ xịt với đường dẫn có tiếng Nhật.

2 Likes

với VS compiler sẽ có: https://docs.microsoft.com/en-us/cpp/standard-library/basic-ifstream-class?view=vs-2019

với MinGW thì nó theo standard ko có :V Có thể xài thử cái Nowide kia, team có cho phép xài hàng thử nghiệm ko =]]

The simple program that uses the API would work on the systems that use UTF-8 internally – the vast majority of Unix-Line operating systems: Linux, Mac OS X, Solaris, BSD. But it would fail on files like War and Peace - Война и мир - מלחמה ושלום.zip under Microsoft Windows because the native Windows Unicode aware API is Wide-API – UTF-16.

trong cái ví dụ của nó cho phép xài utf-8 trên Windows nè, thử xem có đc như nó nói ko =]

#include <boost/nowide/args.hpp>
#include <boost/nowide/fstream.hpp>
#include <boost/nowide/iostream.hpp>
int main(int argc,char **argv)
{
    boost::nowide::args a(argc,argv); // Fix arguments - make them UTF-8
    if(argc!=2) {
        boost::nowide::cerr << "Usage: file_name" << std::endl; // Unicode aware console
        return 1;
    }
    boost::nowide::ifstream f(argv[1]); // argv[1] - is UTF-8
    if(!f) {
        // the console can display UTF-8
        boost::nowide::cerr << "Can't open " << argv[1] << std::endl;
        return 1;
    }
    int total_lines = 0;
    while(f) {
        if(f.get() == '\n')
            total_lines++;
    }
    f.close();
    // the console can display UTF-8
    boost::nowide::cout << "File " << argv[1] << " has " << total_lines << " lines" << std::endl;
    return 0;
}

tốt nhất là xài MSVC, người ta bảo nhập gia tùy tục ai lại đi xài g++ trên Windows :V :V

3 Likes

Trước mình có dùng MSVC nhưng nó khó tính bm. Ném những lỗi linker, flag mò nửa ngày không fix được.

Với lại lib thì build bằng MinGW nên thằng MSVC nó không chơi. Build lại thì cả tiếng mới xong.
Mà tại thằng MinGW nó dễ tính :smile:

Boost thực sự là mình ngại dùng, cả Win API. Bởi dự định post đa nền tảng rồi dính vào sửa mệt lắm.

2 Likes

à có cái version ko depend vào boost kìa http://cppcms.com/files/nowide/nowide_standalone.zip trong code bỏ hết mấy cái boost ra là được :V
muốn đa nền tảng thì thêm vài cái #define vào ktra nếu Windows thì xài IFSTREAM là nowide::ifstream, còn ko thì xài std::ifstream
ví dụ
edit: đọc source nó thấy khỏi cần tạo file riêng :V

#include <nowide/config.hpp>
#include <nowide/fstream.hpp>

int main(int argc, char** argv)
{
    nowide::args nowide_args(argc,argv);
    ....
    nowide::ifstream ifs("D:/nguyễn.txt");
}

compiler dễ tính thì mình càng dễ code sai :V

mà code C# sao qua C++ lại đi chê hàng MS :V

3 Likes

Thực ra dùng thư viện ngoài hoặc lớp FILE thì vẫn được. Nhưng đang nói là cái yêu cầu cơ bản nhất thế lại không có trong các thư viện chuẩn thì hơi chán.

Mình làm nhiều mảng nên chơi C++ vì mảng hiện tại thì C++ làm trùm. Trước có cố làm bằng C# nhưng quá nhọc :grin:

Hàng anh Mic thì ngon nhưng mà khó tính. Toàn lỗi linker, compiler tìm mỏi mắt không thấy cách fix thì biết làm sao @@

4 Likes

bạn ơi cho mình hỏi chính xác cái toàn tử “>>” là như nào nhỉ
tại sao trong file mình ghi a b c 1 2 3 xong chạy ct thì nó lại k ra gì nữa cả :33

mình thấy đa số các bạn điều muốn đọc dữ liệu từ file nhưng mà lại ko quan tâm định dạng dữ liệu trong file như thế nào. Các bạn muốn một hàm tổng quát đọc được dữ liệu mình mong muốn chẳn hạn như số nguyên mà ko quan tâm file chứa đủ thứ như chữ cái, ký tự,… Việc này khá khó nhằn, ý tưởng của mình là nhập hết vào mảng ký tự rồi xử lý theo từng trường hợp.

1 Like

Nhu cầu, định dạng là vô vàn.
Một hàm xử lý tất cả là không cần thiết.
Mỗi định dạng sẽ có nhiều thư viện đi kèm.
Học để biết vào ra cơ bản và sau đó chứ ít khi xây dựng lại một hàm trừ trường hợp bắt buộc.

2 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?