본문 바로가기
College Computer Science/C Language

[C 프로그래밍 실습] Report 02

by 2den 2021. 1. 2.
728x90

Program 1

 

뎃셈, 뺄셈, 솝셈, 나눗셈, 나머지연산(%)을 지원하는 계산기 프로그램을 작성한다고 하자. 각연산이 몇번씩 나오는지 기억해서 화면에 출력하는 프로그램을 쓰시오.

  • 연산자의 종류는 5가지(+, -, *, /, %)
  • 연산식은 공백을 포함할 수 있다.
  • 현재까지의 총 연산자의 회수를 출력한다.
  • 예외 처리, 문자나 5가지 이외의 연산자가 사용된 연산식은 오류 메시지를 출력

 

 

1) 문제 해결 방법에 대한 설명

  • 5가지 종류의 연산자를 입력 받으면 개수를 카운트 : 5가지 종류의 연산자를 입력 받기 위한 변수를 선언, 식을 입력 받은 후 문자를 하나씩 읽어 5가지 종류의 연산자가 나오면 변수에 값을 증가
  • 연산식은 공백을 포함할 수 있음 : 공백을 입력으로 받아야 하기 때문에 scanf 입력 형식을 ‘%[^\n]’으로 지정, 입력을 읽을 때 정상적이지만 카운트에 들어가지 않는 문자인 숫자와 함께 다음 반복으로 넘어갈 수 있도록 instruction 작성
  • 예외 처리 : 문자 전체와 5가지 연산이 아닌 특수문자를 조건으로 작성하기 어렵기 때문에 else문으로 처리, else문 앞에서 이미 카운트를 증가시키기 때문에 정상적인 입력이 들어오다 잘못된 입력이 발생하면 카운트를 다시 돌려주어야 함 (temp 변수로 해결)
  • 나머지 설명은 주석으로 대신합니다.

 

2) 소스 코드

#include<stdio.h>

int main()
{
    // 입력 받을 식 문자열
    char* formula;

    // 카운트를 위한 변수, 입력 오류 시 원래의 값을 다시 저장하기 위한 temp 변수 정의
    int plus = 0, minus = 0, times = 0, division = 0, remainder = 0;
    int plus_temp = 0, minus_temp = 0, times_temp = 0, division_temp = 0, remainder_temp = 0;
    // 입력 오류 시 연산 합계 출력을 skip하기 위한 flag
    int iserror = 0;

    printf("연산종류의 개수를 카운트하는 프로그램입니다.\n");
    while (1)
    {
        // 입력 전 초기화, 기존의 카운트를 temp에 저장
        plus_temp = plus; minus_temp = minus; times_temp = times; division_temp = division; remainder_temp = remainder;
        // 입력 오류 flag를 false로 초기화
        iserror = 0;

        printf("연산식을 입력하시오 : ");
        scanf(" %[^\n]", formula); // 공백도 입력으로 받음

        for (int i = 0; *(formula + i); i++)
        {
            if (*(formula + i) == '+') plus++;
            else if (*(formula + i) == '-') minus++;
            else if (*(formula + i) == '*') times++;
            else if (*(formula + i) == '/') division++;
            else if (*(formula + i) == '%') remainder++;
            else if (('0' <= *(formula + i) && *(formula + i) <= '9') || *(formula + i) == ' ') continue; // 숫자나 공백은 카운트에 넣지 않음
            else {
                printf("??연산식 오류\n");
                // temp에 저장해 두었던 이번 입력 이전의 카운트를 다시 restore
                plus = plus_temp; minus = minus_temp; times = times_temp; division = division_temp; remainder = remainder_temp;
                //flag true로 변경
                iserror = 1;
                break;
            }
        }

        if (!iserror)
        {
            // 연산 합계가 0이 아닐 때부터 출력
            if (plus) printf("+ 연산 합계 : %d\n", plus);
            if (minus) printf("- 연산 합계 : %d\n", minus);
            if (times) printf("* 연산 합계 : %d\n", times);
            if (division) printf("/ 연산 합계 : %d\n", division);
            if (remainder) printf("% 연산 합계 : %d\n", remainder);
        }
        printf("\n");
    }

    return 0;
}

 

3) 입력/출력 결과

 


 

Program 2

 

문자열로 받은 16진수를 10진수로 변경하여 출력하는 프로그램을 만들어 보자. 10장 주요 문자 관련 함수의 기능을 사용하여 프로그램하시오. (무한 루프로 수행)

  • 입력 16진수 문자열은 사용자 입력(표준 입력)으로 받아 처리하도록 한다.
  • 16진수 표기에 포함된 alphabet 대소문자, 16진수를 의미하는 0x, 0X 등 처리해야함
  • 함수 정의하여 사용 (16진수인지를 검사하는 함수, 16진수 문자열을 10진수로 변경하여 return 하는 함수)
  • 예외 처리 : 16진수가 아닌 경우 재입력
  • 모든 라이브러리 함수 사용 가능

 

 

