📄 util.c
字号:
/*
* 2002/04/22 周国祥 增加 send_msg(), recv_msg()
*/
#include <stdio.h>
#include <termio.h>
#include <signal.h>
#include <time.h>
#include <setjmp.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <varargs.h>
#include <string.h>
int GV_y, GV_m, GV_d, GV_hh, GV_mm, GV_ss;
int GV_curdate, GV_curtime;
static FILE *GV_errfp = NULL;
static char GV_errfile[128];
static int day_tab[2][13] = {
{0,31,28,31,30,31,30,31,31,30,31,30,31},
{0,31,29,31,30,31,30,31,31,30,31,30,31}
};
/*
* 向端口(fd or sock)发送信息,保证len个子节全部送完
*/
send_msg(int fd, char *buf, int len)
{
int ret, len1;
int off;
off = 0;
len1 = len;
while (len1 > 0) {
ret = write(fd, buf + off, len1);
if (ret <= 0)
return (ret);
len1 -= ret;
off += ret;
}
return(len);
}
/*
* 向端口(fd or sock)发送信息,保证len个子节全部送完
*/
recv_msg(int fd, char *buf, int len)
{
int ret, len1;
int off;
off = 0;
len1 = len;
while (len1 > 0) {
ret = read(fd, buf + off, len1);
if (ret <= 0)
return (ret);
len1 -= ret;
off += ret;
}
return(len);
}
/*
* 将制表符转换为空格(tab_size=8或=4)
*/
zut_translate_tab(dstr, sstr, tab_size)
char *dstr, *sstr;
short tab_size;
{
int i, j;
int ii;
int start;
dstr[0] = '\0';
ii = 0;
for (i = 0; i < (int)strlen(sstr); i++) {
if (sstr[i] == '\t') {
start = ii%tab_size;
for (j = start; j < tab_size; j++) {
dstr[ii] = ' ';
ii++;
}
} else {
dstr[ii] = sstr[i];
ii++;
}
}
dstr[ii] = '\0';
}
/*
* 将字符串最后(右边)的空格符截去.
*/
char *
zut_trunc_r_space(str)
char *str;
{
int i;
for (i = (int)strlen(str)-1; i >= 0; i--) {
if (str[i] != ' ' && str[i] != '\t' && str[i] != '\0') {
str[i+1] = '\0';
return(str);
}
}
return(str);
}
zut_RTrim(s)
char *s;
{
while (s[strlen(s)-1] == ' ' || s[strlen(s)-1] == '\t')
s[strlen(s)-1] = '\0';
}
/*
* 将字符串开头(左边)的空格符截去.
*/
char *
zut_trunc_l_space(str)
char *str;
{
int i;
char *s1, *s2;
if (str == NULL)
return("\0");
s1 = str;
for (i = 0; i < (int)strlen(str); i++) {
if (*s1 != ' ' && *s1 != '\t')
break;
s1++;
}
return(s1);
}
zut_LTrim(s)
char *s;
{
while (s[0] == ' ' || s[0] == '\t')
zut_TruncChar(s, 0, 1);
}
/*
* 将字符串开头与最后(左右两边)的空格符截去.
*/
char *
zut_trunc_lr_space(str)
char *str;
{
int i;
char *s1, *s2;
if (str == NULL)
return("\0");
s1 = str;
for (i = 0; i < (int)strlen(str); i++) {
if (*s1 != ' ')
break;
s1++;
}
s2 = &str[(int)strlen(str)-1];
for (i = 0; i < (int)strlen(str); i++) {
if (*s2 != ' ')
break;
s2--;
}
*(s2+1) = '\0';
return(s1);
}
/*
* 判断字符串是否全为数字
*/
zut_is_all_digit(str)
char *str;
{
int i;
if (str == NULL)
return(0);
for (i = 0; i < (int)strlen(str); i++) {
if (str[i] < '0' || str[i] > '9')
return(0);
}
return(1);
}
/*
* 判断字符串是否为空串
*/
zut_is_null(str)
char *str;
{
if (str[0] == '\0')
return(1);
return(0);
}
/*
* 判断字符串是否为空白串(全为空格)
*/
zut_is_blank_str(str)
char *str;
{
int i;
if (str == NULL)
return(1);
for (i = 0; i < (int)strlen(str); i++) {
if (str[i] != ' ')
return(0);
}
return(1);
}
zut_curdate()
{
zut_get_ymdhms(&GV_y, &GV_m, &GV_d, &GV_hh, &GV_mm, &GV_ss);
GV_curdate = GV_y * 10000 + GV_m * 100 + GV_d;
GV_curtime = GV_hh * 10000 + GV_mm * 100 + GV_ss;
}
/*
* 获取系统当日日期, y, m, d分别存放年, 月, 日
* 返回值: 格式为YYYYMMDD的日期
*/
zut_get_ymd(y, m, d)
int *y, *m, *d;
{
struct tm *h, *localtime();
long p;
int year, i, yday, leap;
p = time(0);
h = localtime(&p);
year = 1900 + h->tm_year;
yday = h->tm_yday + 1;
*y = year;
leap = (year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0);
for (i = 1; yday > day_tab[leap][i]; i++)
yday -= day_tab[leap][i];
*m = i;
*d = yday;
return((year) * 10000 + (i) * 100 + (yday));
}
/*
* 获取系统当日日期时间
* y, m, d分别存放年, 月, 日
* hh, mm, ss分别存放时, 分, 秒
* 返回值: 格式为YYYYMMDD的日期
*/
zut_get_ymdhms(y, m, d, hh, mm, ss)
int *y, *m, *d;
int *hh, *mm, *ss;
{
struct tm *h, *localtime();
long p;
int year, i, yday, leap;
p = time(0);
h = localtime(&p);
year = 1900 + h->tm_year;
yday = h->tm_yday + 1;
*hh = h->tm_hour;
*mm = h->tm_min;
*ss = h->tm_sec;
*y = year;
leap = (year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0);
for (i = 1; yday > day_tab[leap][i]; i++)
yday -= day_tab[leap][i];
*m = i;
*d = yday;
return((year) * 10000 + (i) * 100 + (yday));
}
/*
* 计算两个日期之间的天数.
* 若date1>date2, 则为负数;
* 否则, 为正.
*/
zut_have_days(date1, date2)
int date1, date2;
{
char flag;
int yy, mm, dd;
int mon1, mon2;
int days = 0;
int i, leap = 0;
int year;
if (date1 > date2) {
yy = date2;
date2 = date1;
date1 = yy;
flag = 1;
} else
flag = 0;
#ifdef zgx97
zut_get_ymd(&yy, &mm, &dd);
mon1 = yy/100*10000 + date1/100; /* 9605 => 199605 */
mon2 = yy/100*10000 + date2/100;
#endif
mon1 = date1/100;
mon2 = date2/100;
for (i = mon1; i < mon2; ) {
year = i / 100; /* 199605=>1996 */
leap = (year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0);
days += day_tab[leap][i%100];
if (i % 100 == 12)
i = (i/100+1)*100+1;
else
i++;
}
days += date2%100-date1%100;
if (flag)
return(-days);
return(days);
}
/*
* 计算date2距date1的年数
* date2比date1小则非法, 返回-1
* 不满一年返回0, 不满两年返回1...
*/
zut_have_years(date1, date2)
{
int y1, m1, d1;
int y2, m2, d2;
y1 = date1/10000;
m1 = date1%10000/100;
d1 = date1%10000%100;
y2 = date2/10000;
m2 = date2%10000/100;
d2 = date2%10000%100;
if (date2-date1 < 0)
return(-1);
if (y1 == y2)
return(0);
if (m2 < m1)
return(y2-y1-1);
if (m2 == m1) {
if (d2 < d1)
return(y2-y1-1);
return(y2-y1);
}
return(y2-y1);
}
/*
* 计算昨天日期
*/
zut_yestoday(date)
int date;
{
int yy, mm, dd;
int leap = 0;
yy = date / 10000;
mm = date % 10000 / 100;
dd = date % 10000 % 100;
if (dd == 1) {
if (mm == 1) {
mm = 12;
yy--;
dd = 31;
} else {
leap = (yy % 4 == 0) && (yy % 100 != 0) || (yy % 400 == 0);
mm--;
dd = day_tab[leap][mm];
}
} else
dd--;
return(yy*10000+mm*100+dd);
}
/*
* 检查日期合法性, cnt1为前几年, cnt2为后几年.
* 若cury为-1, 则不判断年份的合法性.
* 否则, 判断年份y是否在cury的前后几年之间.
*/
zut_check_date(y, m, d, cury, cnt1, cnt2)
{
if (cury != -1)
if (y < cury-cnt1 || y > cury + cnt2)
return(-1);
if (m < 1 || m > 12)
return(-2);
if (m == 1 || m == 3 || m == 5 || m == 7 || m == 8 || m == 10 || m == 12) {
if (d < 1 || d > 31)
return(-6);
return(0);
} else if (m == 4 || m == 6 || m == 9 || m == 11) {
if (d < 1 || d > 30)
return(-5);
return(0);
} else { /* m == 2 */
if ((y % 4 == 0) && (y % 100 != 0) || (y % 400 == 0)) {
if (d < 1 || d > 29)
return(-3);
return(0);
} else {
if (d < 1 || d > 28)
return(-4);
return(0);
}
}
}
/*
* 计算字符串中有几组以某分隔符(sepchar)分隔的串
*/
zut_get_seperate(buf, sepchar)
char *buf;
char sepchar;
{
int num;
int i;
if (sepchar == '\0')
sepchar = ';';
num = i = 0;
while (1) {
if (buf[i] == '\0') {
if (i == 0) /* 若为空串,则num=0 */
break;
/* 若不是以分隔符结尾,则num+1 */
if (buf[i-1] != sepchar)
num++;
break;
}
if (buf[i] == sepchar)
num++;
i++;
}
return num;
}
/*
* 根据序号(ord)从字符串中获取某个以分隔符(sepchar)分隔的子串
* 所获取的子串放入substr中传给调用者
*/
zut_get_fld(buf, ord, substr, sepchar)
char *buf;
int ord;
char *substr;
char sepchar;
{
int i, cnt, order;
if (sepchar == '\0')
sepchar = ';';
cnt = 0;
order = 0;
for (i = 0; i < (int)strlen(buf); i++) {
if (buf[i] == sepchar) {
substr[cnt] = '\0';
if (order == ord) {
return(0);
}
cnt = 0;
order++;
continue;
}
substr[cnt++] = buf[i];
}
substr[cnt] = '\0';
if (order == ord) {
return(0);
}
substr[0] = '\0';
return(-1);
}
/*
* 在字符串s中查找字符c, 返回第一次c出现的位置或-1(未找到)
* 与strchr()类似, 但strchr返回指针
*/
zut_FindChar(s, c)
char *s;
char c;
{
int j, i;
i = strlen(s);
for(j = 0; j < i; j++) {
if (s[j] == c)
return(j);
}
return(-1);
}
/*
* 从字串str的某位置(pos)起截掉len个字符
* 若字串中从pos起无len个字符, 则返-1, 串不变
* 否则返0
*/
zut_TruncChar(str, pos, len)
char *str;
int pos, len;
{
int i, k;
if ((pos+len-1) > strlen(str))
return(-1);
k = strlen(str) - len;
for (i = pos; i <= k; i++) {
str[i] = str[i+len];
}
str[k] = '\0';
return(0);
}
/*
* 将字串str中的字符ch1换成ch2
*/
zut_UpdateChar(str, ch1, ch2)
char *str;
char ch1, ch2;
{
int i, k;
for (i = 0; i <= (int)strlen(str); i++) {
if (str[i] == ch1)
str[i] = ch2;
}
return(0);
}
char unit[15][3] = {
{"元"}, {"拾"}, {"佰"}, {"仟"},
{"万"}, {"拾"}, {"佰"}, {"仟"},
{"亿"}, {"拾"}, {"佰"}, {"仟"}
};
/*
* 将double型金额值转换为大写表示的字串
*/
char *
upper_str(fee)
double fee;
{
char str[128];
char str1[128];
char ustr[128];
int i, len, len1;
char *cupper();
char zero = 0;
if (fee < 0.00) {
sprintf(ustr, "负");
sprintf(str1, "%.2f", -fee);
} else {
ustr[0] = '\0';
sprintf(str1, "%.2f", fee);
}
len = (int)strlen(str1);
for (i = 0; i < len; i++) {
str[i] = str1[len-i-1];
}
str[len] = '\0';
if (strcmp(str, "00.0") == 0)
return("零元整");
len1 = len - 3; /* XXXXXX.XX len1 为小数点前位数 */
strcpy(str1, &str[3]);
for (i = len1-1; i >= 0; i--) {
if (str1[i] == '0') {
zero = 1;
if (i == 0 && len1 == 1) /* 0.XX */
break;
if (i == 0 || i == 4 || i == 8) {
strcat(ustr, unit[i]);
zero = 0;
}
} else {
if (zero)
strcat(ustr, "零");
zero = 0;
strcat(ustr, cupper(str1[i]));
strcat(ustr, unit[i]);
}
}
if (str[0] == '0') {
if (str[1] != '0') {
strcat(ustr, cupper(str[1]));
strcat(ustr, "角");
}
} else {
if (str[1] != '0') {
strcat(ustr, cupper(str[1]));
strcat(ustr, "角");
strcat(ustr, cupper(str[0]));
strcat(ustr, "分");
} else {
if (len1 == 1 && str1[0] == '0') {
strcat(ustr, cupper(str[0]));
strcat(ustr, "分");
} else {
strcat(ustr, "零");
strcat(ustr, cupper(str[0]));
strcat(ustr, "分");
}
}
}
strcat(ustr, "整");
return(ustr);
}
char *
cupper(c)
char c;
{
switch(c) {
case '0':
return("零");
case '1':
return("壹");
case '2':
return("贰");
case '3':
return("叁");
case '4':
return("肆");
case '5':
return("伍");
case '6':
return("陆");
case '7':
return("柒");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -