Exercise 24 Lập Trình C – Learn C The Hard Way


Exercise 24: Input, Output, Files

Bạn đã từng sử dụng lệnh printf? Đúng như vậy, bạn đã sử dụng rất nhiều lần để in nhiều thứ ra màn hình. Và trong bài học hôm nay, chúng ta sẽ học nhiều hơn thế nữa. Chúng ta sẽ được giới thiệu về hàm fscanffgets để xây dựng thông tin của một person trong một struct. Và sau đó, chúng ta sẽ học thêm về I/O trong C. Và trong bài học này, các bạn đa số đã được học rồi, quan trọng là các bạn nhớ được bao nhiêu.

#include <stdio.h>
#include "dbg.h"

#define MAX_DATA 100

typedef enum EyeColor {
    BLUE_EYES, GREEN_EYES, BROWN_EYES,
    BLACK_EYES, OTHER_EYES
} EyeColor;

const char *EYE_COLOR_NAMES[] = {
    "Blue", "Green", "Brown", "Black", "Other"
};

typedef struct Person {
    int age;
    char first_name[MAX_DATA];
    char last_name[MAX_DATA];
    EyeColor eyes;
    float income;
} Person;

int main(int argc, char *argv[])
{
    Person you = {.age = 0 };
    int i = 0;
    char *in = NULL;

    printf("What's your First Name? ");
    in = fgets(you.first_name, MAX_DATA - 1, stdin);
    check(in != NULL, "Failed to read first name.");

    printf("What's your Last Name? ");
    in = fgets(you.last_name, MAX_DATA - 1, stdin);
    check(in != NULL, "Failed to read last name.");

    printf("How old are you? ");
    int rc = fscanf(stdin, "%d", &you.age);
    check(rc > 0, "You have to enter a number.");

    printf("What color are your eyes:\n");
    for (i = 0; i <= OTHER_EYES; i++) { 
        printf("%d) %s\n", i + 1, EYE_COLOR_NAMES[i]); 
    } 
    printf("> ");

    int eyes = -1;
    rc = fscanf(stdin, "%d", &eyes);
    check(rc > 0, "You have to enter a number.");

    you.eyes = eyes - 1;
    check(you.eyes <= OTHER_EYES 
               && you.eyes >= 0, "Do it right, that's not an option.");

    printf("How much do you make an hour? ");
    rc = fscanf(stdin, "%f", &you.income);
    check(rc > 0, "Enter a floating point number.");

    printf("----- RESULTS -----\n");

    printf("First Name: %s", you.first_name);
    printf("Last Name: %s", you.last_name);
    printf("Age: %d\n", you.age);
    printf("Eyes: %s\n", EYE_COLOR_NAMES[you.eyes]);
    printf("Income: %f\n", you.income);

    return 0;
error:

    return -1;
}

Đây là một chương trình đơn giản, và giới thiệu về hàm fscanf, chức năng tương tự như scanf. “Dòng họ” của scanf là ngược lại với printf. Printf in dữ liệu ra ngoài dựa trên một format, còn scanf thì đọc dữ liệu vào dựa trên một format.

Phần đầu của file .c trên quá đơn giản rồi, chúng ta sẽ giải thích một chút ở hàm main.

Dòng 24 – 28: Set up một vài biến chúng ta cần.
Dòng 30 – 32: Chúng ta sẽ lấy first name từ hàm fgets (chúng ta sẽ nhập từ bàn phím), và hàm fgets sẽ đọc một chuỗi từ input (thông thường là bàn phím, và đây là trường hợp của stdin). Nhớ rằng đừng tránh lỗi overflow.
Dòng 34 – 36: Tương tự như trên nhưng dành cho biến you.last_name, tiếp tục dùng fgets.
Dòng 38 – 39: Dùng hàm fscanf để đọc một số integer từ stdin và đẩy số integer này vào biến you.age. Bạn có thể thấy rằng những format string y chăng như chúng ta dùng trong hàm printf để in số integer. Trong hàm fscanf, bạn phải cung cấp địa chỉ của biến you.age để có thể thay đổi được giá trị cho biến này.
Dòng 41 – 45: In tất cả các giá trị thuộc tính trong EYE_COLOR_NAMES.
Dòng 47 – 50: Tiếp tục sử dụng fscanf, để thiếp lập giá trị cho biến eyes bằng cấp nhập giá trị từ bàn phím, ghi nhớ rằng phải nhập một giá trị valid.
Dòng 52 – 53: Xem lại trong file dbg.h.
Dòng 56: Tương tự cho biến you.income.
Những dòng còn lại chỉ là in giá trị ra màn hình.

What You Should See

Bạn có thể thực hành bài học như sau:

$ make ex24
cc -Wall -g -DNDEBUG    ex24.c    -o ex24
$ ./ex24
What's your First Name? Zed
What's your Last Name? Shaw
How old are you? 37
What color are your eyes:
1) Blue
2) Green
3) Brown
4) Black
5) Other
> 1
How much do you make an hour? 1.2345
----- RESULTS -----
First Name: Zed
Last Name: Shaw
Age: 37
Eyes: Blue
Income: 1.234500

The I/O Functions

Dưới đây là danh sách các I/O functions mà bạn có thể phải sử dụng trong tương lai. Tìm cách nào đó để lưu nó lại và biết cách để tra cứu trên internet những hàm này:

  • fscanf
  • fgets
  • fopen
  • freopen
  • fdopen
  • fclose
  • fcloseall
  • fgetpos
  • fseek
  • ftell
  • rewind
  • fprintf
  • fwrite
  • fread

Còn nhiều hàm như thế nữa. Ví dụ họ fscanf còn những hàm như: scanf, sscanf, vscanf, ….

Trong hệ điều hành linux, khi bạn muốn xem hướng dẫn sử dụng của một hàm thì bạn có thể dùng lệnh man:

man fscanf

Extra Credit

  • Viết lại hàm trên mà không sử dụng hàm fscanf. You có thể dùng hàm atoi để chuyển từ string sang number.
  • Phân biệt scanffscanf.
  • Nếu bạn nhập một chuỗi có khoảng trắng thì bạn sẽ làm như thế nào?
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s