계산기 두개..

qprk의 이미지

100cal.c 는 예전에 네이버 지식인에서 누가 질문 올렸길래 만들어봤구요..
parseQuery.c 는 뭐 만드는데 중간 과정에서 저런 파싱기가 있어야기에 만들어봤습니다.

뭐 만들어놓고 보니 코드가 좀 지저분한감이 있내요..

그리고 첨부 파일은 100cal 로 계산한 1000000! 입니다.

100cal.c

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


#define MAX_BUFF_SIZE	930000

void deohagi(char *, char *, char *);
void bbegi(char *, char *, char *);
void gobhagi(char *, char *, char *);
void nanugi(char *, char *, char *);
void fac(char *, char *);

void outfile(char *, char *, char *, char);

main()
{
  char a[MAX_BUFF_SIZE];
  char b[MAX_BUFF_SIZE];
  char c;
  char result[MAX_BUFF_SIZE];
  int i;


 cont:
  
  for(i=0;i<MAX_BUFF_SIZE;i++){
    a[i] = b[i] = result[i] = '\0';
  }

  printf("input number a->");
  gets(a);

  if(strlen(a) > MAX_BUFF_SIZE){
    printf("input error 첨부터 다시..\n");
    goto cont;
  }

  printf("연산방식 입력( + - * / ! )-> ");
  gets(result);
  c = result[0];
  strcpy(result, "0");
  if(c != '+' && c != '-' && c != '*' && c != '/' && c != '!'){
    printf("input error 첨부터 다시..\n");
    goto cont;
  }

  if(c != '!'){
    printf("input number b->");
    gets(b);

    if(strlen(b) > MAX_BUFF_SIZE){
      printf("input error 첨부터 다시..\n");
      goto cont;
    }
  }

  //  printf("값을 입력해라.. ex)1000 + 1000) 연산은 + - * / !\n");
  //  scanf("%s %c %s", a, &c, b);
  //  getchar(); // 마지막 엔터 읽어서 없에기..

  if(c != '+' && c != '-' && c != '*' && c != '/' && c != '!'){
    printf("input error 연산자, 첨부터 다시..\n");
    goto cont;
  }
  if(strlen(a) > MAX_BUFF_SIZE){
    printf("input error A수 , 첨부터 다시..\n");
    goto cont;
  }
  if(strlen(b) > MAX_BUFF_SIZE){
    printf("input error 뒷수,  첨부터 다시..\n");
    goto cont;
  }

  if(c == '+'){
    deohagi(a, b, result);
    printf("'%s'\n",result);
    //    outfile(a, b, result, c);
  }else if(c == '-'){
    bbegi(a, b, result);
    printf("'%s'\n",result);
    //    outfile(a, b, result, c);
  }else if(c == '*'){
    gobhagi(a, b, result);
    printf("'%s'\n",result);
    //    outfile(a, b, result, c);
  }else if(c == '/'){
    nanugi(a, b, result);
    printf("'%s'\n",result);
    //    outfile(a, b, result, c);
  }else if(c == '!'){
    fac(a, result);
    printf("'%s'\n",result);
    outfile(a, "", result, c);
  }

 KIN:
  printf(" \n");
exit(0);
  gets(result);
  c = result[0];
  if(c == '2'){
    exit(0);
  }else if(c == '1'){
    goto cont;
  }else{
    printf("똑바로 입력해라\n");
    goto KIN;
  }

}

// 0: 48, 9:57
void deohagi(char *a, char *b, char *result)
{
  int i;
  int lenA, lenB, lenC;
  int smallRst, smallPa;
  char temp[MAX_BUFF_SIZE];
  
  smallRst = smallPa = 0;

  lenA = strlen(a)-1;
  lenB = strlen(b)-1;
  lenC = 0;

  for(i=0;i<MAX_BUFF_SIZE;i++, lenA--, lenB--){
    if(lenA > -1 && lenB > -1){
      smallRst = (a[lenA] - 48) + (b[lenB] - 48) + smallPa;
      smallPa = smallRst>=10 ? 1 : 0 ;
      smallRst = smallRst % 10;
      temp[i] = smallRst + 48;
    }else{
      if(lenA > -1){
	smallRst = (a[lenA] - 48) + smallPa;
	smallPa = smallRst>=10 ? 1 : 0 ;
	smallRst = smallRst % 10;
	temp[i] = smallRst + 48;
      }else if(lenB > -1){
	smallRst = (b[lenB] - 48) + smallPa;
	smallPa = smallRst>=10 ? 1 : 0 ;
	smallRst = smallRst % 10;
	temp[i] = smallRst + 48;
      }else{
	temp[i] = smallPa + 48;
	temp[i+1] = '\0';
	break;
      }
    }//  if(lenA > -1 && lenB > -1){
  }
  
  if(smallPa)
    i++;
  
  for(lenC=0;i>=0;i--,lenC++){
    result[lenC-1] = temp[i];
  }
  result[lenC] = '\0';
}


