Turbo-C
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
터보-C 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
Lua 게시판
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C/C++ Q/A
[2196] Re:[왕초보입니다] 숫자 읽기
임문환 [mhlim] 1887 읽음    2003-03-28 00:50
더 나은 방법이 있겠지만 기본적으로 아래와 같이 할 것 같습니다.

일단 숫자부분을 1의 자리에서 시작해서 4자리씩 구분지읍니다.
각 블럭 내부에서 숫자는 천단위로 읽게 되겠죠.
각 블럭 내부 숫자를 읽기 위한 기본 단위는 "천백십 "이 겠죠.

즉, 아래에서 각블럭 내부숫자를 읽을 때는 1->일 2345->이천삼백사십오, 6789->육천칠백팔십구
1,2345,6789
그런다음 각 블럭의 끝에 해당 블럭의 위치에 따른 단위를 추가하면 됩니다.

1의 자리부터 시작하면
첫블럭의 단위는 없고
두번째 블럭의 단위는 만
세번째 블럭의 단위는 억
네번째 블럭의 단위는 조

이렇게 블럭의 단위까지해서 위 숫자를 읽어보면
1->일억 2345->이천삼백사십오만, 6789->육천칠백팔십구

각 자리의 숫자가 무엇인지는 어떻게 아냐구요?
주어진게 숫자를 표현하는 문자열이라면 간단하구요.
int 등의 정수형으로 주어졌다면 그걸 문자열로 만든 다음 하든지
1부터 시작해서 10배씩 증가된 값으로 주어진 숫자를 나눈 몫을 다시 10으로 나눈 나머지가 해당 자리의 값이 되겠죠
나누는 작업이 끝나는 시점은 첫번째 나눗셈의 몫이 0이 되는 시점입니다.



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

char * ReadNumber(char *strNum, char *res);
char * ReadBaseNumber(char *strNum,char *res);

void main()
{
char num[]="12345678901234567890234";
unsigned int no=4123456789;
char ret[128];

ReadNumber(num,ret);
printf("\n%s\n%s",num,ret);

sprintf(num,"%u",no);
ReadNumber(num,ret);
printf("\n\n%s\n%s",num,ret);

while(kbhit()) getch(); getch();
}



char * ReadNumber(char *strNum, char *res)
{
if(!strNum || !res) return NULL;
char *p;
int len;
int sign=0;

//반환값 초기화
res[0]='\0';

if(*strNum=='+'){
  sign=1;
  strNum++;
}else if(*strNum=='-'){
  sign=-1;
  strNum++;
}

p=strNum;

//숫자인지 검사
while(*p>='0' && *p<='9') p++;
//숫자 아닌게 있으면 오류(빈문자열 반환)
if(*p) return res;


p=strNum;
//숫자의 앞부분에 있는 0을 제거
while(*strNum=='0') strNum++;

len=strlen(strNum);

if(len==0 && p!=strNum)
{
  strcpy(res,"영");
  return res;
}
else if(len==0) //문자열에 아무것도 없으면 빈문자열 반환
{
  return res;
}
else if(len>72)
{
  strcpy(res,"너무 큰 숫자(최대72자리)");
  return res;
}

const char* const BlockUnits[]={"","만 ","억 ","조 ","경 ","해 ","자 ","양 ","구 ","간 ","정 ","재 ","극 ","항하사 ","아승기 ","나유타 ","불가사의 ","무량수 "};
char buf[5], ret[16];
int cnt,unitIndex;


if(sign>0)  strcat(res,"양수 ");
else if(sign<0) strcat(res,"음수 ");

//문자열의 앞부분은 숫자로 생각하면 뒷부분에 비해 높은 자리임.
unitIndex=(len-1)/4; // 만억조경... 중 어떤 단위가 시작점인지 계산
cnt = len%4; // 최초에 다룰 블럭에 들어있는 숫자의 갯수
if(cnt==0) cnt=4; // 길이를 4로 나눈 나머지가 0이면 길이가 4의 배수이므로 처음 다룰 숫자가 4개가 됨.
for(int i=0; i<len ;i+=cnt,unitIndex--)
{
  //for 루프를 한 번 돌고 나면 cnt는 항상 4가 됨
  if(i>=cnt) cnt=4;
  strncpy(buf,strNum+i,cnt);
  buf[cnt]='\0';
  ReadBaseNumber(buf,ret);
  if(ret[0])
  {
   strcat(res,ret);
   strcat(res,BlockUnits[unitIndex]);
  }
}

return res;
}
//---------------------------------------------------------------------------


//네자리 이하로 된 숫자 읽기
char *ReadBaseNumber(char *strNum,char *res)
{
if(!strNum || !res) return NULL;

char *p=strNum;

//숫자 앞부분에 있는 0을 제거
while(*strNum=='0') strNum++;
int len,unitIndex;
len=strlen(strNum);
//가장 선두에 있는 숫자의 단위(숫자의 길이가 4라면 천, 3이라면 백, 2라면 십)
unitIndex = len-1;

//반환값 초기화
res[0]='\0';

//모두 '0'으로 되어 있는 경우 빈문자열 반환
if(unitIndex<0 && p!=strNum) return res;

//선두에 있는 숫자의 단위가 비정상인 경우(즉,strNum에 저장된 숫자의 길이에 이상이 있는 경우)
if(unitIndex<0 || unitIndex>=4) return NULL;

const char* const NumNames[]={"","일","이","삼","사","오","육","칠","팔","구"};
const char* const BaseUnits[]={"","십","백","천"};

for(int i=0 ,n;i<len ;i++){
  //문자로 표현된 숫자를 실제 숫자로 변환('0'->0 , '1'->1 .... '9'->9)
  n=strNum[i]-'0';
  //보통 숫자 0은 읽는 경우가 없음
  //2 이상의 숫자는 해당 숫자와 단위를 모두 읽음
  if(n>1)
  {
   strcat(res,NumNames[n]);
   strcat(res,BaseUnits[unitIndex-i]);
  }
  // 숫자 1은 보통 일의 자리에 있을 경우에만 읽음
  else if(n==1 && i==len-1)
  {
   strcat(res,NumNames[n]);
  }
  //숫자 1이 일의 자리가 아닌 다른 자리에 있을 때는 해당 자리의 단위로만 읽음
  else if(n==1)
  {
   strcat(res,BaseUnits[unitIndex-i]);
  }
}
return res;
}



김학래 님이 쓰신 글 :
: C로 숫자를 입력받아서 한글로 출력하는 프로그램을
:
: 만들어야하는데 알고리즘이 떠오르지를 않네요 ㅜㅜ
:
: 예를 들어서 숫자 "-12345" 를 입력하면
:
: "음수 만이천삼백사십오" 가 출력되게 해야하는데 좀 가르쳐주세요.......
:

+ -

관련 글 리스트
2192 [왕초보입니다] 정말 왕초보라서 그러는데 좀 가르쳐주세요..... 김학래 1197 2003/03/27
2196     Re:[왕초보입니다] 숫자 읽기 임문환 1887 2003/03/28
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.