프로그래밍/C언어

[쉽게 풀어쓴 C언어 Express 개정4판] 15장 Exercise & Programming

곰탱이들 2024. 10. 17.

15장 Exercise & Programming

14장 Exercise

 

1. 다음 중 표준 파일 스트림이 아닌 것은?

정답: 4번 stdcon

 

2. 다음은 표준 입출력 함수들에 대한 설명이다. 설명에 가장 일치하는 함수를 보기에서 골라서 쓰시오.

 

1) fflush()

2) fgets()

3) feof()

4) fscanf()

 

3. 파일의 시작 부분으로 파일 포인터를 이동시키는 문장은?

정답: 3번 fseek(fp, 0L, SEEK_SET);

 

4. 다음의 설명에 적합한 문장을 작성하시오.

 

a) FILE *afp = fopen("junk.txt", "a");
b) FILE *pfp = fopen("para.txt", "r+");
c) FILE *bfp = fopen("company.dat", "rb");

 

5. 텍스트 파일을 읽다가 쓰기도 하고자 한다. 어떤 파일 모드로 열어야 하는가?

정답: 4번 "r+"

 

6. XXX 함수는 표준 입력 스트림에서 하나의 문자를 읽어서 반환한다.

정답: 4번 getchar()

 

7. 다음 중에서 이진 파일에서 올바르게 읽은 문장을 모두 선택하시오.

FILE *fp = fopen("TEST.DAT", "rb");
char buffer[200];

정답: 2, 3번 fread(buffer, 100, 1, fp); fread(buffer, 1, 300, fp);

 

8. 다음 프로그램의 오류를 지적하시오. 오류는 하나 이상일 수도 있다.

#include <stdio.h>

struct test {
    int a;
    float b;
} record;

int main(void) {
    FILE *fp = fopen("TEST.DAT", "rb");
    fread(record, sizeof(record), 1, fp);
    fclose(fp);
    return 0;
}

정답

- fread() 함수의 첫 번째 인수로 구조체 record를 그대로 전달할 수 없습니다. 주소를 전달해야 하므로 &record로 수정해야 합니다

- 파일 포인터 fp를 열었는지 확인하는 조건문이 필요합니다 (if (fp == NULL))

 

9. 다음 프로그램의 실행 결과를 쓰시오.

#include <stdio.h>

int main(void) {
    int i;
    long int pos;
    FILE *fp = fopen("test.dat", "w+b");

    for (i = 0; i < 10; i++) {
        fwrite(&i, sizeof(int), 1, fp);
    }

    pos = ftell(fp);
    pos -= 8;
    fseek(fp, pos, 0);
    fread(&i, sizeof(int), 1, fp);
    printf("i = %d\n", i);

    fclose(fp);
    return 0;
}

정답: i = 8

 

15장 Programming

 

1. 텍스트 파일 proverbs.txt를 읽어서 각 줄의 앞에 줄 번호를 붙여서 화면에 출력하는 프로그램을 작성하라.

#include <stdio.h>

int main(void) {
    FILE *fp = fopen("proverbs.txt", "r");
    char buffer[256];
    int line_number = 1;

    if (fp == NULL) {
        printf("파일을 열 수 없습니다.\n");
        return 1;
    }

    while (fgets(buffer, sizeof(buffer), fp) != NULL) {
        printf("%d: %s", line_number++, buffer);
    }

    fclose(fp);
    return 0;
}

 

2. 텍스트 파일을 열어서 파일 안에 들어 있는 문자열을 모두 대문자로 변경하여 새로운 파일에 저장하는 프로그램을 작성하라. 새로운 파일을 화면에 출력하여 확인하자.

#include <stdio.h>
#include <ctype.h>

int main(void) {
    FILE *fp_in = fopen("proverbs.txt", "r");
    FILE *fp_out = fopen("test2.txt", "w");
    char ch;

    if (fp_in == NULL || fp_out == NULL) {
        printf("파일을 열 수 없습니다.\n");
        return 1;
    }

    while ((ch = fgetc(fp_in)) != EOF) {
        fputc(toupper(ch), fp_out);
    }

    fclose(fp_in);
    fclose(fp_out);

    fp_out = fopen("test2.txt", "r");
    while ((ch = fgetc(fp_out)) != EOF) {
        putchar(ch);
    }
    fclose(fp_out);
    return 0;
}

 

3. 두 개의 텍스트 파일을 서로 비교하는 프로그램을 작성하여보자. 파일의 이름은 사용자에게 입력받는다. 만약 두 개의 파일이 일치하면 "파일은 서로 일치함"을 출력하며 일치하지 않으면 첫 번째 문장과 다음과 같이 출력한다.

#include <stdio.h>
#include <string.h>

