30/09/2018, 16:24

Tổng hợp: đọc file bằng C++ và C

Mình tìm thấy nhiều cách đọc file bằng C++ vào std::string khác nhau, post tạm 1 cách đã, có thời gian post dần thêm.

Cách đầu tiên là đọc file bằng istreambuf_iterator. Ví dụ cụ thể:

File text.txt lưu với nội dung như sau:

nguyen chiem minh vu
01216558383
(EOF)

Và đọc file như vầy:

#include <iostream>
#include <fstream>

using namespace std;

int main()  {

    ifstream textfile("text.txt");
    string s1; //store a line of file

    for(istreambuf_iterator<char,char_traits<char> > it(textfile.rdbuf());
         *it != '
'; it++)   {

        s1 += *it; //append at end of string
    }

    cout << s1.data() << endl;

    return 0;
}

Output:
nguyen chiem minh vu

Giả sử các bạn thay cái phần đọc file vào string thành như sau:

for(istreambuf_iterator<char,char_traits<char> > it(textfile.rdbuf());    
     it != istreambuf_iterator<char,char_traits<char> >(); it++)   {

        s1 += *it; //append at end of string
}

Thì output sẽ là:

nguyen chiem minh vu
01216558383

Phần trên là một trong số những cách đọc file trong C++, bữa khác mình post thêm.

... viết 18:25 ngày 30/09/2018

Tiếp theo là sử dụng lớp stringstream để đọc nội dung file text.txt nội dung như ở trên:

File text.txt:
nguyen chiem minh vu
01216558383
(EOF)

Và đọc file như sau:

#include <iostream>
#include <fstream>
#include <sstream>

using namespace std;

int main()  {

    ifstream textfile("text.txt");
    string s1; //store a line of file

    stringstream ss;
    ss << textfile.rdbuf(); //pass data in buffer into stream ss
    s1 = ss.str(); //assign to s1 string

    cout << s1.data() << endl;

    return 0;
}

Output:
nguyen chiem minh vu
01216558383

Đây cũng là một cách để hốt toàn bộ kí tự trong file vào string.

... viết 18:30 ngày 30/09/2018

Cách tiếp theo là các bạn khởi tạo giá trị cho constructor của class string luôn.
Cũng file text.txt cùng nội dung như ở trên, ta đọc file như sau:

#include <iostream>
#include <fstream>
#include <sstream>

using namespace std;

int main()  {

    ifstream textfile("text.txt");
    string s1(istreambuf_iterator<char>(textfile.rdbuf()),istreambuf_iterator<char>());

    cout << s1.data() << endl;

    return 0;
}

Output:
nguyen chiem minh vu
01216558383

Nếu các bạn không muốn dùng constructor, thì có thể thay lại như sau:

string s1;

s1.assign(istreambuf_iterator<char>(textfile.rdbuf()),istreambuf_iterator<char>());

Kết quả vẫn tương tự như ở trên.

... viết 18:25 ngày 30/09/2018

Sau một hồi đọc file vào string theo kiểu màu mè, thì bây giờ trở lại với kiểu cổ điển vậy

File text.txt:
nguyen chiem minh vu
01216558383

Đọc file:

#include <iostream>
#include <fstream>
using namespace std;

int main()  {

    ifstream fileinput("text.txt");
    string s;

    while(!fileinput.eof()) {

        char c;
        fileinput.get(c); //read a character
        s += c;
    }

    cout << s.data() << endl;
    return 0;
}

Nội dung in ra là toàn bộ file. Vậy muốn đọc từng dòng thì nàm thao? Không rõ đọc vào std::string thì thế nào, thôi thì đọc tạm vào kiểu char[] vậy

#include <iostream>
#include <fstream>
using namespace std;

int main()  {

    ifstream fileinput("text.txt");
    //string s;
    char temp[255];
    int line_number = 1;

    while(fileinput.getline(temp,255)) {

        cout << "Line " << line_number++ << ": " << temp << endl;
    }

    return 0;
}

Thông thường các bạn đọc file bằng vòng lặp while như trên hay dùng điều kiện là:

while(!fileinput.eof())     {

     fileinput.getline(temp,255);
}

Thì sẽ in ra thừa 1 dòng trống, do nó đọc riêng kí tự EOF vào temp một lần nữa. Dùng cách ở trên kia sẽ không bị đọc thừa.

... viết 18:26 ngày 30/09/2018

Còn sót mất kiểu đọc file trong C++ nào không anh @ltd nhỉ?

Nguyễn Minh Dũng viết 18:28 ngày 30/09/2018

Mấy cách em liệt kê ra ở đây anh cũng không biết hết

... viết 18:31 ngày 30/09/2018

C++ chán rồi giờ về lại C phát, do lâu rồi không dùng nên có sót thì nhờ thánh C @ltd bổ sung phát.

Đầu tiên là cách múc toàn bộ file text vào xâu kí tự. Giả sử file text như sau:

nguyen chiem minh vu
0121 655 8383
(EOF)

Đọc file như sau:

#include <stdio.h>
#include <stdlib.h>

int main()  {

    FILE* f = fopen("text.txt","r");
    if(f == NULL)   {

        printf("Error orcured when open file\n");
        exit(1);
    }

    fseek(f,0,SEEK_END);
    int n = ftell(f); //count the length of file
    rewind(f); // f pointer will point at begin of file

    char* s = new char[n+1]; //use dynamic allocate
    fscanf(f,"%[^EOF]",s); // read file into string, only ignore EOF character
    puts(s);
    delete[] s;
    fclose(f);

    return 0;
}

