ƯỜ

Ạ Ọ

TR

Ộ NG Đ I H C BÁCH KHOA HÀ N I

Ệ Ơ Ệ Ậ Ậ Ỹ K  THU T L P TRÌNH H  C  ĐI N

TỬ

Gi ng viên

ặ : TS. TS. Đ ng Thái Vi

t

ơ ệ ử

ơ

Đ n vơ ị: B  môn C  đi n t

, Vi n C  khí

Hà N i, 09/2017

1

Programming Engineering in Mechatronics

Ệ Ơ Ệ Ử

K  THU T L P TRÌNH H  C  ĐI N T

ữ ậ

1. T ng quan v  ngôn ng  l p trình

ấ 7. C u trúc

ệ ơ ộ

2. Gi

i thi u s  b  ngôn ng  C

8. Vào/ra trong C

3. Ki u, toán t

ể  và bi u th c

ơ ở ủ 9. C  s  c a C++

4. Dòng đi u khi n

10. L pớ

ươ

ế ừ

5. Hàm và c u trúc ch

ng trình

11. K  th a và đa hình

ỏ 6. Con tr  và m ng

12. Lu ng vào/ra trong C++

2

ƯƠ CH NG 8. Vào ra trong C

8.1  Vào ra chu n – getchar và putchar 8.2  In ra theo khuôn d ngạ ạ 8.3  Nh p vào theo khuôn d ng ộ ớ ạ 8.4  Chuy n d ng trong b  nh ệ ử 8.5  X  lý t p ộ ố 8.6  M t s  hàm ti n ích

3

ẩ Vào ra chu n – getchar và putchar

1. Vào ra chuẩn – getchar và putchar

• Thư viện chuẩn

- Mỗi tệp gốc có tham trỏ tới hàm thư viện chuẩn đều phải chứa:

- Vị trí ở chỗ bắt đầu chương trình

- Tệp stdio.h định nghĩa các macro và biến cùng các hàm dùng trong thư viện vào/ra.

4

• Hàm getchar ()

- Cơ chế vào đơn giản nhất là đọc từng ký tự từ thiết bị vào chuẩn, nói chung là bàn phím và màn hình của người sử dụng, bằng hàm getchar().

- Dùng câu lệnh sau : biến = getchar(); Nhận một ký tự vào từ bàn phím và không đưa ra màn hình. Hàm sẽ trả về ký tự nhận được và lưu vào biến.

• Ví dụ:

5

ẩ Vào ra chu n – getchar và putchar

• Hàm putchar ()

- Để đưa một ký tự ra thiết bị ra chuẩn, nói chung là màn hình, ta sử dụng hàm putchar().

- Dùng câu lệnh sau : putchar(ch); Đưa ký tự ch lên màn hình tại vị trí hiện tại của con trỏ. Ký tự sẽ được hiển thị với màu trắng.

• Ví dụ:

6

ẩ Vào ra chu n – getchar và putchar

• Hàm getch()

- Hàm nhận một ký tự từ bộ đệm bàn phím, không cho hiện lên màn hình.

- Dùng câu lệnh sau : getch(); Nếu có sẵn ký tự trong bộ đệm bàn phím thì hàm sẽ nhận một ký tự trong đó. Nếu bộ đệm rỗng, máy sẽ tạm dừng. Khi gõ một ký tự thì hàm nhận ngay ký tự đó ( không cần bấm thêm phím Enter như trong các hàm nhập khác ). Ký tự vừa gõ không hiện lên màn hình.

• Ví dụ:

7

ẩ Vào ra chu n – getchar và putchar

• Hàm putch()

- Đưa ký tự “ch” lên màn hình tại vị trí hiện tại của con trỏ. Ký tự sẽ được hiển thị theo màu xác định trong hàm textcolor. Hàm cũng trả về ký tự được hiển thị.

- Dùng câu lệnh sau : putch(ch);

8

ẩ Vào ra chu n – getchar và putchar

ư ế ả Đ a k t qu  lên màn hình

2. Đưa kết quả lên màn hình

• Hàm printf(điều khiển, đối số 1, đối số 2, ...)

- Hàm printf chuyển, tạo khuôn dạng và in các đối của nó ra thiết bị ra chuẩn dưới sự điều khiển của xâu điều khiển. Xâu điều khiển chứa hai kiểu đối tượng: các ký tự thông thường, chúng sẽ được đưa ra trực tiếp thiết bị ra, và các đặc tả chuyển dạng, mỗi đặc tả sẽ tạo ra việc đổi dạng và in đối tiếp sau của printf.

9

• Chuỗi điều khiển có thể có các ký tự điều khiển

- \n sang dòng mới

- \f sang trang mới

- \b lùi lại một bước

- \t dấu tab.

- Dạng tổng quát của đặc tả : %[-][fw][.pp] ký tự chuyển dạng.

10

ư ế ả Đ a k t qu  lên màn hình

• Dấu trừ :

- Khi không có dấu trừ thì kết quả ra được dồn về bên phải nếu độ dài thực tế của kết quả ra nhỏ hơn độ rộng tối thiểu fw dành cho nó. Các vị trí dư thừa sẽ được lấp đầy bằng các khoảng trống. Riêng đối với các trường số, nếu dãy số fw bắt đầu bằng số 0 thì các vị trí dư thừa bên trái sẽ được lấp đầy bằng các số 0. - Khi có dấu trừ thì kết quả được dồn về bên trái và các vị trí dư thừa về bên phải ( nếu có ) luôn được lấp đầy bằng các khoảng trống.

11

ư ế ả Đ a k t qu  lên màn hình

fw:

- Khi fw lớn hơn độ dài thực tế của kết quả ra thì các vị trí dư thừa sẽ được lấp đầy bởi các khoảng trống hoặc số 0 và nội dung của kết quả ra sẽ được đẩy về bên phải hoặc bên trái. - Khi không có fw hoặc fw nhỏ hơn hay bằng độ dài thực tế của kết quả ra thì độ rộng trên thiết bị ra dành cho kết quả sẽ bằng chính độ dài của nó.

- Tại vị trí của fw ta có thể đặt dấu *, khi đó fw được xác định bởi giá trị nguyên của đối tương ứng.

12

ư ế ả Đ a k t qu  lên màn hình

• pp:

- Tham số pp chỉ được sử dụng khi đối tương ứng là một xâu ký tự hoặc một giá trị kiểu float hay double.

- Trong trường hợp đối tương ứng có giá trị kiểu float hay double thì pp là độ chính xác của trường ra. Nói một cách cụ thể hơn giá trị in ra sẽ có pp chữ số sau số thập phân.

- Khi vắng mặt pp thì độ chính xác sẽ được xem là 6.

13

ư ế ả Đ a k t qu  lên màn hình

ự ạ Ký t ể  chuy n d ng

3. Ký tự chuyển dạng

- Ký tự chuyển dạng là một hoặc một dãy ký hiệu xác định quy tắc chuyển dạng và dạng in ra của đối tương ứng. Như vậy sẽ có tình trạng cùng một số sẽ được in ra theo các dạng khác nhau. - Cần phải sử dụng các ký tự chuyển dạng theo đúng qui tắc định sẵn.

- Mọi dãy ký tự không bắt đầu bằng % hoặc không kết thúc bằng ký tự chuyển dạng đều được xem là ký tự hiển thị.

14

15

ự ạ Ký t ể  chuy n d ng

• Ví dụ:

16

ự ạ Ký t ể  chuy n d ng

ạ ậ Nh p vào theo khuôn d ng

4. Nhập vào theo khuôn dạng

• Số liệu từ bàn phím - hàm scanf:

- Hàm scanf là hàm đọc thông tin từ thiết bị vào chuẩn ( bàn phím ), chuyển dịch chúng ( thành số nguyên, số thực, ký tự vv.. ) rồi lưu trữ nó vào bộ nhớ theo các địa chỉ xác định.

- scanf(điều khiển,đối 1, đối 2, ...);

%[*][d...d]ký tự chuyển dạng

- dấu * nói lên rằng trường vào vẫn được dò đọc bình thường, nhưng giá trị của nó bị bỏ qua ( không được lưu vào bộ nhớ ). Như vậy đặc tả chứa dấu * sẽ không có đối tương ứng