int main(void) {
    char file1[100], file2[100];
    FILE *fp1, *fp2;
    char line1[256], line2[256];
    int line_number = 1;

    printf("첫 번째 파일 이름: ");
    scanf("%s", file1);
    printf("두 번째 파일 이름: ");
    scanf("%s", file2);

    fp1 = fopen(file1, "r");
    fp2 = fopen(file2, "r");

    if (fp1 == NULL || fp2 == NULL) {
        printf("파일을 열 수 없습니다.\n");
        return 1;
    }

    while (fgets(line1, sizeof(line1), fp1) != NULL &&
           fgets(line2, sizeof(line2), fp2) != NULL) {
        if (strcmp(line1, line2) != 0) {
            printf("<< %s\n>> %s\n", line1, line2);
            fclose(fp1);
            fclose(fp2);
            return 0;
        }
        line_number++;
    }

    if (fgets(line1, sizeof(line1), fp1) == NULL &&
        fgets(line2, sizeof(line2), fp2) == NULL) {
        printf("파일은 서로 일치함\n");
    } else {
        printf("파일 길이가 다름\n");
    }

    fclose(fp1);
    fclose(fp2);
    return 0;
}

 

4. 다음과 같이 학생의 교과목 성적이 저장되어 있는 텍스트 파일을 읽어 성적의 평균을 구하여 다른 파일에 쓰는 프로그램을 작성해보자. 평균은 소수점 2자리까지 출력하도록 하라.

#include <stdio.h>

int main(void) {
    FILE *fp_in = fopen("scores.txt", "r");
    FILE *fp_out = fopen("averages.txt", "w");
    char name[50];
    int kor, math, eng;
    double average;

    if (fp_in == NULL || fp_out == NULL) {
        printf("파일을 열 수 없습니다.\n");
        return 1;
    }

    while (fscanf(fp_in, "%s %d %d %d", name, &kor, &math, &eng) == 4) {
        average = (kor + math + eng) / 3.0;
        fprintf(fp_out, "%s %.2f\n", name, average);
    }

    fclose(fp_in);
    fclose(fp_out);
    return 0;
}

 

5. 사용자로부터 받은 파일 이름으로 텍스트 파일을 연 후에 파일 안에 들어 있는 문자의 개수와 단어들의 개수를 계산하여 출력해보자.

#include <stdio.h>
#include <ctype.h>

int main(void) {
    FILE *fp;
    char filename[100];
    int char_count = 0, word_count = 0;
    char ch;
    int in_word = 0;

    printf("파일 이름: ");
    scanf("%s", filename);

    fp = fopen(filename, "r");
    if (fp == NULL) {
        printf("파일을 열 수 없습니다.\n");
        return 1;
    }

    while ((ch = fgetc(fp)) != EOF) {
        char_count++;
        if (isspace(ch)) {
            if (in_word) {
                word_count++;
                in_word = 0;
            }
        } else {
            in_word = 1;
        }
    }

    if (in_word) {
        word_count++;
    }

    fclose(fp);

    printf("문자의 개수는 %d\n", char_count);
    printf("단어의 개수는 %d\n", word_count);

    return 0;
}

 

6. 사용자가 입력하는 텍스트를 파일에 저장하게 하는 프로그램을 작성하여보자. 사용자가 Ctrl-Z를 입력하면 종료하는 것으로 가정한다.

#include <stdio.h>

int main(void) {
    FILE *fp = fopen("test.c", "w");
    char buffer[256];

    if (fp == NULL) {
        printf("파일을 열 수 없습니다.\n");
        return 1;
    }

    printf("파일에 저장할 내용을 입력하세요 (Ctrl+Z로 종료):\n");
    while (fgets(buffer, sizeof(buffer), stdin) != NULL) {
        fputs(buffer, fp);
    }

    fclose(fp);
    printf("입력이 종료되었습니다.\n");

    return 0;
}

 

7. 명령 프롬프트에서 인수로 주어진 2개의 텍스트 파일을 합하여 하나의 파일로 저장하는 프로그램을 작성해보자.

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    if (argc != 4) {
        printf("사용법: %s 파일1 파일2 출력파일\n", argv[0]);
        return 1;
    }

    FILE *fp1 = fopen(argv[1], "r");
    FILE *fp2 = fopen(argv[2], "r");
    FILE *fp_out = fopen(argv[3], "w");

    if (fp1 == NULL || fp2 == NULL || fp_out == NULL) {
        printf("파일을 열 수 없습니다.\n");
        return 1;
    }

    char ch;
    while ((ch = fgetc(fp1)) != EOF) {
        fputc(ch, fp_out);
    }
    while ((ch = fgetc(fp2)) != EOF) {
        fputc(ch, fp_out);
    }

    fclose(fp1);
    fclose(fp2);
    fclose(fp_out);

    printf("%s 파일과 %s 파일을 합하여 %s 파일로 저장합니다.\n", argv[1], argv[2], argv[3]);

    return 0;
}

 