void gobhagi(char *a, char *b, char *result)
{
  int i,j;
  int lenB;
  char aa[MAX_BUFF_SIZE];
  char bb[MAX_BUFF_SIZE];

  strcpy(aa, "0");
  strcpy(bb, a);
  lenB = strlen(b) -1;

  for(i=0;lenB > -1;i++, lenB--){
    j = b[lenB] - 48;

    for(;j>0;j--){		/*  */
      deohagi(aa, bb, result);
      strcpy(aa, result);
    }
    strcat(bb,"0");
  }
}


void bbegi(char *a, char *b, char *result)
{
  int i;
  int lenA, lenB, lenC;
  int smallRst, smallPa;

  int isMinus=0;
  char temp[MAX_BUFF_SIZE];
  char aa[MAX_BUFF_SIZE], bb[MAX_BUFF_SIZE];
  char *p, *q;
  
  smallRst = smallPa = 0;

  lenA = strlen(a)-1;
  lenB = strlen(b)-1;
  lenC = 0;

  strcpy(aa, a);
  strcpy(bb, b);

  if(lenA < lenB){
    isMinus = 1;
  }else if(lenA == lenB){
    if(a[0] < b[0]){
      isMinus = 1;
    }
  }

 min:
  if(isMinus){
    strcpy(temp, aa);
    strcpy(aa, bb);
    strcpy(bb, temp);
    lenA = strlen(aa)-1;
    lenB = strlen(bb)-1;
  }

  for(i=0;i<MAX_BUFF_SIZE;i++, lenA--, lenB--){
    if(lenA > -1 && lenB > -1){
      smallRst = (aa[lenA] - 48) - (bb[lenB] - 48) - smallPa;
      smallPa = 0;
      if(smallRst < 0){
	smallRst += 10;
	smallPa = 1;
      }
      temp[i] = smallRst + 48;
    }else{
      if(lenA > -1){
	smallRst = (aa[lenA] - 48) - smallPa;
	smallPa = 0;
	if(smallRst < 0){
	  smallRst += 10;
	  smallPa = 1;
	}
	smallRst = smallRst % 10;
	temp[i] = smallRst + 48;
      }else if(lenB > -1){
	smallRst = (bb[lenB] - 48) - smallPa;
	smallPa = 0;
	if(smallRst < 0){
	  smallRst += 10;
	  smallPa = 1;
	}
	smallRst = smallRst % 10;
	temp[i] = smallRst + 48;
      }else{
	if(smallPa){
	  smallPa = 0;
	  isMinus = 1;
	  goto min;
	}
	//	temp[i] = smallPa + 48 ;
	temp[i] = '\0';
	break;
      }
    }//  if(lenA > -1 && lenB > -1){
  }
  
  lenC=0;
  if(isMinus){
    result[0] = '-';
    lenC += 2;
    i--;
  }

  for(;i>=0;i--){
    result[lenC-1] = temp[i];
    lenC++;
  }
  result[lenC] = '\0';

  q = p = result;
  while(*p){
    if(*p == '-'){
      p++;
      q++;
    }else if(*p == '0'){
      p++;
    }else{
      strcpy(q, p);
      break;
    }
  }

}


void nanugi(char *a, char *b, char *result)
{
  char aa[MAX_BUFF_SIZE];
  char bb[MAX_BUFF_SIZE];
  char cc[MAX_BUFF_SIZE];
  char temp[MAX_BUFF_SIZE];
  char temp1[MAX_BUFF_SIZE];

  strcpy(aa, a);
  strcpy(bb, b);
  strcpy(cc, "0");

  while(1){
    memset(temp1, 0, MAX_BUFF_SIZE);
    memset(temp, 0, MAX_BUFF_SIZE);
    bbegi(aa, bb, temp);
    if(temp[0] != '-' ){
      if(temp[0] == '0'){
	deohagi(cc, "1", temp1);
	break;
      }

      strcpy(aa, temp);
      deohagi(cc, "1", temp1);
      strcpy(cc, temp1);
    }else{
      break;
    }
  }
  
  strcpy(result, temp[0] != '-' ? temp1 : cc);
  if(temp1[0] != '0' || temp1[0] != '-'){
    strcat(result, " 나머지 ");
    strcat(result, temp[0] == '-' ? aa : temp);
  }  
}