Vậy là xâu s khi in ra sẽ có nội dung như sau:

nguyen chiem minh vu
0121 655 8383

Nghĩa là toàn bộ kí tự trong file đã được hốt vào xâu.

Nếu chỉ muốn đọc một dòng, thì thay dòng fscanf thành như sau:

fscanf(f,"%[^\n],s);

hoặc

fgets(s,255,f);
... viết 18:30 ngày 30/09/2018

Tiếp đến là kiểu đọc toàn bộ file nhưng in ra từng dòng.

File text nội dung như sau:

nguyen chiem minh vu
0121 655 8383
nguyenchiemminhvu@gmail.com (EOF)

Đọc file như sau:

#include <stdio.h>
#include <stdlib.h>

int main()  {

    FILE* f = fopen("text.txt","r");
    if(!f)  {

        printf("Error orcured when open file\n");
        exit(0);
    }

    char line[255];
    int i = 1;
    while(fgets(line,255,f))    {

        printf("Line %d: %s",i++,line);
    }

    fclose(f);
    return 0;
}

Result:

Line 1: nguyen chiem minh vu
Line 2: 0121 655 8383
Line 3: nguyenchiemminhvu@gmail.com

... viết 18:40 ngày 30/09/2018

Test thử đọc file (chỉ đọc số nguyên) trong C++ phát:

File text.txt:
nguyen chiem minh vu
0121 655 8383
nguyenchiemminhvu@gmail.com

#include <iostream>
#include <fstream>
#include <sstream>

using namespace std;

int main()  {

        fstream f("text.txt");
        if(!f)  {

            cerr << "Error orcured when open this file" << endl;
            return 1;
        }

        string line;

        int i = 0;
        int a[255];
        while(getline(f,line))  {

            stringstream ss(line);
            int n;
            while(ss >> n)   {

                a[i] = n;
                i++;
            }
        }
        for(int j = 0; j < i-1; j++)    {

            cout << a[j] << " ";
        }
        cout << endl;

        f.close();
        return 0;
}

Nội dung in ra:

121
655
8383

... viết 18:25 ngày 30/09/2018

Thử chuyển code trên từ C++ qua C xem thế nào:

#include <stdio.h>
#include <stdlib.h>

int main()  {

    FILE* f = fopen("text.txt","r");
    if(!f)  {

        printf("Error orcured when open this file\n");
        exit(0);
    }

    char line[255];
    int a[255];
    int i = 0;
    while(fgets(line,255,f))    {

        int n;
        while(sscanf(line,"%d",&n))  {

            a[i] = n;
            i++;
        }
    }

    int j;
    for(j = 0; j < i; j++)  {

        printf("%d\n",a[j]);
    }
    return 0;
}

Code block báo lỗi segment fault rồi anh @ltd ơi

Gió viết 18:31 ngày 30/09/2018

Segment fault là do vòng while trong sscanf nó không chịu dừng lại

Nguyễn Minh Dũng viết 18:37 ngày 30/09/2018

I moved 3 posts to an existing topic: Off-topic will be moved here

Thanh Sang Cao viết 18:27 ngày 30/09/2018

Cho e hỏi cách đọc file thỏa mãn dữ liệu đầu vào như sau :Dòng 1 ghi số bộ test, mỗi bộ test ghi trên 1 dòng xâu ký tự họ tên
VD có dữ liệu file:
3
Nguyen Van Nam
Do Van A
Tran Thi B

... viết 18:32 ngày 30/09/2018

Trong C bạn có những hàm như fgetc, fgets… để đọc 1 kí tự, đọc 1 xâu, hay fscanf để đọc 1 định dạng nào đó. Cái gì cần đọc trước thì định dạng trước.
http://www.tutorialspoint.com/c_standard_library/c_function_fscanf.htm
Bạn coi người ta làm rồi làm theo.

Sáng Béo viết 18:36 ngày 30/09/2018

C++ chán rồi giờ về lại C phát

char* s = new char[n+1];

lêu lêu, C thì ko cấp phát bằng new ạ. lêu lêu…

... viết 18:34 ngày 30/09/2018


Bị phát hiện rồi, phải flag để bịt đầu mối mới được

Lộc Ninh Trường Thpt viết 18:26 ngày 30/09/2018

Em chào anh. Anh ơi anh có thể chỉ em cách làm đọc 1 file như sau:
Tran Trinh Quoc Viet 1552005 7,8 8,9 6,7
Trong đó Ten : Tran Trinh Quoc Viet
MSSV 1552005 . 2 cái này là kiểu char[255]
Còn 7,8 8,9 6,7 là điểm toán lý hoá kiểu float.
Bây giờ em muốn đọc file này xong tính toán toán ra điểm trung bình của toán lý hoá thì em phải làm sao hả anh. Anh có thể giới thiệu hàm hoặc cách làm cho em được không ?

Phong Phú Vũ viết 18:27 ngày 30/09/2018

Cho em hỏi. nếu mình đọc file bằng getline và stringstream thì khi gặp dòng trống thì làm cách nào để mình lược bỏ nó đi

Bài liên quan
0