Thắc mắc về cách nhập dữ liệu từ file của C++

mình có một đoạn file văn bản như sau

AAAAAAAAAAAAAAMAAAAAAAAAAAAAAAWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWNWWWWWWWWWWWWWWWWWWWWWWWWAAAAAAAAAAAA
AAAAAAAAAAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFLFFFFFFFFFFFFFFFFFFFFFFFKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
QQQQQQQQQQQQQQAAAAAAQQQQQQQQQQQQQAAAQQQQQQXQQQQQQQQQQQQQQQQQQQQQQQQQQQHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH

và mục đích của mình là đếm số lần xuất hiện ký tự từ A đến Z
và sau đây là chường trình của mình

#include<bits/stdc++.h>
#define nmax 100100
#define ll long long
using namespace std;
string s;
ll arr[nmax];
int main()
{   memset(arr,0,nmax);
    ifstream f("matma.inp",ios::in);
    //freopen("matma.out","w",stdout);
    while(!f.eof())
    {
        f>>s;
        for(int i=0; i<s.size(); i++)
        {
            arr[s[i]]++;

        }

    }
    for(int i=65; i<=90; i++)
    {
       // if(arr[i]>0&&arr[i]<=9)
       // {
            cout << arr[i] << endl;
           // cout << i;
       //}
    }
}

mình ko hiểu tại sao khi cho chương trình chạy nó lại đọc cái chuỗi cuối cũng trong file dữ liệu đến 2 lần cả

Mình chạy thử thì kết quả đúng mà. Thử thêm 1 kí tự Z (chưa có trong dữ liệu gốc của bạn) vào dòng cuối, nó in đúng ra 1.

Chỉ có vấn đề này: Bạn đang phí phạm bộ nhớ một cách kinh khủng.
Bài này chỉ cần mảng char (1 byte) với 256 phần tử (tốn 256 byte cho cả mảng). Nhưng bạn lại dùng mảng kiểu long long (8 byte) với 100100 phần tử (= 8 * 100100 = 800800 byte ≈ 782 KB). Gấp 3128 lần dữ liệu tối đa cần dùng.

Chỉ A-Z nên chắc không phải Unicode đâu nhỉ.
Cho dù có dùng đến Unicode thì cũng tốn mảng wchar (2 byte) với 65536 phần tử (= 2 * 65536 = 131072 byte = 128KB). Nhỏ hơn mảng bạn khai báo cả 6 lần.

8 Likes

mình ko bt là nó tốn nhiều bộ nhớ thế nhưng mà nếu để nguyên ko thêm ấy thì nó lặp lại chuỗi cuối một lần nữa

Thật ra vấn đề bị lặp là do ở chỗ này này.
(để tạo ra bug này thì input phải có ít nhất 1 dấu enter ở dòng cuối cùng nữa)
Nếu học kỹ một chút bạn sẽ biết f.eof() sẽ trả về true khi nào, và f>>s sẽ đọc những gì vào schừa lại gì :stuck_out_tongue:
Còn không nữa, thì chỉ cần code theo convention chuẩn một chút, bạn sẽ không dùng biến s ở global làm gì cả… chỉ cần mang string s vào trong vòng while là tự nhiên sẽ hết lỗi.

Nói chung là vừa không học kỹ lưỡng, vừa code style mỳ ăn liền của CP thì bị bug là bình thường nha bạn =]]

Spoiler cách chuẩn hơn hết
std::string s;
while(f>>s){
   // do work here
}
8 Likes

vậy bạn có kiểu nào mà khai báo biến toàn cục mà nó ko bị lỗi ko cho mình tham khảo với

ý là mình nhập từ file văn bản ấy mà khai báo s toàn cục thì có cách nào để nhập ko

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