void fac(char *a, char *result)
{
  char aa[MAX_BUFF_SIZE];
  char bb[MAX_BUFF_SIZE];
  char rst[MAX_BUFF_SIZE];

  strcpy(aa, a);
  strcpy(rst, a);
  do{
    bbegi(aa, "1", bb);
    strcpy(aa,bb);
    gobhagi(rst, bb, result);
    strcpy(rst, result);
  }while(strcmp(bb, "2"));

}



void outfile(char *a, char *b, char *c, char d)
{
  FILE *fp;

  fp = fopen("infile.dat", "w");
  fprintf(fp,"%s %c %s", a, d, b);
  fclose(fp);

  fp = fopen("outfile.dat", "w");
  fprintf(fp,"%s", c);
  fclose(fp);
}

parseQuery.c

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



typedef struct __QueryBuff{
  char *data;
  struct __QueryBuff *next;
} _QueryBuff;


typedef struct __QueryBuffHeader{
  struct __QueryBuff *stackTop;
  struct __QueryBuff *queueFront;
  struct __QueryBuff *queueTail;
}_QueryBuffHeader;




_QueryBuff *get_new_query_buff_node();
_QueryBuffHeader *create_query_buff_header();
void reset_query_buff_header(_QueryBuffHeader *);
void *query_buff_push(_QueryBuffHeader *, void *);
void *query_buff_pop(_QueryBuffHeader *);
void *query_buff_insert(_QueryBuffHeader *, void *);
void *query_buff_delete(_QueryBuffHeader *);
char *get_token(char *, char *, char **);
char *str_trim(char *);
int is_operator(char *);
void process_query(_QueryBuffHeader *);



/***************************************************************************
 * 새로운 노드를 하나 할당한다.
 ***************************************************************************/
_QueryBuff *get_new_query_buff_node()
{
  _QueryBuff *newNode;
  newNode = (_QueryBuff *)malloc(sizeof(_QueryBuff));
  newNode->data = NULL;
  newNode->next = NULL;
  return newNode;
}


/***************************************************************************
 * data를 스택에 밀어넣고 해당 포인터를 리턴
 ***************************************************************************/
void *query_buff_push(_QueryBuffHeader *header, void *data)
{
  register _QueryBuff *newTop;

  newTop = get_new_query_buff_node();
  
  newTop->data = data;
  newTop->next = header->stackTop;
  header->stackTop = newTop;
  //printf("push('%s')\n", (char *)data);
  return newTop->data;
}

/***************************************************************************
 * 스택에서 팝해서 data의 포인터를 리턴.
 ***************************************************************************/
void *query_buff_pop(_QueryBuffHeader *header)
{
  void *data;
  _QueryBuff *newTop;  

  if(header->stackTop == NULL ) return NULL; /* stack enpty */

  if(header->stackTop->data) data = header->stackTop->data;
  else data = NULL;

  newTop = header->stackTop->next;
  free(header->stackTop);
  header->stackTop = newTop;
  //printf("pop('%s')\n", (char *)data);
  return data;
}


/***************************************************************************
 * 큐에 data를 저장하고 저장된 문자열을 리턴
 ***************************************************************************/
void *query_buff_insert(_QueryBuffHeader *header, void *data)
{
  header->queueTail->data = data;
  header->queueTail->next = get_new_query_buff_node();
  header->queueTail = header->queueTail->next;
  //printf("insert('%s')\n", (char *)data);
  return data;
}

/***************************************************************************
 * 큐에 data를 지우고 지워진 data를 리턴
 ***************************************************************************/
void *query_buff_delete(_QueryBuffHeader *header)
{
  void *data;
  _QueryBuff *freeNode;

  if(header->queueFront == header->queueTail) return NULL; /* queue empty */

  if(header->queueFront->data) data = header->queueFront->data;
  else data = NULL;

  freeNode = header->queueFront;
  header->queueFront = header->queueFront->next;
  free(freeNode);
  //printf("delete('%s')\n", (char *)data);
  return data;
}



