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
123456789
(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 != '\n'; 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
123456789

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.

8 Likes

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
123456789
(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
123456789

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

6 Likes

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
123456789

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.

3 Likes

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 :astonished:

File text.txt:
nguyen chiem minh vu
123456789

Đọ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 :dizzy:

#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.

3 Likes

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

1 Like

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

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. :stuck_out_tongue_closed_eyes:

Đầ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
123456789
(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
123456789

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);
4 Likes

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
123456789
[email protected] (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: 123456789
Line 3: [email protected]

1 Like

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

File text.txt:
nguyen chiem minh vu
1234 5678 9
[email protected]

#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:

1234
5678
9

1 Like

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 :dizzy_face:

1 Like

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

2 Likes

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

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

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.

1 Like

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

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

2 Likes

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 ?

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

3 posts were split to a new topic: Truyền tập tin vào chương trình con

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