8. 텍스트 파일 proverbs.txt를 읽어서 사용자가 지정하는 줄을 삭제하는 프로그램을 작성해보자.

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    FILE *fp_in = fopen("proverbs.txt", "r");
    FILE *fp_out = fopen("temp.txt", "w");
    char buffer[256];
    int line_to_delete, current_line = 1;

    if (fp_in == NULL || fp_out == NULL) {
        printf("파일을 열 수 없습니다.\n");
        return 1;
    }

    printf("삭제를 원하는 줄 번호: ");
    scanf("%d", &line_to_delete);

    while (fgets(buffer, sizeof(buffer), fp_in) != NULL) {
        if (current_line != line_to_delete) {
            fputs(buffer, fp_out);
        }
        current_line++;
    }

    fclose(fp_in);
    fclose(fp_out);

    remove("proverbs.txt");
    rename("temp.txt", "proverbs.txt");

    printf("줄이 삭제되었습니다.\n");

    return 0;
}

 

9. 텍스트 파일에서 특정한 단어를 찾아서 다른 단어로 변경하여 출력 파일에 쓰는 프로그램을 작성해보자.

#include <stdio.h>
#include <string.h>

int main(void) {
    FILE *fp_in = fopen("android.txt", "r");
    FILE *fp_out = fopen("android_updated.txt", "w");
    char buffer[256];
    char *target = "Android";
    char *replacement = "안드로이드";

    if (fp_in == NULL || fp_out == NULL) {
        printf("파일을 열 수 없습니다.\n");
        return 1;
    }

    while (fgets(buffer, sizeof(buffer), fp_in) != NULL) {
        char *pos = strstr(buffer, target);
        if (pos) {
            *pos = '\0';
            fprintf(fp_out, "%s%s%s", buffer, replacement, pos + strlen(target));
        } else {
            fputs(buffer, fp_out);
        }
    }

    fclose(fp_in);
    fclose(fp_out);

    printf("단어가 변경되었습니다.\n");

    return 0;
}

 

10. 사용자가 지정하는 텍스트 파일을 읽어서 시저 암호 방법으로 암호화된 파일을 생성하는 프로그램을 작성해보자.

#include <stdio.h>

int main(void) {
    char filename[100];
    int shift;
    printf("파일 이름을 입력하세요: ");
    scanf("%s", filename);
    printf("이동 거리를 입력하세요: ");
    scanf("%d", &shift);

    FILE *fp_in = fopen(filename, "r");
    FILE *fp_out = fopen("encrypted.txt", "w");
    char ch;

    if (fp_in == NULL || fp_out == NULL) {
        printf("파일을 열 수 없습니다.\n");
        return 1;
    }

    while ((ch = fgetc(fp_in)) != EOF) {
        if (ch >= 'A' && ch <= 'Z') {
            ch = (ch - 'A' + shift) % 26 + 'A';
        } else if (ch >= 'a' && ch <= 'z') {
            ch = (ch - 'a' + shift) % 26 + 'a';
        }
        fputc(ch, fp_out);
    }

    fclose(fp_in);
    fclose(fp_out);

    printf("암호화된 파일이 생성되었습니다.\n");

    return 0;
}

 

11. 하드 디스크에서 파일을 삭제하는 프로그램을 작성해보자.

#include <stdio.h>

int main(void) {
    char filename[100];
    printf("파일 이름을 입력하세요: ");
    scanf("%s", filename);

    if (remove(filename) == 0) {
        printf("%s가 성공적으로 삭제되었습니다.\n", filename);
    } else {
        printf("%s 파일을 삭제하는 데 실패했습니다.\n", filename);
    }

    return 0;
}

 

12. 사람들의 이름과 전화번호를 파일에 저장하는 프로그램을 작성해보자. 사람들의 이름은 aa부터 zz까지 676(26×26)개의 이름을 자동으로 생성한다. 전화번호도 100부터 775까지를 자동으로 생성한다.

#include <stdio.h>

int main(void) {
    FILE *fp = fopen("phone.txt", "w");
    char name[3] = "aa";
    int number = 100;

    if (fp == NULL) {
        printf("파일을 열 수 없습니다.\n");
        return 1;
    }

    for (char first = 'a'; first <= 'z'; first++) {
        for (char second = 'a'; second <= 'z'; second++) {
            name[0] = first;
            name[1] = second;
            fprintf(fp, "%s %d\n", name, number++);
        }
    }

    fclose(fp);
    printf("전화번호 파일이 생성되었습니다.\n");

    return 0;
}

 

13. 자기가 소유하고 있는 도서를 관리하는 프로그램을 작성하여보자. 다음과 같은 메뉴 화면을 가진다.

1. 추가
2. 검색
3. 파일로 저장
4. 파일에서 읽기
5. 종료