17

- Với dòng vào : 54.32e-1 25 12452348a Kết quả là lệnh scanf sẽ gán 5.432 cho x 25.0 cho y 124 cho a xâu "523" và dấu kết thúc \0 cho ch xâu "48a" và dấu kết thúc \0 cho ct.

18

ậ ạ Nh p vào theo khuôn d ng

• Ký tự chuyển dạng:

- Ký tự chuyển dạng xác định cách thức dò đọc các ký tự trên dòng vào cũng như cách chuyển dịch thông tin đọc đựợc trước khi gán nó cho các địa chỉ tương ứng.

- Cách dò đọc thứ nhất là đọc theo trường vào, khi đó các khoảng trắng bị bỏ qua. Cách này áp dụng cho hầu hết các trường hợp. - Cách dò đọc thứ hai là đọc theo ký tự, khi đó các khoảng trắng cũng được xem xét bình đẳng như các ký tự khác. Phương pháp này chỉ xảy ra khi ta sử dụng một trong ba ký tự chuyển dạng sau : C, [ dãy ký tự ], [^ dãy ký tự ].

19

ậ ạ Nh p vào theo khuôn d ng

20

ạ ậ Nh p vào theo khuôn d ng

- Với dòng vào : 35 13145 xyz 584235 Sẽ gán : 35 cho a xâu "13145" cho ch xâu "xyz' cho ck 584 cho b.

21

ạ ậ Nh p vào theo khuôn d ng

• Đưa kết quả ra máy in:

- Để đưa kết quả ra máy in ta dùng hàm chuẩn fprintf có dạng sau.

- Tham số stdprn xác định thiết bị đưa ra là máy in. Điều khiển có dạng đặc tả như lệnh printf. Dùng giống như lệnh printf, chỉ khác là in ra máy in.

22

ạ ậ Nh p vào theo khuôn d ng

ử ệ X  lý t p

5. Xử lý tệp

5.1. Vào ra trên tệp

• Ghi tệp văn bản bằng “<<” .

- Mở tệp tin theo chế độ để ghi bằng đối tượng ofstream (mở tệp tin chỉ để ghi): ofstream (, ios::out);.

- Ghi dữliệu vào tệp bằng thao tác “<<”: <<;

- Đóng tệp tin bằng lệnh close(): .close();

23

24

ử ệ X  lý t p

• Đọc dữ liệu từ tệp văn bản bằng “>>” .

- Mở tệp tin theo chế độ để đọc bằng đối tượng ifstream (mở tệp tin chỉ để đọc): ifstream (, ios::in);

25

ử ệ X  lý t p

- Đọc dữ liệu từ tệp bằng thao tác “>>”: >>;

- Đóng tệp tin bằng lệnh close(): .close();

26

ử ệ X  lý t p

27

ử ệ X  lý t p

- Minh hoạ việc copy toàn bộ nội dung của một tệp tin sang một tệp tin mới:

28

ử ệ X  lý t p

29

ử ệ X  lý t p

ử ệ X  lý t p

5.2. Vào ra tệp nhị phân bằng read và write

• Ghi vào tệp nhị phân bằng write.

- Mở tệp tin theo chế độ để ghi nhị phân bằng đối tượng fstream: fstream (, ios::out|ios::binary); - Ghi dữliệu vào tệp bằng thao tác “write()”: .write(char* , int );

- Đóng tệp tin bằng lệnh close(): .close();

30

- Thao tác write nhận hai tham số đầu vào như sau:

- Tham số thứ nhất là con trỏ kiểu char trỏ đến vùng dữ liệu cần ghi vào tệp. Vì con trỏ bắt buộc có kiểu char nên khi muốn ghi dữ liệu có kiểu khác vào tệp, ta dùng hàm chuyển kiểu: reinterpret_cast(); - Tham sốthứhai là kích cỡ dữ liệu được ghi vào tệp. Kích cỡ này được tính theo byte, nên thông thường ta dùng toán tử: sizeof();

31

ử ệ X  lý t p

• Đọc dữ liệu từ tệp nhị phân bằng read.

