본문 바로가기

System Programming

시스템 프로그래밍 프로젝트 #4

문제 :

 

입력 파일 :

numb.txt
0.00MB

 

실행 결과 :

 

소스 코드 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
 
void get_token_num(char *bp);
void hextodec(char *test, int len); // hex to decimal function
void atohex(char *ascii, int len); // ascii to hex function
int sum = 0;
int cnt = 0;
 
int main() {
    FILE *fp = NULL;
    char buf[80];
    if((fp = fopen("numb.s""r"))==NULL) {
        printf("file not found...\n"); exit(1);
    }
    while(fgets(buf, sizeof(buf), fp) != NULL) {
        get_token_num(buf);
        }
    fclose(fp);
    printf("\nsum = %d\n", sum);
    return 0;
}
void get_token_num(char *bp){
    int i,len;
    char test[10];
        char* result = strtok(bp," \t\n"); // 문자열 자르기    
    while(result!=NULL) {       // 자른 token이 NULL 일떄까지 loop
        if(result[0== 'X'){ // 자른 token 의 원소가 'X' 이면 hexadecimal
            for(i=2; i<=strlen(result)-2; i++){ // 처리할 부분만 잘라냄
                test[i-2= result[i];
                cnt++;
            }    
            printf("token : %s\t",result);
            printf("\t\t");
            hextodec(test, cnt);
            cnt=0;
        }
        else if(result[0== 'C'){ // 자른 token의 첫 원소가 'C' 이면 ASCII
            printf("token : %s\t",result);
            for(i=2; i<=strlen(result)-2; i++){ // 처리할 부분만 잘라냄
                test[i-2= result[i];
                cnt++;
            }
            test[cnt] = '\0'
            atohex(test, cnt);
            cnt=0;
        }
        else { // 자른 token이 문자열 상수이면 decimal
            printf("token : %s\t",result);
            sum += atoi(result);
            printf("\t\tdec : %d\n", atoi(result));
        }
        result = strtok(NULL," \t\n");
    }
}
void hextodec(char *test, int len){ // 16진수로 된 문자열
    int decimal = 0;               // 10진수를 저장할 변수
    int i;
    int position = 0;
    for (i = len - 1; i >= 0; i--) {   // 문자열을 역순으로 반복
        char ch = test[i];         // 각 자릿수에 해당하는 문자를 얻음
        if (ch >= 48 && ch <= 57) {      // 문자가 0~9이면(ASCII 코드 48~57)
            // 문자에서 0에 해당하는 ASCII 코드 값을 빼고
            // 16에 자릿수를 거듭제곱한 값을 곱함
            decimal += (ch - 48* pow(16, position);
        }
        else if (ch >= 65 && ch <= 70) {   // 문자가 A~F이면(ASCII 코드 65~70)
                        // 대문자로 된 16진수의 처리
                   // 문자에서 (A에 해당하는 ASCII 코드 값 - 10)을 빼고
            // 16에 자릿수를 거듭제곱한 값을 곱함
            decimal += (ch - (65 - 10)) * pow(16, position);
        }
        else if (ch >= 97 && ch <= 102) {  // 문자가 a~f이면(ASCII 코드 97~102)
            // 소문자로 된 16진수의 처리
            // 문자에서 (a에 해당하는 ASCII 코드 값 - 10)을 빼고
            // 16에 자릿수를 거듭제곱한 값을 곱함
            decimal += (ch - (97 - 10)) * pow(16, position);
        }
        position++;
    }
    printf("dec : %d\n", decimal);
    sum += decimal;
}
void atohex(char *ascii, int len){
    char outword[10];
    int i, tmp_len;
    for(i = 0; i<len; i++){
        sprintf(outword+i*2"%02X", ascii[i]);
    }
    tmp_len = strlen(outword);
    printf("hex : %s\t", outword);
    hextodec(outword, tmp_len);
}
 

 

설명 :

이 소스코드에서 Hex = Hexadecimal = 16진수 , Dec = Decimal = 10진수를 나타냅니다.

진수 변환시에 위 코드처럼 풀어서 사용하지 않고 sprintf 같은 다른 간단한 방법을 사용할 수도 있습니다.

방법을 보여주고자 위와 같이 풀어서 작성했습니다.

pow함수는 double형의 두 가지 값을 받아서, 가령 입력값 A, B가 인자로 전달되었다면,

A^B 를 계산한 값을 반환하는 함수인데, math.h에 정의되어 있습니다.

정상적으로 코드 내 헤더 파일을 include 시켰음에도 라이브러리 호출이 안된다면, 아래와 같은 명령어로 해결할 수 있습니다.

ex) gcc -lm pj4.c 혹은 gcc -o "filename" "filename.c" -lm 이런 형태로 gcc 컴파일 명령어 뒤에 -lm을 추가함으로써 해결할 수 있습니다.

그리고 문제에 있는 numb.s 텍스트를 그대로 긁어서 붙여넣기 하면 따옴표가 특수문자여서 1바이트가 아닌 2바이트로 인식됩니다.

그래서 Token을 자를 때 코딩한대로 실행되지 않을 수 있으므로 가급적이면 직접 타이핑 하시거나 제대로 된 numb.txt 파일을 올려 두었으니 다운받아서 리눅스 환경에서 numb.s 를 만들어 붙여넣기해서 사용하시기 바랍니다.