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 ạ?
Một số thao tác đọc dữ liệu từ File trong C++
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));
Mình đọc ghi file gặp 2 cái hóc:
-
Đọ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.
-
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 ?
- Phải dùng WinAPI thôi vì
fstream
nhậnstring
chứ ko nhậnwstring
- 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.
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 @@.
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 :))
đườ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
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.
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
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
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.
à 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
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
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 @@
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.
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.