Đọc/ghi file văn bản

Một phần của tài liệu Giáo trình lập trình cc++ cơ bản (Trang 133 - 144)

8.5.1. Đọc/ghi file với hàm fprintf/fscanf Sử dụng hai hàm sau:

int fprintf(FILE *fp, const char *format [, arg, ...]);

int fscanf (FILE *fp, const char *format, address, ...);

Ví dụ 8.6: Giả sử có file văn bản chứa ma trận các số thực với cấu trúc như sau:

- Dòng đầu tiên chứa 2 số nguyên m và n tương ứng với số dòng và số cột.

- m dòng tiếp theo mỗi dòng chứa n số thực.

Hàm sau đây sẽ đọc dữ liệu từ file văn bản để lưu vào mảng 2 chiều A có kích thước m × n.

void DocFile(char *FileName,int &m,int

&n,float A[][]) {

FILE *f;

int x;

f=fopen(FileName,"rt");

fscanf(f,"%d",&x); m=x;

fscanf(f,"%d",&x); n=x;

for(int i=0;i<m;i++)

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

float xx;

fscanf(f,"%f",&xx); A[i][j]=xx;

} fclose(f);

}

Hàm sau đây sẽ ghi dữ liệu từ mảng 2 chiều A có kích thước m × n vào file văn bản.