정수값을 입력하세요: 1
도서의 이름: Introduction to Heros
저자: 홍길동
출판사: 히어로출판사

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_BOOKS 100

typedef struct {
    char title[100];
    char author[100];
    char publisher[100];
} Book;

Book books[MAX_BOOKS];
int book_count = 0;

void add_book() {
    if (book_count >= MAX_BOOKS) {
        printf("책 목록이 가득 찼습니다.\n");
        return;
    }

    printf("도서의 이름: ");
    getchar(); // 버퍼 비우기
    fgets(books[book_count].title, sizeof(books[book_count].title), stdin);
    books[book_count].title[strcspn(books[book_count].title, "\n")] = '\0';

    printf("저자: ");
    fgets(books[book_count].author, sizeof(books[book_count].author), stdin);
    books[book_count].author[strcspn(books[book_count].author, "\n")] = '\0';

    printf("출판사: ");
    fgets(books[book_count].publisher, sizeof(books[book_count].publisher), stdin);
    books[book_count].publisher[strcspn(books[book_count].publisher, "\n")] = '\0';

    book_count++;
}

void save_to_file() {
    FILE *fp = fopen("books.txt", "w");
    if (fp == NULL) {
        printf("파일을 열 수 없습니다.\n");
        return;
    }

    for (int i = 0; i < book_count; i++) {
        fprintf(fp, "%s,%s,%s\n", books[i].title, books[i].author, books[i].publisher);
    }

    fclose(fp);
    printf("파일로 저장되었습니다.\n");
}

void read_from_file() {
    FILE *fp = fopen("books.txt", "r");
    if (fp == NULL) {
        printf("파일을 열 수 없습니다.\n");
        return;
    }

    book_count = 0;
    while (fscanf(fp, "%99[^,],%99[^,],%99[^\n]\n", books[book_count].title, books[book_count].author, books[book_count].publisher) == 3) {
        book_count++;
    }

    fclose(fp);
    printf("파일에서 읽기가 완료되었습니다.\n");
}

void print_menu() {
    printf("1. 추가\n");
    printf("2. 검색\n");
    printf("3. 파일로 저장\n");
    printf("4. 파일에서 읽기\n");
    printf("5. 종료\n");
}

int main(void) {
    int choice;

    while (1) {
        print_menu();
        printf("정수값을 입력하세요: ");
        scanf("%d", &choice);

        switch (choice) {
            case 1:
                add_book();
                break;
            case 3:
                save_to_file();
                break;
            case 4:
                read_from_file();
                break;
            case 5:
                exit(0);
                break;
            default:
                printf("잘못된 입력입니다.\n");
                break;
        }
    }

    return 0;
}

 

14. 이진 파일의 가장 전형적인 예는 이미지 파일이다. 이미지 파일 안에는 이미지 픽셀 값들이 이진값으로 저장된다. 많은 이미지 파일은 앞에 헤더가 있어서 헤더를 해석해야 만이 이미지 픽셀값들을 꺼내서 사용할 수 있다. raw 파일 형식은 이미지 헤더가 없고 픽셀값이 8비트 이진데이터로 저장되어 있다. lena(256x256).raw 파일을 읽어서 화면에 표시하는 프로그램을 작성해보자.

#include <stdio.h>
#include <windows.h>

#define WIDTH 256
#define HEIGHT 256

int main(void) {
    FILE *fp = fopen("lena(256x256).raw", "rb");
    if (fp == NULL) {
        printf("파일을 열 수 없습니다.\n");
        return 1;
    }

    unsigned char image[HEIGHT][WIDTH];
    fread(image, sizeof(unsigned char), WIDTH * HEIGHT, fp);
    fclose(fp);

    HDC hdc = GetWindowDC(GetForegroundWindow());
    if (hdc == NULL) {
        printf("디스플레이를 가져올 수 없습니다.\n");
        return 1;
    }

    for (int y = 0; y < HEIGHT; y++) {
        for (int x = 0; x < WIDTH; x++) {
            unsigned char pixel = image[y][x];
            SetPixel(hdc, x, y, RGB(pixel, pixel, pixel));
        }
    }

    ReleaseDC(GetForegroundWindow(), hdc);
    printf("이미지가 표시되었습니다.\n");

    return 0;
}

16장 Exercise & Programming은 아래 클릭하시면됩니다.

[쉽게 풀어쓴 C언어 Express 개정4판] 16장 Exercise & Programming

 

[쉽게 풀어쓴 C언어 Express 개정4판] 16장 Exercise & Programming

16장 Exercise & Programming16장 Exercise 1. #define을 이용하여 다음 매크로 SIZE를 10으로 올바르게 정의한 것을 모두 고르시오. 정답: 4번 #define SIZE 10  2. 다음의 설명에 부합하는 매크로를 정의하여보자.

gomszone.tistory.com

댓글