/***************************************************************************
 * 프로그램 시작할때 한번 호출하여 새로운 해더를 하나 만들고 초기화 한다.
 ***************************************************************************/
_QueryBuffHeader *create_query_buff_header()
{
  _QueryBuffHeader *newNode;
  newNode = (_QueryBuffHeader *)malloc(sizeof(_QueryBuffHeader ));
  newNode->stackTop=NULL;
  newNode->queueFront=NULL;
  newNode->queueTail=NULL;
  return newNode;
}

/***************************************************************************
 * 이전에 쓰던 내용이 있을지도 모르니까 리샛한다.
 ***************************************************************************/
void reset_query_buff_header(_QueryBuffHeader *headNode)
{
  register _QueryBuff *nowNode, *agoNode;
  
  nowNode = headNode->stackTop;
  while(nowNode){
    agoNode = nowNode;
    nowNode = nowNode->next;
    if(agoNode->data) free(agoNode->data);
    free(agoNode);
  } /* while(nowNode){ */

  nowNode = headNode->queueFront;
  while(nowNode){
    agoNode = nowNode;
    nowNode = nowNode->next;
    if(agoNode->data) free(agoNode->data);
    free(agoNode);
  } /* while(nowNode){ */

  /* 비어있는 노드 하나 만들어둔다. */
  headNode->queueFront = headNode->queueTail = get_new_query_buff_node();
}



/***************************************************************************
 * buff의 앞 뒤에 붙어 있는 공백 등을 모두 빼낸다.
 **************************************************************************/
char *str_trim(char *buff)
{
  register char *sP, *eP;
  char *temp;

  temp = (char *)malloc(strlen(buff)+3);

  sP = buff;			/* 앞쪽검사 */
  while(*sP){
    if( !(*sP == ' ') &&
	!(*sP == '\n') &&
	!(*sP == '\r') &&
	!(*sP == '\t')){
      break;
    }
    sP++;
  }

  if(*sP == '\0'){		/* 빈줄이다. */
    buff[0] = '\0';
    return buff;
  }

  eP = &buff[strlen(buff)-1];	/* 뒤쪽 검사 */
  while(*eP){
    if( !(*eP == ' ') &&
	!(*eP == '\n') &&
	!(*eP == '\r') &&
	!(*eP == '\t')){
      break;
    }
    eP--;
    if(eP == sP){
      break;
    }
  }
  
  *(eP+1) = '\0';
  strcpy(temp, sP);
  strcpy(buff, temp);
  free(temp);

  return buff;
}


/***************************************************************************
 * 피가 연산자인지 검사해서 연잔사면 연산자의길이를 리턴 그렇지 안니하면 0
 * 또. 리턴할때 해당 연산자의 우선순위를 리턴한다.
 * 연산자의 길이를 알고싶으면 리턴값에 %1000 
 * 연산자 우선순위를 알고싶을때 리턴값에 /1000
 ***************************************************************************/
int is_operator(char *p)
{
  if(p == NULL) return 0;
  else if (!strncmp(p, "(", 1)) return 1 + 999000;
  else if(!strncmp(p, ")", 1)) return 1 + 999000;
  else if(!strncmp(p, "+", 1)) return 1 + 11000;
  else if(!strncmp(p, "-", 1)) return 1 + 11000;
  else if(!strncmp(p, "*", 1)) return 1 + 22000;
  else if(!strncmp(p, "/", 1)) return 1 + 22000;
  
  return 0;
}


/***************************************************************************
 * string1에서 하나의 토큰을 잘라서 그 주소를 리턴하고 다음에 시작할 위치를
 * string2에 저장한다.
 ***************************************************************************/
