0
点赞
收藏
分享

微信扫一扫

冷门库

@[TOC]

标准库

一. 冷门的库

  1. 与小数精度有关的<float.h>
  2. 与数据的大小范围限制有关 <limits.h>
  3. 与国家的地域属性有关的配置<locale.h>
  4. 关于jmp条转的库<setjmp.h>
  5. 关于信号处理 <signal.h>
  6. 定义一些结果运算后的变量或者类型<stddef.h>

二. 实用的标准库

(一). <assert.h> 信息诊断

assert(条件判断)

函数没有返回值,可能会引起程序退出

#include <assert.h>
#include <stdio.h>

int main()
{
int a;
printf("请输入一个整数值: ");
scanf("%d", &a);
assert(a >= 10);
printf("输入的整数是: %d\n", a);

return(0);
}

如果你的输入>=10,程序正常执行

如果你的输入<10,程序中断退出

(二). <errno.h>报错反馈

1.stderr(errno) 找不到文件

extern int errno

这里只能用​​errno​​,用其它的变量名称都不可以

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

extern int errno;

int main ()
{
FILE *file_ptr;

file_ptr = fopen("file.txt", "r");
if( file_ptr == NULL )
{

fprintf(stderr, "错误类型编号: %d\n", errno);
fprintf(stderr, "发生了什么错误: %s\n", strerror(errno));
}
else
{
fclose(file_ptr);
}

return(0);
}

2. EDOM 超出数学定义域

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LTj41M7g-1645462567059)(C%E5%BA%93.assets/image-20220220223247653.png)]

value = sqrt(-10);

我们知道,负数是不能开方的,所以不在规定的数学定义域内

#include <stdio.h>
#include <errno.h>
#include <math.h>

int main()
{
double value;

errno = 0;
value = sqrt(-10);
if(errno == EDOM)
{
printf("错误类型编号: %d\n", errno);
printf("错误类型编号: %d\n", EDOM);
printf("发生了什么错误:超出数学函数定义的域 \n ");

}
else
{
printf("在数学函数定义的域\n");
}

return(0);
}

3. ERANGE 不在数学函数域

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3SqFjeTv-1645462567061)(C%E5%BA%93.assets/image-20220220224116147.png)]

log()的范围是[-∞,+∞]

当结果是∞的时候,就会这样报错

#include <stdio.h>
#include <errno.h>
#include <math.h>

int main()
{
double x;
double value;


x = 0.000000;
value = log(x);

if( errno == ERANGE )
{
printf("错误类型 %d\n",errno);
printf("Log(%f) is too large\n", x);
}
else
{
printf("Log(%f) = %f\n", x, value);
}


return 0;
}

(三). <stdarg.h>可变参数

#include <stdarg.h>
#include <stdio.h>

int add(int, ...);

int main()
{
printf("和 = %d\n", add(2, 20, 30) );
return 0;
}

int add(int how_many_args, ...)
//how_many_args 固定的参数,代表了参数的个数,
{
int sum = 0;
va_list book_list;
int i;

va_start(book_list, how_many_args);
for(i = 0; i < how_many_args; i++)
{
sum += va_arg(book_list, int);
//(int) va_arg(book_list, int);返回一个int的类型
//va_arg(book_list, int); 根据int的数据长度去遍历ags
}
va_end(book_list);

return sum;
}

上面中

1. va_list book_list

book_list用于了va_start()、va_arg()va_end()

2. va_start(book_list, how_many_args);

在参数,参数个数的条件下,借​​va_start​​初始化了book_list

用于后面参数的遍历

3. va_arg(book_list, int);

返回int型

遍历也是4字节4字节的遍历

4. va_end(book_list);

结束这个book_list

如果没有end,连start都无法开始

(四). <stdio.h>标准库

1. vfprintf() 多此一举的fprintf

#include <stdio.h>
#include <stdarg.h>
//这里用到了可变参数
//翻看网上的教程,发现他们基本上都用可变参数
void WriteFrmtd(FILE *stream, char *format, ...)
{
va_list args;

va_start(args, format);
vfprintf(stream, format, args);
va_end(args);
}

int main ()
{
FILE *fp;

fp = fopen("d:/file.txt","w+");

WriteFrmtd(fp, "This is just one argument %d %s\n", 10,"dqx");

fclose(fp);

return(0);
}

2. vprintf 多此一举的printf

用vprintf实现printf,多此一举

#include<stdio.h>
//#include<stdlib.h>
#include<stdarg.h>//ANSI C可变参数的头文件

int print(char* format, ...) {
va_list ap;
int n;
va_start(ap, format);
n = vprintf(format, ap);
va_end(ap);
return 0;
}

int main() {
int ch1 = 10, ch2 = 20;
print("%d\t%d\n", ch1, ch2);
return 0;
}

3. vsprintf 多此一举的sprintf

#include <stdio.h>
#include <stdarg.h>

char buffer[80];
int func(char *format, ...)
{
va_list aptr;
int ret;

va_start(aptr, format);
ret = vsprintf(buffer, format, aptr);
va_end(aptr);

return(ret);
}

int main()
{
int i = 5;
float f = 27.0;
char str[50] = "runoob.com";

func("%d %f %s", i, f, str);
printf("%s\n", buffer);

return(0);
}

#include <stdarg.h>
#include <stdio.h>

int add(int, ...);

int main()
{
printf("和 = %d\n", add(2, 20, 30) );
return 0;
}

int add(int how_many_args, ...)
//how_many_args 固定的参数,代表了参数的个数,
{
int sum = 0;
va_list book_list;
int i;

va_start(book_list, how_many_args);
for(i = 0; i < how_many_args; i++)
{
sum += va_arg(book_list, int);
//(int) va_arg(book_list, int);返回一个int的类型
//va_arg(book_list, int); 根据int的数据长度去遍历ags
}
va_end(book_list);

return sum;
}

8. abort() 异常中断退出

C 库函数 void abort(void) 中止程序执行,直接从调用的地方跳出。

9. atexit()

函数发生问题退出的时候调用的函数

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

void functionA ()
{
printf("这是函数A\n");
}

int main ()
{


atexit(functionA );

return(0);
}

(六). <time.h>时间库

协调世界时 UTC:1970-01-01 00:00:00 下面的绝大多数的时间都是与它做减法

库变量 下面是头文件 time.h 中定义的变量类型:



size_t

是无符号整数类型,它是 sizeof 关键字的结果。

clock_t

这是一个适合存储处理器时间的类型。

time_t is

这是一个适合存储日历时间类型。是long的类型

struct tm

这是一个用来保存时间和日期的结构。

-

--



struct tm 结构体

tm 结构的定义如下:

struct tm {
int tm_sec; /* 秒,范围从 0 到 59 */
int tm_min; /* 分,范围从 0 到 59 */
int tm_hour; /* 小时,范围从 0 到 23 */
int tm_mday; /* 一月中的第几天,范围从 1 到 31 */
int tm_mon; /* 月,范围从 0 到 11 */
int tm_year; /* 自 1900 年起的年数 */
int tm_wday; /* 一周中的第几天,范围从 0 到 6 */
int tm_yday; /* 一年中的第几天,范围从 0 到 365 */
int tm_isdst; /* 夏令时 */
};

关于那写数据转化为字符串怎么输出

说明符

替换为

实例

%a

缩写的星期几名称

Sun

%A

完整的星期几名称

Sunday

%b

缩写的月份名称

Mar

%B

完整的月份名称

March

%c

日期和时间表示法

Sun Aug 19 02:56:02 2012

%d

一月中的第几天(01-31)

19

%H

24 小时格式的小时(00-23)

14

%I

12 小时格式的小时(01-12)

05

%j

一年中的第几天(001-366)

231

%m

十进制数表示的月份(01-12)

08

%M

分(00-59)

55

%p

AM 或 PM 名称

PM

%S

秒(00-61)

02

%U

一年中的第几周,以第一个星期日作为第一周的第一天(00-53)

33

%w

十进制数表示的星期几,星期日表示为 0(0-6)

4

%W

一年中的第几周,以第一个星期一作为第一周的第一天(00-53)

34

%x

日期表示法

08/19/12

%X

时间表示法

02:50:06

%y

年份,最后两个数字(00-99)

01

%Y

年份

2012

%Z

时区的名称或缩写

CDT

%%

一个 % 符号

%

asctime() 返回一个tm类型的字符串,,代表了tm的结构

char *asctime(const struct tm *timeptr)

参数 是

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

int main()
{
struct tm t;

t.tm_sec = 10;
t.tm_min = 12;
t.tm_hour = 3;
t.tm_mday = 23;
t.tm_mon = 2;
t.tm_year = 22;
t.tm_wday = 6;

puts(asctime(&t));

return(0);
}

输出

Sat Mar 23 03:12:10 1922

clock() 返回处理器时钟所使用的时间。

clock_t clock(void)

处理器时钟所使用的时间

CLOCKS_PER_SEC 可能是一个单位,就像

sizeof(arr)/sizeof(int) ​​CLOCKS_PER_SEC​​​好比​​/sizeof(int)​

#include <time.h>
#include <stdio.h>

int main()
{
clock_t start, end;
double total;
int i;

start = clock();
printf("程序启动,start = %ld\n", start);

printf("开始一个大循环,start = %ld\n", start);
for(i=0; i< 10000000; i++)
{
}
end = clock();
printf("大循环结束,end_t = %ld\n", end);

total = (double)(end - start) / CLOCKS_PER_SEC;
printf("CPU 占用的总时间:%f\n", total );
printf("程序退出...\n");

return(0);
}

time()

time_t time(time_t *seconds)

以 time_t 对象返回当前时间自纪元 Epoch(1970-01-01 00:00:00 UTC)起经过的秒数

#include <stdio.h>
#include <time.h>

int main ()
{
time_t seconds;

seconds = time(NULL);
printf("自 1970-01-01 起的小时数 = %ld\n", seconds/3600);

return(0);
}

输出

自 1970-01-01 起的小时数 = 457105

ctime()

char *ctime(const time_t *timer)

返回一个表示当地时间的字符串

#include <stdio.h>
#include <time.h>

int main ()
{
time_t curtime;

time(&curtime);

printf("当前时间 = %s", ctime(&curtime));

return(0);
}

difftime() 返回2个时间的差

double difftime(time_t time1, time_t time2)

参数1,参数2是两个time_t类型的时间 用dounle返回两个时间之间相差的秒数 (time1 - time2)。

#include <stdio.h>
#include <time.h>
#include <Windows.h>



int main ()
{
time_t start_t, end_t;
double diff_t;


//把时间给start_t
time(&start_t);

Sleep(1000);
//这里是毫秒,1000毫秒=1秒
//Sleep必须大写,否者编译器不认识


//把时间给end_t
time(&end_t);

diff_t = difftime(end_t, start_t);

printf("执行时间 = %lf\n", diff_t);


return(0);
}

输出

执行时间 = 1.000000

gmtime() 将time_t转化为tm

#include <stdio.h>
#include <time.h>

//时区的初始化
#define BST (+1)
#define CCT (+8)

int main ()
{

time_t init_time;

//定义了一个结构体指针
struct tm *ptr;

//初始化rawtime
time(&init_time);


/* 获取 GMT 时间 */
//把time_t类型转化为tm类型,并返回一个结构体指针
ptr = gmtime(&init_time );

printf("当前的世界时钟:\n");
printf("伦敦:%2d:%02d\n", (ptr->tm_hour+BST)%24, ptr->tm_min);
printf("中国:%2d:%02d\n", (ptr->tm_hour+CCT)%24, ptr->tm_min);

return(0);
}

localtime

struct tm *localtime(const time_t *timer)

localtime() 将参数 timer所指的 time_t 结构中的信息转换成真实世界所使用的时间日期表示方法,然后返回结构体指针

#include <stdio.h>
#include <time.h>

int main ()
{
time_t init_time;
struct tm *output;

time( &init_time );

output = localtime( &init_time );
printf("当前的本地时间和日期:%s", asctime(output));

return(0);
}

mktime()

time_t mktime(struct tm *timeptr)

参数是一个时间结构体指针

函数返回自 1970 年 1 月 1 日以来持续时间的秒数。如果发生错误,则返回 -1 值

#include <stdio.h>
#include <time.h>

int main () {
int ret;
struct tm info;
char buffer[80];
//1970-01-01 00:00:00
info.tm_year = 2021 - 1900;
info.tm_mon = 7-1;
info.tm_mday = 4-0;
info.tm_hour = 0-0;
info.tm_min = 0-0;
info.tm_sec = 1-0;
info.tm_isdst = -1;/* 夏令时 */

ret = mktime(&info);
if( ret == -1 )
{
printf("Error: unable to make time using mktime\n");
}
else
{
strftime(buffer, sizeof(buffer), "%c", &info );
printf(buffer);
}

return(0);
}

输出

另外一个代码

/* 输入日期判断是周几 */
#include <stdio.h> /* printf, scanf */
#include <time.h> /* time_t, struct tm, time, mktime */

int main ()
{
time_t init_time;
struct tm * time_struct_ptr;
int year, month ,day;

const char * weekday_arr[] = { "周日", "周一","周二", "周三","周四", "周五", "周六"};

/* 用户输入日期 */
printf ("年: ");
//fflush(stdout);
scanf ("%d",&year);

printf ("月: ");
//fflush(stdout);
scanf ("%d",&month);

printf ("日: ");
//fflush(stdout);
scanf ("%d",&day);

/* 获取当前时间信息,并修改用户输入的输入信息 */
time ( &init_time );

time_struct_ptr = localtime ( &init_time );
time_struct_ptr->tm_year = year - 1900;
time_struct_ptr->tm_mon = month - 1;
time_struct_ptr->tm_mday = day;

/* 调用 mktime: time_struct_ptr->tm_wday */
mktime ( time_struct_ptr );


printf ("那一天是:%s\n", weekday_arr[time_struct_ptr->tm_wday]);

return 0;
}

输入2001.09.27 输出

年: 2001
月: 9
日: 27
那一天是:周四

strftime 将时间写入字符串

size_t strftime(char *str, size_t maxsize, const char *format, const struct tm *timeptr)

参数1:接收时间字符串的数组 参数2: 这是被复制到 str 的最大字符数 参数3: 格式化写入 参数4:时间结构体 函数返回 如果产生的 C 字符串小于 size 个字符(包括空结束字符),则会返回复制到 str 中的字符总数(不包括空结束字符),否则返回零,没有字符串写入到数组

#include <stdio.h>
#include <time.h>

int main ()
{
time_t rawtime;
struct tm *info;
char buffer[80];

time( &rawtime );

info = localtime( &rawtime );

strftime(buffer, 50, "%Y-%m-%d %H:%M:%S", info);
printf("格式化的日期 & 时间 : |%s|\n", buffer );

return(0);
}

输出

格式化的日期 & 时间 : |2022-02-23 09:15:27|

举报

相关推荐

0 条评论