- Mở tệp tin theo chế độ để đọc nhị phân bằng đối tượng fstream (mở tệp tin chỉ để ghi): fstream (, ios::in|ios::binary);

- Đọc dữ liệu từ tệp bằng thao tác “read()”: .read(char* , int );

- Đóng tệp tin bằng lệnh close(): .close();

32

ử ệ X  lý t p

ự ế ậ ệ Truy nh p t p tr c ti p

6. Truy nhập tệp trực tiếp

6.1. Con trỏ tệp tin

• Con trỏ tệp tin có vai trò như một đầu đọc trỏ vào một vị trí xác định của tệp và thao tác truy nhập tệp diễn ra tuần tự

- Tại mỗi thời điểm, con trỏ tệp tin xác định một vị trí trên tệp mà tại đó, thao tác truy nhập tệp (đọc/ghi) được thực hiện

- Sau thao tác truy nhập, con trỏ tệp tự động chuyển đến vị trí tiếp theo dựa vào kích thước đơn vị dữ liệu được truy nhập

33

• Cách truy nhập tệp tuần tự có nhược điểm là bao giờ cũng phải bắt đầu từ đầu tệp tin, đi tuần tự cho đến vị trí cần truy nhập. Khi tệp tin có kích thước lớn thì cách truy nhập này rất tốn thời gian.

• C++ cho phép truy nhập trực tiếp đến một vị trí xác định

trên tệp tin bằng các phép toán:

- Truy nhập vị trí hiện tại của con trỏ tệp tin

- Dịch chuyển con trỏ tệp tin đến một vị trí xác định

34

ự ế ậ ệ Truy nh p t p tr c ti p

ự ế ậ ệ Truy nh p t p tr c ti p

6.2. Truy nhập vị trí hiện tại của con trỏ tệp

- Nếu biến tệp là kiểu mở tệp để đọc ifstream thì cú pháp là: .tellg();

- Nếu biến tệp là kiểu mở tệp để ghi ofstream thì cú pháp là: .tellp();

35

36

ự ế ậ ệ Truy nh p t p tr c ti p

37

ự ế ậ ệ Truy nh p t p tr c ti p

ự ế ậ ệ Truy nh p t p tr c ti p

6.3. Dịch chuyển con trỏ tệp

• Ngoài việc xác định vị trí hiện thời của con trỏ tệp, C++ còn cho phép dịch chuyển con trỏ tệp đến một vị trí bất kì trên tệp. Cú pháp dịch chuyển phụ thuộc vào kiểu biến tệp là đọc hay ghi.

- Nếu biến tệp có kiểu là mở tệp tin để đọc ifstream, cú pháp sẽ : .seekg(, ); - Nếu biến tệp có kiểu là mở tệp để ghi ofstream, cú pháp sẽ là: .seekp(, );

38

- Kích thước: là tham số mô tả khoảng cách dịch chuyển so với vị trí mốc dịch chuyển. Đơn vị tính của kích thước là byte, có kiểu là số nguyên

- Mốc dịch chuyển: là vị trí gốc để xác định khoảng cách dịch chuyển của con trỏ tệp. Có ba tham số hằng về kiểu mốc dịch chuyển:

- ios::beg: Mốc dịch chuyển là đầu tệp tin.

- ios::cur: Mốc dịch chuyển là vị trí hiện thời của con trỏ tệp.

- ios::end: Mốc dịch chuyển là vị trí cuối cùng của tệp tin

39

ự ế ậ ệ Truy nh p t p tr c ti p

• Ví dụ:

ifstream fileIn(“abc.txt”, ios::in); fileIn.seekg(sizeof(char)*7, ios::beg);

- Sẽ dịch chuyển con trỏ tệp tin đến kí tự (kiểu char) thứ 7+1 = 8 trong tệp tin abc.txt để đọc (giả sử tệp tin abc.txt lưu các kí tự kiểu char).

40

ự ế ậ ệ Truy nh p t p tr c ti p

41

ự ế ậ ệ Truy nh p t p tr c ti p

42

ự ế ậ ệ Truy nh p t p tr c ti p

43

ự ế ậ ệ Truy nh p t p tr c ti p