char *get_token(char *tokenBuff, char *string1, char **string2)
{
  register char *p;
  char *tokenP;
  int operLen = 0;

  if((strlen(string1)) == 0) return NULL;

  str_trim(string1);	/* 앞뒤로 공백잘라내기. */

  tokenP = p = string1;
  while((*p != ' ')&&(*p != '\t')&&(*p != '\n')&&(*p != '\r')&& *p){
    operLen = is_operator(p) % 1000;
    if(operLen) break;
    p++;
  } /* while(*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r'){ */

  if(operLen){			/* 연산자가 발견되면 */
    if(p == tokenP){		/* 앞에 나온경우 */
      strncpy(tokenBuff, p, operLen);
      tokenBuff[operLen] = '\0';
      *string2 = p+operLen;
      return tokenBuff;
    }else{			/* 연산자가 끝에 나왔다. */
      strncpy(tokenBuff, tokenP, p-tokenP);
      tokenBuff[p-tokenP] = '\0';
      *string2 = p;
      return tokenBuff;
    } /* if(p == tokenP){ */
  } /* if(isOper){ */

  *string2 = p;
  strncpy(tokenBuff,tokenP, p-tokenP);
  return tokenBuff;
}


/***************************************************************************
 * 입력된 쿼리를 계산할 준비 다했으니 쭈~ㄱ 따라가면서 계산만 하면 된다.
 ***************************************************************************/
void process_query(_QueryBuffHeader *queryBuffHead)
{
  register char *data1, *data2, *data3;
  char string[512];
  int result;

  while((data1 = (char *)query_buff_delete(queryBuffHead))){
    //    printf("[%s]\n",data1);
    if(is_operator(data1)){	/* 연산자이면 두개 팝해서 계산하고 푸시 */
      data3 = (char *)query_buff_pop(queryBuffHead); /* 나중값을 먼저팝 */
      data2 = (char *)query_buff_pop(queryBuffHead);
      
      if(data1[0] == '+') result = atoi(data2) + atoi(data3);
      else if(data1[0] == '-') result = atoi(data2) - atoi(data3);
      else if(data1[0] == '*') result = atoi(data2) * atoi(data3);
      else if(data1[0] == '/') result = atoi(data2) / atoi(data3);
      sprintf(string, "%d",result);
      //      printf("중간 결과값 : %d\n", result);
      query_buff_push(queryBuffHead, strdup(string));
      free(data1);
      free(data2);
      free(data3);
    }else{
      query_buff_push(queryBuffHead, data1);
    } /* if(is_operator(data1)){ */
  } /* while((data1 = (char *)query_buff_delete(queryBuffHead))){ */

  data1 = (char *)query_buff_pop(queryBuffHead);
  printf("query result is [%s]\n", data1);
  free(data1);
}



#define single_test
#ifdef single_test
/***************************************************************************
 * 
 ***************************************************************************/