1) 문제 해결 방법에 대한 설명

  • 16진수 표기에 포함된 0x, 0X 처리 : 문자열이 0x 또는 0X로 시작할 경우, 문자열을 가리키는 포인터에 2를 더해 해당 문자 뒤부터 문자열로 인식하도록 설정
  • 함수를 정의하여 사용 : 16진수인지를 검사하는 함수 ishexa()와 10진수로 변경하여 return하는 함수 hextodec() 정의, ishexa()는 문자열 길이만큼 isxdigit()함수를 통해 16진수인지를 검사하고 hextodec()은 strtol()함수를 통해 10진수로 변환
  • 예외 처리 : ishexa()의 반환 값이 0인 경우 오류 메시지 출력 후 입력을 다시 받음
  • 나머지 설명은 주석으로 대신합니다.

 

2) 소스 코드

#include<stdio.h>

int ishexa(char* string)
{
    // 문자열 길이만큼 확인
    for (int i = 0; *(string + i); i++)
    {
        // 16진수 숫자가 아니면 반복 종료 후 0 return
        if (isxdigit(*(string + i)) == 0) return 0;
    }
    // 모두 16진수 숫자면 1 return
    return 1;
}

int hextodec(char* hexa)
{
    // 10진수로 변환
    return (int)strtol(hexa, NULL, 16);
}

int main()
{
    char* hexa;

    printf("16진수를 정수로 변환하는 프로그램입니다.\n");
    while (1)
    {
        printf("16진수 문자열을 입력하시오 : ");
        scanf(" %s", hexa);
        // 0x, 0X 처리
        if (*hexa == '0' && (*(hexa + 1) == 'x' || *(hexa + 1) == 'X')) hexa = hexa + 2;

        //16진수 아닐 경우
        if (!ishexa(hexa)) {
            printf("?? 16진수가 아닙니다.\n");
            continue;
        }

        //16진수가 맞으면 10진수로 변환 출력
        printf(">> 10수로 변환 결과 : %d\n\n", hextodec(hexa));

    }

    return 0;
}

 

3) 입력/출력 결과

 


 

Program 3

 

우리는 일상 생활에서 다양한 암호를 사용한다. 사용자로부터 암호를 입력받고, 암호의 안전도를 검사하는 프로그램을 쓰시오.

  • 암호는 대문자, 소문자, 숫자, 그리고 그외의 문자(특수문자, 기호) 4가지로 될 수 있다.
  • 4가지중 3가지를 포함한다면 암호가 안전도가 높다고 판단한다.
  • 안전도가 낮은 경우 다시 입력 받도록 한다.
  • 비밀번호는 8글자 이상, 12글자 이하이어야 한다.
  • prinft(), scanf()를 제외한 library 함수는 사용하지 않는다.

 

 

1) 문제 해결 방법에 대한 설명

  • 자리수 다르면 오류메시지 출력
  • 3가지 이상 포함 안되면 오류메시지 출력
  • check 문자열과 기존 문자열 비교 (기존 문자열 한 글자 사라지는 현상 발생)
  • 주석으로 대신합니다.

 


 

Program 4

 

표준 입력으로 받은 정수 n에 대하여 1부터 n까지의 홀수의 합을 구하는 함수를 재귀함수로 작성하고, 합이 출력되도록 프로그램을 작성하시오.

 

 

1) 문제 해결 방법에 대한 설명

  • 정수가 아니거나 0보다 작을 경우 오류 메시지 출력 하기 위해 if문 실행, 무한 루프를 방지하기 위해 다음 반복 실행 전에 getchar()
  • oddsum()함수 : 짝수이면 n-1과 n-3부터 2씩 줄이며 더하도록, 홀수이면 n부터 2씩 줄이며 더하도록 설정
  • 나머지 설명은 주석으로 대신합니다.

 

2) 소스 코드

#include<stdio.h>

int oddsum(int n)
{
    if (n == 1) return 1;
    else if (n % 2 == 0) return (n - 1) + oddsum(n - 3);
    else return n + oddsum(n - 2); // 짝수일 경우
}

int main()
{
    int n;

    while (1)
    {
        printf("1부터 n까지 홀수의 합을 구하는 재귀호출 프로그램입니다.\n");
        printf("정수 n을 입력하십시오 >> ");
        while (1)
        {
            scanf("%d", &n);
            //정수가 아닐 경우
            if (n == '\0') {
                printf("?? 정수가 아닙니다. 다시 입력하시오 >> ");
                getchar();
                continue;
            }
            // 0보다 작을 경우
            if (n <= 0) {
                printf("?? 0보다 큰 정수를 입력하시오 >> ");
                getchar();
                continue;
            }
            else {
                getchar();
                break;
            }
        }
        printf("1부터 %d까지 홀수 합: %d\n\n", n, oddsum(n));
    }

    return 0;
}

 

3) 입력/출력 결과

 

 

728x90

댓글