void GhiFile(char *FileName,int m,int n,int A[MAX][MAX]) {

FILE *f = fopen(FileName,"wt");

fprintf(f,"%d %d\n", m,n);

for(int i=1;i<=m;i++) {

for(int j=1;j<=n;j++)

fprintf(f,"%f ", A[i][j]);

fprintf(f,"\n"); //xuong dong }

fclose(f);

}

8.5.2. Đọc/ghi file với <fstream>

 Mở file để ghi dữ liệu:

o ofstream <fileVar> (FileName);

 Mở file để đọc dữ liệu:

o ifstream <fileVar> (FileName);

 Đóng file:

o fileVar.close();

 Ghi dữ liệu vào file:

o fileVar<<Value1<<...<<ValueN;

 Đọc dữ liệu từ file:

o fileVar>>Var1>>Var2>>...>>VarN;

Ví dụ 8.7:

 Input: giờ, phút, giây

 Output: giờ, phút, giây tiếp theo

TIME.INP TIME.OUT

16 59 59 17 00 00

Bước 1: Tạo file TIME.INP với nội dung như đã cho.

Bước 2: Viết chương trình (viết code)

Bước 3: Chạy chương trình.

Bước 4: Mở file TIME.OUT để xem kết quả.

Sau đây là chương trình ở bước 2:

1. #include <iostream>

2. #include <fstream>

3. using namespace std;

4. int main() 5. {

6. int gio, phut,giay;

7. ifstream fi (“Time.inp”);

8. ofstream fo ("Time.out”);

9. fi>>gio>>phut>>giay;

10. giay++;

11. if(giay>59) 12. {

13. giay=0;

14. phut++;

15. }

16. if(phut>59) 17. {

18. phut=0;

19. gio++;

20. }

21. if(gio>23)

22. gio=0;

23. fo<<gio<<” “<<phut<<” “<<giay;

24. fi.close();

25. fo.close();

26. return 0;

27. }

Có thể viết cách khác:

1. #include <iostream>

2. #include <fstream>

3. using namespace std;

4. int main() 5. {

6. int gio, phut,giay;

7. FILE *fi = fopen(“Time.inp”,"rt");

8. FILE *fo = fopen("Time.out","wt");

9. fscanf(fi,"%d%d%d",&gio,&phut,&giay);

10. giay++;

11. if(giay>59) 12. {

13. giay=0;

14. phut++;

15. }

16. if(phut>59) 17. {

18. phut=0;

19. gio++;

20. }

21. if(gio>23)

22. gio=0;

23. fprintf(fo,"%d %d %d",gio,phut,giay);

24. fclose(fi);

25. fclose(fo);

26. return 0;

27. }

BÀI TẬP

Bài tập 8.1: (TUGIAC) Cho tứ giác ABCD với các đỉnh A(x1,y1), B(x2,y2), C(x3,y3) và D(x4,y4) không trùng nhau, tứ giác không chéo nhau. Hãy cho biết tứ giá ABCD là hình gì (tứ giác, thang, bình hành, chữ nhật, thoi, vuông)?

Input: Tọa độ 4 điểm A(x1,y1), B(x2,y2), C(x3,y3) và D(x4,y4) mỗi điểm trên 1 dòng

Output: Một số nguyên duy nhất (0  5) là số hiệu của hình tương ứng

0: tứ giác 1: hình thang 2: hình bình hành 3: hình thoi 4: hình chữ nhật 5: hình vuông Ví dụ:

TUGIAC.INP TUGIAC.OUT

0 0 1 3 5 3 7 0

1

Bài tập 8.2: (FIB)

Một số trong dãy Fibonacci được tính bằng cách cộng hai số liên tiếp trước nó trong dãy, trong đó phần tử đầu tiên và thứ hai đều bằng 1.

f (1) = 1, f (2) = 1, f (n > 2) = f (n - 1) + f (n - 2)

Yêu cầu: Nhập vào số nguyên dương N, hãy tìm số Fibonacci tương ứng trong dãy.

Input: Số nguyên dương N (N ≤ 10000).

Output: Số trong dãy Fibonacci tương ứng trong dãy.

Ví dụ:

FIB.INP FIB.OUT

3 2

Bài tập 8.3: (SEQ) (Olympic Tin học 2014, khối Cao đẳng)

Cho dãy số gồm 𝑛 số nguyên 𝑎1, 𝑎2, . . . , 𝑎𝑛. Một đoạn con của dãy đã cho là dãy 𝑎𝑖, . . . , 𝑎𝑗 (1 ≤ 𝑖 ≤ 𝑗 ≤ 𝑛), dãy có độ dài (𝑗 − 𝑖 + 1) và có trọng số bằng tổng (𝑎𝑖+. . . +𝑎𝑗).

Yêu cầu: Tìm đoạn con có độ dài là một số chia hết cho 3 và có trọng số lớn nhất.

Input: Vào từ file văn bản SEQ.INP có định dạng như sau:

 Dòng đầu ghi số nguyên 𝑛 (𝑛 ≥ 3);

 Dòng thứ hai ghi 𝑛 số nguyên 𝑎1, 𝑎2, . . . , 𝑎𝑛 (|𝑎𝑖| ≤ 109).

Output: Ghi ra file văn bản SEQ.OUT giá trị trọng số của đoạn con tìm được.

Ví dụ:

SEQ.INP SEQ.OUT

11

1 1 1 -9 1 1 1 1 -1 1 -9

4 Chú ý:

- Có 30% số test có 𝑛 ≤ 300;

- Có 30% số test khác có 𝑛 ≤ 3000;

- Có 40% số test còn lại có 𝑛 ≤ 300000.

Bài tập 8.4: (ROBOT) (Olympic Tin học 2013, khối Cao đẳng) Trung tâm XYZ có nhiệm vụ khảo sát mức độ phóng xạ của một khu vực nhiễm xạ gồm n địa điểm. Các địa điểm nằm trên một đường thẳng, được đánh số từ 1 đến n từ trái qua phải. Trung tâm sử dụng một robot để đo mức độ nhiễm xạ. Robot có khả năng nhận hai loại lệnh để di chuyển: Loại 1, di chuyển sang phải a bước; Loại 2, di chuyển sang trái b bước. Cụ thể, nếu robot đang đứng ở địa điểm , robot có thể thực hiện lệnh loại 1 để di chuyển đến địa điểm v+a nếu v+a ≤ n, hoặc robot có thể thực hiện lệnh loại 2 để di chuyển đến địa điểm v-b nếu v-b ≥ 1. Khi robot dừng lại tại một địa điểm, robot có thể

bật máy đo mức độ nhiễm xạ và gửi kết quả đo được về trung tâm. Tuy nhiên, do pin của robot có hạn, robot chỉ có thể thực hiện được không quá k lệnh di chuyển. Ban đầu robot được đặt ở địa điểm 1.

Ví dụ, với n = 6; a = 2; b = 3 và k = 3 có thể sử dụng robot để đo được mức độ nhiễm xạ tại các địa điểm 1, 2, 3, 5 (bao gồm cả địa điểm ban đầu của nó). Như vậy, robot không thể đo được mức độ nhiễm xạ tại các địa điểm 4 và 6.

Yêu cầu: Cho n, a, b và k, hãy đếm số địa điểm mà robot không thể đo được mức độ nhiễm xạ.

Input: Vào từ file văn bản ROBOT.INP:

 Dòng đầu ghi số T (0 < T ≤ 10) là số bộ dữ liệu có trong file;

 Dòng sau, mỗi dòng chứa bốn số nguyên dương n, a, b và k (a,b ≤ n ≤ 109, k ≤ 1000).

Output: Đưa ra file văn bản ROBOT.OUT gồm dòng, mỗi dòng là số lượng địa điểm mà robot không thể đo được mức độ nhi m xạ của bộ dữ liệu vào tương ứng.

Ví dụ:

ROBOT.INP ROBOT.OUT

2 6 2 3 3 100 99 1 100

2 0

Bài tập 8.5: (SHOWTV) (Olympic Tin học 2011, khối Cao đẳng) Khi có quá nhiều kênh truyền hình với rất nhiều chương trình giải trí thú vị, bạn sẽ chọn lựa xem những chương trình nào? Đây quả là một câu hỏi khó.

n chương trình giải trí, chương trình thứ i (1 ≤ i n) có thời điểm bắt đầu là si và thời điểm kết thúc là ti. Chương trình giải trí thứ i và chương trình giải trí thứ j (với 1 ≤ i<j n) được gọi là không phù hợp với nhau về lịch phát sóng nếu người xem không thể xem trọn vẹn nội dung của cả hai chương trình giải trí này.

Nếu thời điểm kết thúc ti của chương trình i là thời điểm bắt đầu sj của chương trình j thì hai chương trình này vẫn được xem là có lịch phát sóng phù hợp với nhau.

Ví dụ: Có 3 chương trình giải trí như sau: Chương trình 1 (s1 = 7, t1 = 10), chương trình 2 (s2 = 12, t2 = 15), chương trình 3 (s3 = 10, t3 = 20). Chương trình 1 và chương trình 2 có lịch phát sóng phù hợp với nhau. Tương tự, chương trình 1 và chương trình 3 cũng được xem là có lịch phát sóng phù hợp với nhau. Tuy nhiên, chương trình 2 và chương trình 3 có lịch phát sóng không phù hợp với nhau.

Yêu cầu: Cho biết kế hoạch phát sóng của N chương trình giải trí, hãy xác định có bao nhiêu cặp chương trình có lịch phát sóng không phù hợp với nhau.

Input: Vào từ file văn bản SHOWTV.INP với cấu trúc như sau:

 Dòng đầu tiên chứa một số nguyên dương n (với n ≤ 50 000),

 Dòng thứ i trong số n dòng tiếp theo (1 ≤ i n), mỗi dòng gồm hai số nguyên dương si ti là thời điểm bắt đầu và thời điểm kết thúc của chương trình giải trí thứ i (với 1 ≤ si < ti ≤ 105) .

Các số trên cùng một d.ng được ghi cách nhau bởi 1 khoảng trắng.

Output: Đưa ra file văn bản SHOWTV.OUT một số nguyên - số lượng cặp chương trình có lịch phát sóng không phù hợp với nhau.

Ví dụ:

SHOWTV.INP SHOWTV.OUT

3 7 10 12 15 10 20

1

Bài tập 8.6: (FIRSTNUM) Các số thập phân 1,2,3,… được ghi liên tiếp thành dãy như sau: 123456789101112131415161718192021…

Cho số nguyên dương N. Tìm ra vị trí xuất hiện đầu tiên của N trong dãy số.

Input: Số N, 1 ≤ N ≤ 100,000.

Output: Vị trí xuất hiện đầu tiên của số N trong dãy.

Ví dụ:

FIRSTNUM.INP FIRSTNUM.OUT

34 3

Bài tập 8.7: (KEY) Bé Misa có một ổ khóa được mở bằng mật khẩu số. Ở trên ổ khóa có n vòng xoay và mỗi vòng xoay được đánh số từ 0 đến 9. Sau khi cài đặt mật khẩu xong, Misa muốn mở khóa ra với mật khẩu đã biết.

Yêu cầu: Hãy giúp bé Misa tìm số bước xoay ít nhất tại mỗi vòng xoay để tiết kiệm thời gian khi mở khóa.

Input:

o Dòng đầu: n là độ dài của mật khẩu (1 ≤ n ≤ 1000).

o Dòng thứ hai: gồm n kí tự là trạng thái hiện thời của các vòng xoay trên ổ khóa.

o Dòng thứ ba: gồm n kí tự là mật khẩu của khóa.

Output: Một số nguyên duy nhất là số lần xoay đĩa ít nhất có thể.

Ví dụ:

KEY.INP KEY.OUT

5 82195 64723

13

Bài tập 8.8: (BRACKETS) (Olympic Tin học 2010, khối Cao đẳng) Gọi xâu chỉ chứa các ký tự ngoặc tròn (, ), ngoặc vuông [, ] và ngoặc nhọn {, } là xâu ngoặc. Xâu ngoặc đúng được định nghĩa như sau:

 Xâu rỗng được coi là xâu ngoặc đúng,

 Nếu a là xâu ngoặc đúng thì (a), [a], {a} cũng là các xâu ngoặc đúng,

 Nếu a b là các xâu ngoặc đúng thì ab cũng là xâu ngoặc đúng.

Cho xâu S = s1s2…sn độ dài n. Với k >1, xâu sksk+1sk+2…sns1s2…sk-1 được gọi là xâu đẩy vòng thứ k của S. Ta quy ước bản thân xâu S cũng là một xâu đẩy vòng của S với k=1.

Yêu cầu: Cho xâu ngoặc S có độ dài không quá 1000. Hãy xác định có tồn tại một xâu đẩy vòng của S là xâu ngoặc đúng hay không.

Trong trường hợp câu trả lời là khẳng định hãy đưa ra vị trí k nhỏ nhất.

Input: Vào từ file văn bản BRACKETS.INP gồm một dòng chứa xâu S.

Output: Đưa ra file văn bản BRACKETS.OUT vị trí k tìm được, trong trường hợp không có lời giải, ghi ra số 1.

Vi dụ:

BRACKETS.INP BRACKETS.OUT

}{}(){ 2

Bài tập 8.9: (NGHICHTHE) Cho dãy số nguyên dương a gồm N phần tử khác nhau đôi một. Tìm 2 chỉ số i,j thỏa: i < j; ai > aj; j - i = max (xa nhất). Nếu không tìm được nghịch thế, in ra -1.

Input:

- Dòng đầu: chứa số N < 106

- Dòng sau: chứa dãy số a1 a2 ... aN, i,j: ai ≠ aj. (ai<106) Output:

Ghi ra 2 chỉ số I, j sao cho j - i  max Ví dụ:

NGHICHTHE.INP NGHICHTHE.OUT

10

4 1 2 8 6 9 13 16 3 5

1 9 10

1 2 3 4 5 6 7 8 9 12

-1

Bài tập 8.10: (MODFACT) (ACM VietNam 2011)

Cho một số nguyên 1 < N ≤ 109. Hãy kiểm tra xem N! có chia hết cho N3?

Input:

 Dòng đầu tiên là số T (1 ≤ T ≤ 20), với T là số bộ test

 Mỗi dòng tiếp theo là một số nguyên N.

Output:

 Với mỗi giá trị vào N, kết quả ra là YES/NO tương ứng với N! mod N3 hay không, mỗi kết quả viết trên một dòng.

Ví dụ:

MODFACT.INP MODFACT.OUT

2 6 12

NO YES

PHỤ LỤC 1

SỬ DỤNG MỘT SỐ LỚP CỦA THƯ VIỆN STL

STL (Standard Template Library) là thư viện chuẩn của C++

được xây dựng sẵn với một số các cấu trúc dữ liệu và thuật toán thông dụng.

Để thuận tiện hơn cho việc xử lý các vấn đề về lập trình, các lập trình viên C++ cần biết sử dụng và khai thác các lớp chứa phục vụ cho công việc lập trình.

Một phần của tài liệu Giáo trình lập trình cc++ cơ bản (Trang 133 - 144)

Tải bản đầy đủ (PDF)

(176 trang)