int main()
{
  _QueryBuffHeader *queryBuffHead;
  int i=0;

  /* 쿼리파싱할때 사용할 저장곤간을 만들고 초기화 */
  queryBuffHead = create_query_buff_header();
  reset_query_buff_header(queryBuffHead);


  while(1){/* 계산기를 한번 만들어 본다. */
    char string[512];
    char *strBuff1, *strBuff2;
    char tokenBuff[512];
    char *data1, *data2 = NULL;


    printf("%d:input string -> ",i++);
    gets(string);
    //    getchar();
    //    strcpy(string,"12+13+(34/5*4*54-45)+3243");

    printf("org string [%s]\n", string);
    strBuff2 = strBuff1 = string;	/* 앞뒤로 공백잘라내기. */


    while(get_token(tokenBuff, strBuff1, &strBuff2)){ /* 토큰분리 */
      if(!is_operator(tokenBuff)){		/* 연산자가 아니면. */
	//	printf("token -> [%s]\n", tokenBuff);
	query_buff_insert(queryBuffHead, strdup(tokenBuff));
      } else {
	//	printf("token -> [%s] _oper\n", tokenBuff);
	if(tokenBuff[0] == ')'){
	  data1 = (char *)query_buff_pop(queryBuffHead);
	  //printf("1111 -> [%s] _oper\n", data1);
	  while(data1[0] != '('){ /* 여는괄로가 나올때까지 팝해서 인서트 */
	    //printf("1112 -> [%s] _oper\n", data1);
	    query_buff_insert(queryBuffHead, data1);
	    //printf("1113 -> [%s] _oper\n", data1);
	    data1 = (char *)query_buff_pop(queryBuffHead);
	    //printf("1114 -> [%s] _oper\n", data1);
	  } /* while(data1[0] != '('){ */
	  free(data1);		/* 여는괄로 프리하기. */
	}else{
	  data1 = tokenBuff;
	  if(data1[0] == '('){	/* 괄호열리면 무조건푸시 */
	    data2 = NULL;
	    query_buff_push(queryBuffHead, strdup(data1));
	    goto endIf;
	  } /* if(data1[0] == '('){ */
	  if(data2){		/* 앞서 푸시된 연산자가 있으면. */
	    int a,b;		/* 곱하기나 나누기는 2, 더하기나 빼기는 1 */
	    
	    a = is_operator(data1); /* 연산자 우선순위를 알아온다. */
	    if((a/1000)==999) a = -1; /* 괄로는 스택안에 들어가면 우선순위가 가장 낮아진다. */
	    else a /= 1000;
	  reCmp:
	    b = is_operator(data2); /* 연산자 우선순위를 알아온다. */
	    if((b/1000)==999) b = -1; /* 괄로는 스택안에 들어가면 우선순위가 가장 낮아진다. */
	    else b /= 1000;

	    if(a > b){ 		/* 이전 연산자보다 우선순위가 높다. */		
	      data2 = (char *)query_buff_push(queryBuffHead, strdup(data1));
	    }else{		/* 이전 연산자보다 우선순위가 낮다. */
	      data2 = (char *)query_buff_pop(queryBuffHead);
	      query_buff_insert(queryBuffHead, data2);
	      data2 = (char *)query_buff_pop(queryBuffHead);
	      if(data2){	/* 다시 비교 */
		query_buff_push(queryBuffHead, data2);
		goto reCmp; 
	      }else {		/* 더이상 팝할꺼 없으면 신규 푸시 */
		data2 = (char *)query_buff_push(queryBuffHead, strdup(data1));
	      }	/* if(data2){ */
	    } /* if(a > b){ */
	  }else{
	    data2 = query_buff_push(queryBuffHead, strdup(data1));
	  } /* if(data2){ */
	} /* if(tokenBuff[0] == ')'){ */
      }	/* if(strBuff1){ */
    endIf:
      strBuff1 = strBuff2;
    } /* while(token = get_token(strBuff1, &strBuff2)){ */

    /* 스택에 남아있는거 붙인다. */
    while((data2 = (char *)query_buff_pop(queryBuffHead)))
      query_buff_insert(queryBuffHead, data2);

    /* 쭈~ㄱ 따라가면서 함 찌거본다. */
    puts("result is.....");

    process_query(queryBuffHead);
    //    return 0;
  }/* 계산기를 한번 만들어 본다. */




  {/*스택하고 큐하고 잘 동작 하는지 확인하는거  */
    char job[10];
    char string[50];
    char *data;
  restart:
    printf("input job ->  1:stack, 2:queue  :: ");
    gets(job);

    while(1){
      if(job[0] == '1'){
	printf("input action (push:1, pop:2) -> ");
	gets(string);
	if(string[0] == '1'){
	  printf("input string : ");
	  gets(string);
	  query_buff_push(queryBuffHead, strdup(string));
	}else{
	  data = (char *)query_buff_pop(queryBuffHead);
	  printf("pop : [%s]\n", data);
	  free(data);
	}	/* if(string[0] == 1){ */
      }else if(job[0] == '2'){
	printf("input action (insert:1, delete:2) -> ");
	gets(string);
	if(string[0] == '1'){
	  printf("input string : ");
	  gets(string);
	  query_buff_insert(queryBuffHead, strdup(string));
	}else{
	  data = (char *)query_buff_delete(queryBuffHead);
	  printf("delete : [%s]\n", data);
	  free(data);
	}	/* if(string[0] == 1){ */
      }else{
	puts("job error");
	goto restart;
      } /* if(job[0] == '1'){ */
    } /* while(1){ */
  }/*스택하고 큐하고 잘 동작 하는지 확인하는거  */

  return 0;
}
#endif




File attachments: 
첨부파일 크기
Plain text icon 1000000.txt445.88 KB
Forums: 
jeamvfs의 이미지

소스 100cal.c
gcc로 돌려 봤습니다.

뭔 소린지..;;;

/tmp/cckkC5Sx.o(.text+0x8b): In function `main':
: warning: the `gets' function is dangerous and should not be used.

사랑_성공은 여행

FlOw의 이미지

jeamvfs wrote:
소스 100cal.c
gcc로 돌려 봤습니다.

뭔 소린지..;;;

/tmp/cckkC5Sx.o(.text+0x8b): In function `main':
: warning: the `gets' function is dangerous and should not be used.

