#ifdef _DEBUG
#ifndef DEBUG_if_err
#define DEBUG_if_err(a) if(a){on_err();}else{}
#endif
#include "windows.h"
void DEBUG_puts(char *s)
{
OutputDebugString(s);
OutputDebugString("\r\n");
}
void DEBUG_puts_int(char *s, int a)
{
char buf[1024];
sprintf(buf, "%s=%d", s, a);
DEBUG_puts(buf);
}
void DEBUG_puts_int_str(char *s, int a,char *s2)
{
char buf[1024];
sprintf(buf, "%s=%d%s", s, a, s2);
DEBUG_puts(buf);
}
void DEBUG_puts_str(char *s, char *a)
{
char buf[1024];
sprintf(buf, "%s=\"%s\"", s, a);
DEBUG_puts(buf);
}
void DEBUG_puts_char_str(char *s, char c, char *a)
{
char buf[1024];
sprintf(buf, "%s=%c%s", s, c,a);
DEBUG_puts(buf);
}
void DEBUG_puts_float(char *s, float a)
{
char buf[1024];
sprintf(buf, "%s=%f", s, a);
DEBUG_puts(buf);
}
void DEBUG_puts_double(char *s, double a)
{
char buf[1024];
sprintf(buf, "%s=%f", s, a);
DEBUG_puts(buf);
}
void on_err()
{
DEBUG_puts("ERR : on_err");
}
#else
#ifndef DEBUG_if_err
#define DEBUG_if_err(a)
#endif
#ifndef DEBUG_puts
#define DEBUG_puts(a)
#define DEBUG_puts_int(s,a)
#define DEBUG_puts_str(s,a)
#define DEBUG_puts_float(s,a)
#endif
#endif
int isspace(char a)//isspace에서 큰값(한글 일부)을 넣으면 오류발생하여 추가
{
int ret = 0;
switch (a)
{
case ' ':case '\t':case '\r':case '\n':
ret = 1;
break;
default:
break;
}
return ret;
}
char *skip_space(char *s)
{
char a;
while (s)
{
a = *s;
if (strchr(" \t\r\n", a) == 0)
{
break;
}
else
{
s++;
}
}
return s;
}
char *del_space_all(char *s,char *out)
{
char a,*w=out;
//DEBUG_puts_str("del_space_all()", s);
if (s)
{
while (1)
{
a = *s;
if (a == 0)
{
break;
}
else
{
switch (a)
{
case ' ':case '\r':case '\n':case '\t':
//del
break;
default:
*w = a;
w++;
break;
}
}
s++;
}
}
*w = 0;
//DEBUG_puts_str("del_space_all() out", out);
return w;
}
char *skip_space_rev(char *str,char *pNow)//ret=뒷쪽의 첫 스페이스 문자
{
while (pNow > str)
{
if (isspace(*pNow))
{
pNow--;
}
else
{
pNow++;
break;
}
}
return pNow;
}
//+,- e지수, 소수점 숫자 문자열 처음 찾기(strtof)
//pNow는 앞쪽 숫자의 일부여야한다.
char *find_number_str_start_rev(char *str, char *pNow,int *err)
{
char a; int e_cnt = 0, e_num_cnt=0,dot_cnt=0,pluse_cnt=0, minus_cnt=0, pluse_minus_cnt = 0 ;
*err = 0;
if (str == pNow)
{
//pNow = str;
}
else
{
while (isspace(*pNow))
{
pNow--;
}
while (pNow >= str)
{
a = *pNow;
if (isdigit(a))
{
//ok
if (e_cnt == 0)
{
//e 지수 뒷쪽 숫자
e_num_cnt++;
}
else
{
//e 지수 앞쪽 숫자
}
}
else if ((a == '-') || (a == '+'))
{
if (pNow != str)
{
if ((pNow[-1] == 'e') || (pNow[-1] == 'E'))
{
//e지수.계속
pNow--;
e_cnt++;
}
else if (isdigit(pNow[-1]))
{
//앞은 숫자. 부호는 남겨놓아야한다.
pNow++;
break;
}
else
{
//e지수 아님.부호로 처리
break;
}
}
else
{
//첫문자.부호
break;
}
}
else if ((a == 'e') || (a == 'E'))
{
e_cnt++;
if (e_cnt == 1)
{
//ok
pluse_minus_cnt = 0;
minus_cnt = 0;
pluse_cnt = 0;
}
else
{
//err. e가 2번이상 나옴
*err = 1;
DEBUG_puts_str("ERR : 숫자 에러. 지수문자'e'가 2번이상 나옴", str);
break;
}
}
else if (a == '.')
{
if (dot_cnt == 0)
{
//ok
dot_cnt = 1;
}
else
{
//.이 2번이상 나옴
*err = 1;
DEBUG_puts_str("ERR : 숫자 에러. '.'이 2번이상 나옴", str);
break;
}
}
else if (strchr(" \t\r\n", a) == 0)
{
//space
pNow++;
break;
}
else
{
pNow++;
break;
}
if (pNow > str)
{
pNow--;
}
else
{
break;
}
}
}
DEBUG_if_err(pNow < str);
return pNow;
}
char *find_number_str_end(char *str, int *err)//숫자 문자열의 마지막 찾기
{
char a,*pNow= str; int e_cnt = 0, e_num_cnt = 0, dot_cnt = 0;
*err = 0;
while (1)
{
a = *pNow;
if (a == 0)
{
break;
}
else
{
if (isdigit(a))
{
//ok
if (e_cnt == 0)
{
//e 지수 앞쪽 숫자
e_num_cnt++;
}
else
{
//e 지수 뒷쪽 숫자
}
}
else if (strchr(" \t\r\n", a) == 0)
{
//space
break;
}
else if ((a == 'e') || (a == 'E'))
{
if (e_cnt == 0)
{
//ok
e_cnt = 1;
}
else
{
//err. e가 2번이상 나옴
*err = 1;
DEBUG_puts_str("ERR : 숫자 에러. 지수문자'e'가 2번이상 나옴", str);
break;
}
}
else if (a == '.')
{
if (dot_cnt == 0)
{
//ok
dot_cnt = 1;
}
else
{
//.이 2번이상 나옴
*err = 1;
DEBUG_puts_str("ERR : 숫자 에러. '.'이 2번이상 나옴", str);
break;
}
}
else
{
break;
}
}
pNow++;
}
return pNow;
}
void strcpy_wc(wchar_t *buf, char *s)
{
int nLen = MultiByteToWideChar(CP_ACP,
0,
s, -1,
NULL,
NULL);
MultiByteToWideChar(CP_ACP,
0,
s, -1,
buf,
nLen);
}
void strcpy_cw(char *buf, wchar_t *s)//max=1024
{
if (buf)if (s)
{
WideCharToMultiByte(CP_ACP,
0,
s, -1,
buf, 1024,
NULL,
NULL);
}
}
void strcat_wc(wchar_t *buf, char *s)
{
if (buf)if (s)
{
while (*buf)buf++;
int nLen = MultiByteToWideChar(CP_ACP,
0,
s, -1,
NULL,
NULL);
MultiByteToWideChar(CP_ACP,
0,
s, -1,
buf,
nLen);
}
}
void strcat_cw(char *buf, wchar_t *s)//max=1024
{
if (buf)if (s)
{
WideCharToMultiByte(CP_ACP,
0,
s, -1,
buf, 1024,
NULL,
NULL);
}
}
int is_all_spcace(char *s)
{
int bSpace = 1;
while (*s)
{
if (isspace(*s))
{
//bSpace = 1;
}
else
{
bSpace = 0;
break;
}
s++;
}
return bSpace;
}
char *get_line(char *str, char *buf)//\r\n포함
{
char a;
while (1)
{
a = *str;
*buf = a;
if (a == 0)break;
if (a == '\n')
{
str++;
break;
}
else
{
buf++;
str++;
}
}
*buf = 0;
return str;
}
char *skip_empty_1line(char *s)//1줄만 skip
{
char *p = s,*p_old=s;
while (*s)
{
if (isspace(*s))
{
if (*s == '\n')
{
s++;//1줄만 skip
break;
}
else
{
s++;
}
}
else
{
s = p_old;//빈줄이 아닐때, 앞부분 공백문자들 삭제 안함
break;
}
}
return s;
}
char *skip_empty_line_all(char *s)//빈줄 모두 skip
{
char *p;
while (*s)
{
p = skip_empty_1line(s);
if (p != s)
{
s = p;
}
else
{
s = p;
break;
}
}
return s;
}
//spilt문자로 구분된 문자열에서, i0번째 문자열의 시작주소를 얻음
char *spilt_str_get_i(char *s, int i0,char *buf,char spilt)
{
char *p = s, *pf;
*buf = 0;
while(*p)
{
if (i0 == 0)
{
break;
}
else
{
pf = strchr(p, spilt);
if (pf)
{
p = pf + 1;
i0--;
}
else
{
//더이상 없음
p = 0;
break;
}
}
}
if (p)
{
p=strcpy_while_not_char(p, buf, spilt);
}
else
{
}
return p;
}
int spilt_str_get_i_int(char *s, int i0, char spilt)
{
char buf[1024];
spilt_str_get_i(s, i0, buf, spilt);
return atoi(buf);
}
double spilt_str_get_i_double(char *s, int i0, char spilt)
{
char buf[1024];
spilt_str_get_i(s, i0, buf, spilt);
return ATOF(buf);
}
//탭문자로 구분된 문자열에서, i0번째 문자열의 시작주소를 얻음
char *tab_str_get_i(char *s, int i0, char *buf)
{
return spilt_str_get_i(s, i0,buf, '\t');
}
char *skip_tab(char *p, int n)
{
if (p)
{
while (n > 0)
{
p = strchr(p, '\t');
if (p == 0)break;
p++;
n--;
}
}
else
{
//NULL
}
return p;
}
char *strcpy_while_not_char(char *s, char *buf, char c)
{
while (*s)
{
if (*s == c)
{
s++;
break;
}
else
{
*buf = *s;
buf++;
s++;
}
}
*buf = 0;
return s;
}
char *strcpy_while_not_chars(char *s, char *buf, char *c)
{
char a;
while (*s)
{
a = *s;
s++;
*buf = a;
if (strchr(c,a))
{
break;
}
else
{
buf++;
}
}
*buf = 0;
return s;
}
char *strcpy_while_not_chars_num(char *s, char *buf, char *c)//+,-를 가지는 숫자인 경우,+,-도 포함한다.
{
char a;
if (s)
{
s = skip_space(s);
//첫번째 문자가 c에 있는 문자라면 포함된다.
if (strchr(c, *s))
{
*buf = *s;
buf++;
s++;
}
else
{
}
while (*s)
{
a = *s;
*buf = a;
if (strchr(c, a))
{
//2번째 문자인 경우, 다음번에 넣는다.
//s++;
break;
}
else
{
buf++;
s++;
}
}
}
else
{
}
*buf = 0;
return s;
}
int str_cnt(char *str, char *a)
{
int cnt = 0,len_a;
char *p=str;
if (p)
{
if (a)
{
len_a = strlen(a);
while (*p)
{
p = strstr(p, a);
if (p == 0)
{
break;
}
else
{
cnt++;
p += len_a;
}
}
}
else
{ }
}
else
{ }
return cnt;
}
int str_change(char *str, char *a, char *b, char *out_buf)//str==out_buf인 경우, 크기가 증가하면 에러 발생
{
int cnt = 0, len, len_a;
char *p, *pend,*pfree=0;
if (str)
{
p = strstr(str, a);
if (p)
{
/*DEBUG_puts("@str");
DEBUG_puts(str);
DEBUG_puts("@p");
DEBUG_puts(p);
DEBUG_puts("@a");
DEBUG_puts(a);*/
len = p - str;
len_a = strlen(a);
pend = p + len_a;
if (((int)strlen(b)) > len_a)
{
pend = strdup(pend);
pfree = pend;
}
else
{
}
strncpy(out_buf, str, len);
strcpy(out_buf+ len, b);
strcat(out_buf, pend);
cnt = 1;
free(pfree);
}
else
{
if(out_buf!= str)
{
strcpy(out_buf, str);
}
else
{
//동일한 버퍼임
}
}
}
else
{
if (out_buf)
{
*out_buf = 0;
}
else
{
}
}
return cnt;
}
int str_change_all(char *str, char *a, char *b, char *out_buf)
{
int cnt = 0;
while (str_change(str,a,b,out_buf))
{
str = out_buf;
cnt++;
}
return cnt;
}
char *strchr_rev(char *s, char *pnow, char find)
{
char *p = 0;
while (pnow >= s)
{
if (*pnow == find)
{
p = pnow;
break;
}
else
{
pnow--;
}
}
return p;
}
char *strchr_first(char *s, char *find)//find문자들 중에 첫번째 나오는 문자를 찾는다.
{
char *ret = 0;
while (*s)
{
if (strchr(find, *s))
{
//found
ret = s;
break;
}
else
{
//not found
}
s++;
}
return ret;
}
char *strdup1024(char *s)//할당된 메모리에 문자열을 추가할 경우에만 사용
{
int len;
char *p = 0;
if (s)
{
len = strlen(s) + 1024;
p = (char*)malloc(len);
strcpy(p, s);
}
else
{
}
return p;
}
int double_is_EQ(double a, double b)
{
/*부동소수점 계산 오류로 인해, 소수점 5자리이하가 int형변환 해도 계속 1씩 틀리는 문제가 있음.
int ia, ib;
ia = (int)(a * 10000);
ib = (int)(b * 10000);
return ia == ib;*/
char bufa[32], bufb[32];
//계산순서에 따라, 소수점 6째자리숫자가 다를 수 도 있다.(부동소수점 오류) "/1000"해줌
//sprintf(bufa, "%f", a);
//sprintf(bufb, "%f", b);
sprintf(bufa, "%f", a / 1000);
sprintf(bufb, "%f", b / 1000);
return strcmp(bufa, bufb) == 0;
}
char *ToUpperstr(char *s,char *buf)
{
while (*s)
{
*buf = toupper(*s);
s++;
buf++;
}
*buf = 0;
return s;
}
char *stristr(char *s,char *find)
{
char *p;
p = strstr(s, find);
if (p == 0)
{
char *s2, *find2;
s2 = strdup(s);
find2 = strdup(find);
ToUpperstr(s2, s2);
ToUpperstr(find2, find2);
p = strstr(s2, find2);
if (p)
{
p = s + (p - s2);
}
else
{
}
free(s2);
free(find2);
}
else
{
}
return p;
}
char *trim(char *s,char *buf)
{
char a,*p;
s = skip_space(s);
if (s)
{
strcpy(buf, s);
p = buf + strlen(buf)-1;
while (p>buf)
{
a = *p;
if (a == 0)
{
break;
}
else
{
if (isspace(a))
{
//skip
*p = 0;
}
else
{
break;
}
}
p--;
}
}
else
{
*buf = 0;
}
return buf;
}
char *strcpy_if_not_same(char *dst, char *src)
{
char *ret = 0;
if (dst != src)
{
ret=strcpy(dst, src);
}
else
{
ret = dst;
}
return ret;
}
double ATOF(char *s)//지수 e를 포함하는 문자열을 double로 변환
{
char *pend;
return strtof(s, &pend);
}
char *get_brace_str_out(char *s, char strat, char end, s_get_brace_str *pret)//괄호 안쪽 문자열 얻기(중복괄호 허용)
{
char *p,*ps,*pe,a,*pfree;
int len, strat_cnt;
memset(pret, 0, sizeof(s_get_brace_str));
p = strchr(s, strat);
if (p)
{
ps = p+1;
while (1)
{
a = *p;
if (a == 0)
{
break;
}
else
{
if (a == strat)
{
strat_cnt++;
}
else if (a == end)
{
strat_cnt--;
if (strat_cnt == 1)
{
//ok
pe = p-1;
len = pe - ps;
pfree= (char*)malloc(len + 1);
if (pfree)
{
strncpy(pfree, p, len);
pfree[len] = 0;
//ok
pret->len = len;
pret->ps = ps;
pret->pe = pe;
pret->pfree = pfree;
break;
}
else
{
//err
}
break;
}
else
{
//계속
}
}
}
p++;
}
}
else
{
}
return p;
}
//괄호 안쪽 문자열 얻기(중복괄호 허용. 안쪽 괄호문자.중첩된 괄호는 없다.)
char *get_brace_str_in(char *s, char strat, char end, s_get_brace_str *pret)
{
char *p, *ps, *pe, *pfree;
int len;
memset(pret, 0, sizeof(s_get_brace_str));
p = strrchr(s, strat);
if (p)
{
ps = p ;
pe =strchr(p + 1, end);
if(pe)
{
//ok
len = pe+1 - ps;
pfree = (char*)malloc(len + 1);
if (pfree)
{
strncpy(pfree, p, len);
pfree[len] = 0;
//ok
pret->len = len;
pret->ps = ps;
pret->pe = pe;
pret->pfree = pfree;
}
else
{
//err
}
}
else
{ }
}
else
{
}
return p;
}
void trim_and_del_str_mark(char *s)//문자열 따옴표 제거
{
char *p = s;
trim(p, p);
if (*p == '\"')
{
strcpy(s, p + 1);
p = strrchr(s, '\"');
if (p)
{
strcpy(p, p + 1);
}
else
{
}
}
else
{
}
trim(s,s);
}
void del_str_mark(char *s)//문자열 따옴표 제거
{
char *p = s;
p = strchr(s, '\"');
if (p)
{
strcpy(p, p + 1);
}
else
{ }
p = strrchr(s, '\"');
if (p)
{
strcpy(p, p + 1);
}
else
{
}
}
static char *bht = "0123456789ABCDEF";
char *BinToHEX(void *pbin, int len, char *buf)
{
byte1 *p = (byte1*)pbin, a;
char *pbuf = buf;
while (len)
{
a = *p;
pbuf[0] = bht[a >> 4];
pbuf[1] = bht[a & 0x0f];
pbuf[2] = ' ';
pbuf += 3;
len--;
p++;
}
*pbuf = 0;
return pbuf;
}
int HEX1_to_bin(char a, byte1 *b)
{
int bok = 1;
if (('0' <= a) && (a <= '9'))
{
*b = a - '0';
//bok=1;
}
else if (('A' <= a) && (a <= 'F'))
{
*b = a - 'A' + 10;
//bok=1;
}
else if (('a' <= a) && (a <= 'f'))
{
*b = a - 'a' + 10;
//bok=1;
}
else
{
bok = 0;
}
return bok;
}
char *HEX_str_to_bin(char *hex_str, byte1 *buf, int *len)
{
int rlen = 0;
byte1 b, s = 0, cnt = 0, temp;
char c, *p;
while (1)
{
c = *hex_str;
if (c == 0)break;
if (c == '\n')
{
hex_str++;
break;
}
else if (c == ' ')
{
//next
if (cnt)
{
*buf = b;
buf++;
//b=0;
rlen++;
cnt = 0;
}
else
{
//skip
}
}
else if (c == '\t')
{
//next
if (cnt)
{
*buf = b;
buf++;
//b=0;
rlen++;
cnt = 0;
}
else
{
//skip
}
}
else if (c == ';')//주석문
{
p = strchr(hex_str + 1, '\n');
if (p)
{
hex_str = p + 1;
}
else
{
hex_str = 0;
break;
}
}
else
{
if (HEX1_to_bin(c, &temp) == 0)
{
break;
}
else
{
//ok
if (cnt == 0)
{
b = temp;
cnt++;
}
else
{
*buf = (byte1)((b << 4) | temp);
//b=0;
buf++;
rlen++;
cnt = 0;//reset
}
}
}
hex_str++;
}
if (cnt)
{
*buf = b;
buf++;
//b=0;
rlen++;
cnt = 0;
}
*len = rlen;
return hex_str;
}
int str_has_alphabet(char *s)
{
int ret = 0;
while (*s)
{
if (isalpha(*s))
{
ret = 1;
break;
}
else
{
s++;
}
}
return ret;
}
wchar_t *strrchr(wchar_t *s,wchar_t ch)
{
if(s==0)return 0;
if(*s==0)return 0;
return wcsrchr(s,ch);
}
wchar_t *strcpy(wchar_t *dest,wchar_t *src)
{
wchar_t *pd=dest,*p=src;
if(pd==0)return 0;
if(p)
{
while(*p)
{
*pd=*p;
p++;
pd++;
}
}
*pd=0;
return pd;
}
int strlen(const wchar_t *s)
{
if(s==0)return 0;
if(*s==0)return 0;
return wcslen(s);
}
int _unlink(wchar_t *file)
{
return _wunlink(file);
}
inline FILE *fopen(wchar_t *filename,wchar_t *mode)
{
return _wfopen(filename,mode);
}
WIN32_FIND_DATA *GetFileInfo(TCHAR *file,WIN32_FIND_DATA *fd)
{
__int64 len=0;HANDLE h;WIN32_FIND_DATA *ret=0;
h=FindFirstFile(file,fd);
if((h==INVALID_HANDLE_VALUE) && (::GetLastError()==ERROR_FILE_NOT_FOUND))
{
//CD롬에서 일부 파일이 복사가 안되는 문제로 추가
//err
}
else
{
ret=fd;//ok
}
if(h!=INVALID_HANDLE_VALUE)
{
FindClose(h);
}
return ret;
}
__int64 GetFileSize(TCHAR *file)
{
__int64 len=0;WIN32_FIND_DATA fd;
if(GetFileInfo(file,&fd))
{
len=(__int64)fd.nFileSizeHigh*(__int64)fd.nFileSizeLow;
}
return len;
}
void FILETIME_to_SYSTEMTIME(FILETIME *ft,SYSTEMTIME *st)
{
SYSTEMTIME ust;
FileTimeToSystemTime(ft,&ust);
SystemTimeToTzSpecificLocalTime(0,&ust,st);//파일은 Localtime사용하지 말라
}
src.zip
#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"
#include "Lib.h"
#include "string.h"
#pragma warning(disable:4996)
void str_cal_change_all_meanless_str(char *s, char *buf);//의미없는 문자들을 제거한다.
char *ftoa(double v, char *buf)
{
sprintf(buf, "%f", v);
//불필요한 소수점 제거
str_change_all(buf, ".000000", "", buf);
return buf;
}
void double_to_str_add_str(char *buf,double b,char *padd)//double을 문자열로 바꾸고, 불필요한 소수점이하 0을 제거, 문자열 추가
{
char *pfree = 0;
//buf가 문자열이고, padd가 문자열의 뒷부분인 경우. 겹쳐쓰기가 될 수 있다.
if ((padd >= buf) && ((padd - buf) < 16))//부동소수점 문자열 길이
{
padd = strdup1024(padd);//문자열을 추가할 여분의 버퍼
pfree = padd;
}
else
{
}
//sprintf(buf, "%f", b);
//불필요한 소수점 제거
//str_change_all(buf, ".000000", "", buf);
ftoa(b, buf);
strcat(buf, padd);
if (pfree)
{
free(pfree);
}
str_cal_change_all_meanless_str(buf, buf);//의미없는 문자들을 제거한다.
}
int function_to_str(char *str, char *buf);
double str_to_double(char *s)//변수, 함수가 들어 있는 문자열을 double로 변환
{
DEBUG_puts("작성중...");
return atof(s);
}
//치환할 변수,함수,괄호가 없는 문자열에 대해서 사칙연산 수행
double no_variable_no_brace_str_calculation(char *str)
{
double result = 0, a, b;
int err = 0;
char *p, op, *pa, *pend, buf[64];
if (str)
{
/*효과가 별로 없다. if ((strchr(str, '+') == 0) &&
(strchr(str, '-') == 0) &&
(strchr(str, '*') == 0) &&
(strchr(str, '/') == 0) &&
(strchr(str, '%') == 0))
{
//연산자가 없다.
result = atof(buf);//"+ 2.0"은 0이 된다.
}
else*/
{
str = strdup1024(str);//짧은 문자열 할당후 긴문장을 쓰는 경우 에러
//del_space_all(str, str);
str_cal_change_all_meanless_str(str, str);//의미없는 문자들을 제거한다.
DEBUG_if_err(strchr(str, '{'));
DEBUG_if_err(strchr(str, '}'));
DEBUG_if_err(strchr(str, '('));
DEBUG_if_err(strchr(str, ')'));
//곱셈,나눗셈,나머지연산 먼져 수행.빠른것 부터 계산
while (1)
{
DEBUG_puts_str("str", str);
p = strchr_first(str, "*/%");
if (p)
{
op = *p;
*p = 0;
pa = find_number_str_start_rev(str, p - 1, &err);
if (err == 0)
{
a = strtof(pa, &pend);
b = strtof(p + 1, &pend);
switch (op)
{
case '*':
result = a * b;
break;
case '/':
if (b == 0)
{
b = 0.00000000000001f;
}
else
{
}
result = a / b;
break;
case '%':
result = ((int)a) % ((int)b);
break;
default:
//err
on_err();
break;
}
double_to_str_add_str(pa, result, pend);//double을 문자열로 바꾸고, 불필요한 소수점이하 0을 제거, 문자열 추가
}
else
{
//err
on_err();
break;
}
}
else
{
break;
}
}
str_cal_change_all_meanless_str(str, str);//의미없는 문자들을 제거한다.
result = 0;//str안에 값이 들어 있다.
//첫번째 +/-가 연산자라고 보기는 어렵다.
//+/-로 문자열을 나누고, 각 숫자를 모두 합한다.
p = str;
while (*p)
{
p = strcpy_while_not_chars_num(p, buf, "+- ");
result += atof(buf);//"+ 2.0"은 0이 된다.
}
free(str);
}
}
else
{
}
return result;
}
//str은 {...{..(...)...}...}...
//{},()가 있는 연산식 계산.중첩 허용
double no_variable_str_calculation_with_brace(char *str)
{
double ret=0,a=0,b = 0;
char *pb, *pc, *p;// , *pfree = 0;
p = str;
if (str)
{
DEBUG_puts_str("no_variable_str_calculation_with_brace()", str);
if (*str)
{
//문자열을 {}또는 ()를 기준으로 3개로 나누어 계산한다.
//예) A{B}C
//{}먼져 처리해야한다.
//{..{..}..}...{..{..}..}
//{}처리
p = str;//p = pfree;
//{}괄호처리
while (*p)
{
DEBUG_puts_str("\r\nno_variable_str_calculation_with_brace()", str);
pb = strrchr(p, '{');//마지막
if (pb)
{
*pb = 0;
pc = strchr(pb+1, '}');//첫번째
if (pc == 0)
{
//마지막 괄호 없음. 끝까지 모두 계산
pc = "";
}
else
{
*pc = 0;
pc++;
}
b = no_variable_str_calculation_with_brace(pb + 1);//{} 계산
double_to_str_add_str(pb, b, pc);//double을 문자열로 바꾸고, 불필요한 소수점이하 0을 제거, 문자열 추가
}
else
{
//{}없음
break;
}
}
//{}괄호 없음
//()괄호처리
while(*p)
{
DEBUG_puts_str("\r\nno_variable_str_calculation_with_brace()", str);
pb = strrchr(p, '(');
if (pb)
{
*pb = 0;
pc = strchr(pb+1, ')');
if (pc == 0)
{
//마지막 괄호 없음. 끝까지 모두 계산
pc = "";
}
else
{
*pc = 0;
pc++;
}
b = no_variable_str_calculation_with_brace(pb + 1);//() 계산
double_to_str_add_str(pb, b, pc);
}
else
{
//()괄호 없음
break;
}
}
ret = no_variable_no_brace_str_calculation(p);//모든 식 계산
//free(pfree);
}
else
{
//""
}
}
else
{
//NULL
}
DEBUG_puts_double("ret", ret);
return ret;
}
void variable_to_str(char *s, char *buf);//변수를 변수값문자열로 변환
void str_cal_change_all_meanless_str(char *s, char *buf)//의미없는 문자들을 제거한다.
{
del_space_all(s, buf);//s = skip_space(s);
if (strlen(buf) > 2)
{
str_change_all(buf, "--", "+", buf);
str_change_all(buf, "+-", "-", buf);
str_change_all(buf, "++", "+", buf);
str_change_all(buf, "-+", "-", buf);
str_change_all(buf, "*+", "*", buf);
str_change_all(buf, "/+", "/", buf);
str_change_all(buf, "%+", "%", buf);
str_change_all(buf, "E+", "E", buf);
str_change_all(buf, "e+", "e", buf);
str_change_all(buf, "(+", "(", buf);
str_change_all(buf, "[+", "[", buf);
str_change_all(buf, "{+", "{", buf);
}
else
{
}
}
//괄호, 변수, 함수를 포함하는 사칙연산 연산식을 계산한다
double str_calculation_with_brace_func_variable(char *s)
{
char buf[1024], buf2[1024];
//함수의()와 산술식의 ()를 구분해야한다.
//함수의()를 먼져 계산
str_cal_change_all_meanless_str(s, buf2);
s = buf2;
variable_to_str(s, buf);//변수를 변수값문자열로 변환
//식은 사칙연산이나 함수를 포함할 수 있습니다.
//함수를 결과값으로 변환합니다.
function_to_str(buf, buf2);
//괄호를 포함하는 식 계산
return no_variable_str_calculation_with_brace(buf2);
}
#ifdef _DEBUG
class DEBUG_test_cal
{
public:
void test1()
{
sStr_double a[] = {
//문제 정답
//나눗셈의 분자나 분모중 하나는 실수여야한다.
{" ( + 11 ) + ( - 2 ) ", (+11) + (-2) },
{" ( + 12 ) - ( + 9 ) ", (+12) - (+9) },
{" ( + 7 ) * ( - 8 ) ", (+7) * (-8) },
{" ( + 7 ) * ( - 2 ) ", (+7) * (-2) },
{" ( - 10 ) + ( - 10 ) ", (-10) + (-10) },
{" ( - 4 ) * ( - 14 ) ", (-4) * (-14) },
{" ( - 13 ) + ( - 4 ) ", (-13) + (-4) },
{" ( + 7 ) + ( - 2 ) ", (+7) + (-2) },
{" ( + 14 ) / ( - 9 ) ", (+14) / (-9.0f) },
{" ( - 14 ) * ( - 14 ) ", (-14) * (-14) },
{" ( + 11 ) + ( -2 ) ", (+11) + (-2) },
{" ( + 12 ) - ( + 9 ) ", (+12) - (+9) },
{" ( + 7 ) * ( -8 ) ", (+7) * (-8) },
{" ( + 7 ) * ( -2 ) ", (+7) * (-2) },
{" ( -10 ) + ( -10 ) ", (-10) + (-10) },
{" ( -4 ) * ( -14 ) ", (-4) * (-14) },
{" ( -13 ) + ( -4 ) ", (-13) + (-4) },
{" ( + 7 ) + ( -2 ) ", (+7) + (-2) },
{" ( + 14 ) / ( -9 ) ", (+14) / (-9.0f) },
{" ( -14 ) * ( -14 ) ", (-14) * (-14) },
{" ( +11 ) + ( -2 ) ", (+11) + (-2) },
{" ( +12 ) - ( +9 ) ", (+12) - (+9) },
{" ( +7 ) * ( -8 ) ", (+7) * (-8) },
{" ( +7 ) * ( -2 ) ", (+7) * (-2) },
{" ( -10 ) + ( -10 ) ", (-10) + (-10) },
{" ( -4 ) * ( -14 ) ", (-4) * (-14) },
{" ( -13 ) + ( -4 ) ", (-13) + (-4) },
{" ( +7 ) + ( -2 ) ", (+7) + (-2) },
{" ( +14 ) / ( -9 ) ", (+14) / (-9.0f) },
{" ( -14 ) * ( -14 ) ", (-14) * (-14) },
{"(+11)+(-2)", (+11) + (-2)},
{"(+12)-(+9)", (+12) - (+9)},
{"(+7)*(-8)", (+7)*(-8)},
{"(+7)*(-2)", (+7)*(-2)},
{"(-10)+(-10)", (-10) + (-10)},
{"(-4)*(-14)", (-4)*(-14)},
{"(-13)+(-4)", (-13) + (-4)},
{"(+7)+(-2)", (+7) + (-2)},
{"(+14)/(-9)", (+14) / (-9.0f)},
{"(-14)*(-14)", (-14)*(-14)},
{"(+11)+(-2)*(+12)-(+9)", (+11) + (-2)*(+12) - (+9)},
{"(+12)-(+9)/(+7)*(-8)", (+12) - (+9) / (+7.0f)*(-8.0f)},
{"(+7)*(-8)*(+7)*(-2)", (+7)*(-8)*(+7)*(-2)},
{"(+7)*(-2)/(-10)+(-10)", (+7)*(-2) / (-10.0f) + (-10)},
{"(-10)+(-10)-(-4)*(-14)", (-10) + (-10) - (-4)*(-14)},
{"(-4)*(-14)+(-13)+(-4)", (-4)*(-14) + (-13) + (-4)},
{"(-13)+(-4)*(+14)/(-9)/(+7)+(-2)", (-13) + (-4)*(+14) / (-9.0f) / (+7.0f) + (-2)},
{"(-14)*(-14)+(+14) / (-9)-(+7) + (-2)", (-14)*(-14) + (+14) / (-9.0f) - (+7) + (-2)},
{"+11+-2*+12-+9", +11 + -2 * +12 - +9},
{"+12-+9/+7*-8", +12 - +9 / +7.0f*-8},
{"+7*-8*+7*-2", +7 * -8 * +7 * -2},
{"+7*-2/-10+-10", +7 * -2 / -10.0f + -10},
{"-10+-10--4*-14", -10 + -10 - -4 * -14},
{"-4*-14+-13+-4", -4 * -14 + -13 + -4},
{"-13+-4*+14/-9/+7+-2", -13 + -4 * +14 / -9.0f / +7.0f + -2},
{"-14*-14+ +14 / -9-+7 + -2", -14 * -14 + +14 / -9.0f - +7 + -2},
{"-14*-14 + +14 / -9-+7 + -2", -14 * -14 + +14 / -9.0f - +7 + -2},
{"-14*-14 + + 14 / -9-+7 + -2", -14 * -14 + +14 / -9.0f - +7 + -2},
{"-14*-14++ 14 / -9-+7 + -2", -14 * -14 + +14 / -9.0f - +7 + -2},
{"-14*-14 ++14 / -9-+7 + -2", -14 * -14 + +14 / -9.0f - +7 + -2},
{"-14*-14++14 / -9 -+7 + -2", -14 * -14 + +14 / -9.0f - +7 + -2},
{"-14*-14++14 / -9- +7 + -2", -14 * -14 + +14 / -9.0f - +7 + -2},
{"-14*-14++14 / -9-+ 7 + -2", -14 * -14 + +14 / -9.0f - +7 + -2},
{"-14*-14++14 / -9 -+ 7 + -2", -14 * -14 + +14 / -9.0f - +7 + -2},
{"-14*-14++14 / -9 - + 7 + -2", -14 * -14 + +14 / -9.0f - +7 + -2},
{"((+11)+(-2))*(+12)-(+9)", ((+11) + (-2))*(+12) - (+9)},
{"(+12)-((+9)/(+7))*(-8)", (+12) - ((+9) / (+7.0f))*(-8)},
{"(+7)*((-8)*(+7)*(-2))", (+7)*((-8)*(+7)*(-2))},
{"((+7)*(-2))/((-10)+(-10))", ((+7)*(-2)) / ((-10.0f) + (-10))},
{"((-10)+(-10)-(-4)*(-14))", ((-10) + (-10) - (-4)*(-14))},
{"((-4)*(-14))+(-13)+(-4)", ((-4)*(-14)) + (-13) + (-4)},
{"(((-13)+(-4))*(+14))/(-9)/(+7)+(-2)", (((-13) + (-4))*(+14)) / (-9.0f) / (+7) + (-2)},
{"((-14)*(-14))+((+14) / (-9)-(+7) + (-2))", ((-14)*(-14)) + ((+14) / (-9.0f) - (+7) + (-2))},
{"((+11.3)+(-2.3))*(+12.3)-(+9.3)", ((+11.3) + (-2.3))*(+12.3) - (+9.3)},
{"(+12.3)-((+9.3)/(+7.3))*(-8.3)", (+12.3) - ((+9.3) / (+7.3f))*(-8.3)},
{"(+7.3)*((-8.3)*(+7.3)*(-2.3))", (+7.3)*((-8.3)*(+7.3)*(-2.3))},
{"((+7.3)*(-2.3))/((-10.3)+(-10.3))", ((+7.3)*(-2.3)) / ((-10.3f) + (-10.3))},
{"((-10.3)+(-10.3)-(-4.3)*(-14.3))", ((-10.3) + (-10.3) - (-4.3)*(-14.3))},
{"((-4.3)*(-14.3))+(-13.3)+(-4.3)", ((-4.3)*(-14.3)) + (-13.3) + (-4.3)},
{"(((-13.3)+(-4.3))*(+14.3))/(-9.3)/(+7.3)+(-2.3)", (((-13.3) + (-4.3))*(+14.3)) / (-9.3f) / (+7.3) + (-2.3)},
{"((-14.3)*(-14.3))+((+14.3) / (-9.3)-(+7.3) + (-2.3))", ((-14.3)*(-14.3)) + ((+14.3) / (-9.3f) - (+7.3) + (-2.3))},
{" 1 ", 1},
{" +1 ", 1},
{" -1 ", -1},
{" 1+1 ",1 + 1},
{" 1+2+ 3 ", 1 + 2 + 3},
{" 1+-1 ", 1 + -1},
{" 2*\t3 ", 2 * 3},
{" (1+2)*2 ", (1 + 2) * 2},
{" (1*2+2) ", (1 * 2 + 2)},
{" (35 + 1) * 2", (35 + 1) * 2},
{" 35 + 1 * 2 ", 35 + 1 * 2},
{" 48/2*(9+3) ", 48 / 2.0f * (9 + 3)},
{" (6/2)*(1+2) ", (6 / 2.0f)*(1 + 2)},
{" (6/(2*(1+2))) ", (6 / (2.0f * (1 + 2)))},
{" 1/2*3 ", 1 / 2.0f * 3},
{" 1+2*3 ", 1 + 2 * 3},
{" {1+2*3}+{1+2*3} ", (1 + 2 * 3) * 2},
{" {1+2*3}+{1+2*3}+(1+2*3) ", (1 + 2 * 3) * 3}
};
int i;
for (i = 0; i < countof(a); i++)
{
DEBUG_puts_double(a[i].s, a[i].f);
//DEBUG_if_err(!double_cmp(FORMULA_str_to_double(a[i].s) ,a[i].f));
DEBUG_if_err(!double_is_EQ(str_calculation_with_brace_func_variable(a[i].s), a[i].f));//변수가 없는 문자열에대해서 사칙연산 수행
}
}
DEBUG_test_cal()
{
//test1();
}
};
DEBUG_test_cal _DEBUG_test_cal;
#else
#define DEBUG_test_excel()
#endifMessageWnd.zip