gets 함수가 버퍼오버플로우에 대한 검사하지 않기때문에, 위험하다는 warning 인것 같네요.
fgets로 pass =3=3

-------------------- 절취선 --
행복하세요:)

jinurius의 이미지

gets가 위험하므로 fgets를 쓰라는 말은 man page에도 나오죠.
man gets 하셔서 bug 섹션을 보시면 됩니다.

doldori의 이미지

훑어보다가 우선 눈에 띄는 문제점만 말씀드리겠습니다.

#define MAX_BUFF_SIZE   930000 

  char a[MAX_BUFF_SIZE]; 
  char b[MAX_BUFF_SIZE]; 

이렇게 큰 배열을 자동변수로 만들면 스택 오버플로우가 나기 쉽습니다. malloc()이나
정적 배열을 고려해 보세요.

smallRst = (a[lenA] - 48) + (b[lenB] - 48) + smallPa; 48은 '0'을 의도하신 것 같군요. 그렇다면 코드에 직접 '0'을 쓰십시오. 48 같은 숫자를 magic number라고 부르는데 가독성과 유지보수에 좋지 않습니다. ASCII 코드셋을 쓰지 않는 환경에서는 동작하지 않는다는 문제점도 있고요.

  for(lenC=0;i>=0;i--,lenC++){ 
    result[lenC-1] = temp[i]; 
  } 

루프 처음에 result[-1]이 되겠군요.

  lenC=0; 
  if(isMinus){ 
    result[0] = '-'; 
    lenC += 2; 
    i--; 
  } 

  for(;i>=0;i--){ 
    result[lenC-1] = temp[i]; 
    lenC++; 
  } 

마찬가지입니다. isMinus == 0인 경우에는 result[-1]이 됩니다.

if(temp1[0] != '0' || temp1[0] != '-'){ 이 조건문은 항상 참입니다. (잘 따져 보세요.) ||가 아니라 &&를 의도하신 게 아닌가요?

goto가 여기저기 흩어져 있는 것도 매우 좋지 않습니다. 보다 구조화된 방향으로
고쳐보시면 어떨까요?

qprk의 이미지

doldori wrote:
훑어보다가 우선 눈에 띄는 문제점만 말씀드리겠습니다.

#define MAX_BUFF_SIZE   930000 

  char a[MAX_BUFF_SIZE]; 
  char b[MAX_BUFF_SIZE]; 

이렇게 큰 배열을 자동변수로 만들면 스택 오버플로우가 나기 쉽습니다. malloc()이나
정적 배열을 고려해 보세요.

smallRst = (a[lenA] - 48) + (b[lenB] - 48) + smallPa; 48은 '0'을 의도하신 것 같군요. 그렇다면 코드에 직접 '0'을 쓰십시오. 48 같은 숫자를 magic number라고 부르는데 가독성과 유지보수에 좋지 않습니다. ASCII 코드셋을 쓰지 않는 환경에서는 동작하지 않는다는 문제점도 있고요.

  for(lenC=0;i>=0;i--,lenC++){ 
    result[lenC-1] = temp[i]; 
  } 

루프 처음에 result[-1]이 되겠군요.

  lenC=0; 
  if(isMinus){ 
    result[0] = '-'; 
    lenC += 2; 
    i--; 
  } 

  for(;i>=0;i--){ 
    result[lenC-1] = temp[i]; 
    lenC++; 
  } 

마찬가지입니다. isMinus == 0인 경우에는 result[-1]이 됩니다.

if(temp1[0] != '0' || temp1[0] != '-'){ 이 조건문은 항상 참입니다. (잘 따져 보세요.) ||가 아니라 &&를 의도하신 게 아닌가요?

goto가 여기저기 흩어져 있는 것도 매우 좋지 않습니다. 보다 구조화된 방향으로
고쳐보시면 어떨까요?

잘 보았습니다.
100cal.c 는 예전부터 한번 만들어 보고 싶었던던데.. 네이버 지식인에서 질문이 올아와서 만든것입니다. 뭐 말그대로 재미삼아 만들었으니 여기 저기 goto 문이 들어있기도 하구요 ^^
앞으로 코딩 하는데 좀더 신중해야 할 필요가 있을것 같내요..

정작 중요한건 두번째 코드인데.. 여기 글올리고도 몇가지 버그를 잡았내요..

신경써 주셔서 감사합니다. :D

멋진남자...

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.