第十五章 输入/输出函数
错误报告
perror void perror (char const *message)//打印错误信息
终止执行
exit void exit(int status)//在stdlib.h中定义 常见的预定义符号: EXIT_SUCCESS 和 EXIT_FAILURE
ANSI I/O 概念
-
流
绝大多数流是完全缓冲的,从缓冲区来回读写,缓冲区只有写满的时候才会被输出。 如果想printf()之后立即输出则用fflush();
-
文本流
在MS-DOS系统中,文本文件约定以一个回车符和一个换行符结尾 在UNIX中,只用一个换行符结尾
-
二进制流
不会改变文件的内容
-
-
文件
FILE结构,每个ANSI C 程序运行时候会有三个流: stdin stdout stderr
-
标准IO常量
一个程序能打开多少个文件,和编译器有关,FOPEN_MAX个文件。
流IO总览
声明指针变量FILE* fopen 初始化 FILE 读取或者写入 fclose 关闭流
-
执行字符、文本行、二进制IO函数
字符: gerchar putchar 读取(写入)单个字符 文本行: gets scanf puts printf 文本行未格式化和格式化输入输出 二进制数据:fread fwrite 读取(写入)二进制数据
打开流
FILE *fopen(char const *name,char const *mode) 参数二: r 读取 w 写入 a 追加 a+ 允许读和写操作
FILE* file1;
file1 = fopen("123.txt", "w");
if (file1 == NULL)
{
perror("data3");
exit(EXIT_FAILURE);
}
fclose(file1);
FILE* file2;
file2 = freopen("123.txt", "w", file1);
if (file2 == NULL)
{
perror("data4");
exit(EXIT_FAILURE);
}
关闭流
int fclose(FILE *f) 执行成功返回零值,否则返回EOF
字符IO
int fgetc(FILE *stream); int getc(FILE *stream); int getchar(void); 如果流不存在更多的字符,则返回EOF(int类型) int fputc(int ,FILE *stream); int putc(int ,FILE *stream); int putchar(int character); 写入失败也会EOF
撤销字符IO
int ungetc(int character,FILE *stream)
while((ch = getchar())!=EOF && isdigit(ch)){
value *= 10;
value += ch - '0';
}
ungetc(ch,stdin);//将最后一次读取的非字符退还给stdin
未格式化的行IO
原型: char *fgets(char *buffer,int size,FILE *stream)//NUL添加到尾部 读取完毕则返回NULL 否则返回第一个参数 char *gets(char *buffer);
int fputs(char const *buffer,FILE *stream)//如果不包含换行符则不会自己添加换行符 int puts (char const *buffer)
格式化的行IO
-
scanf家族
int fscanf(FILE *stream,char const *format,...) int scanf(char const *format,...) int sscanf(char const *string,char const *format,...); fscanf 从流中读取 scanf 从stdin读取 sscanf 从参数1读取
-
限定符
d、i、n:"h"short,"l"long o、u、x:"h"unsigned short,"l" unsigned long e、f、g:"l"double,"L"long double
-
格式码
-
-
printf家族
int fprintf(FILE *stream,char const *format,...); int printf(char const *format,...); int sprintf(char *buffer,char const *format,...);//输入到buffer中
-
二进制IO
size_t fread (void *buffer,size_t size,size_t count ,FILE *stream) size_t fwrite(void *buffer,size_t size,size_t count ,FILE *stream) 可以避免在转换时候出现精度损失
-
刷新和定位函数
int fflush (FILE *stream)//刷新流 long ftell(FILE *stream)//返回当前位置 int fseek(FILE *stream,long offset,int from)//定位位置 参数3:SEEK_SET SEEK_CUR SEEK_END
void rewind(FILE *stream) 将读写指针回到初始位置 int fgetpos(FILE *stream,fpos_t *position) 此函数的position参数保存了当前stream的位置 int fsetpos(FILE *stream,fpos_t const *position) 此函数的position参数设置stream位置
-
改变缓冲方式
可以用于对缓冲方式进行修改,只有当指定的流被打开且没有执行任何操作前设置。 void setbuf(FILE *stream,char *buf); int setvbuf(FILE *stream,char *buf,int mode,size_t size); 最好不要使用自动数组,使用malloc,使用BUFSIZ大小或者整数倍 参数三: _IOFBF 完全缓冲流 _IONBF不缓冲流 _IOLBF行缓冲流
-
流错误函数
int feof(FILE *stream)//流处于结尾的时候返回真 int ferror(FILE *stream)//写入错误的时候返回真 void clearerr(FILE *stream)//对指定流的错误标志进行重置
-
临时文件
FILE *rmpfile(void) 以wb+的方式创建一个文件,并且关闭程序时候删除该文件 char *tmpnam(char *name) 如果参数为NULL则返回静态数组的指针说明被创建的文件名
-
文件操作函数
int remove(char const *filename) int rename(char const *oldname,char const *newname) 两个函数都是,成功返回0,失败返回非零值
第十六章 标准函数库
整型函数
-
算数<stdlib.h>
-
int abs (int value)
返回绝对值
-
long labs (long value)
返回绝对值,针对长整型
-
div_t div(int numbertor,int denominator)
参数1是分子,参数2是分母,返回商和余数 div_t->int quot //商 div_t->int rem//余数
-
ldiv_t ldiv(long numbertor,long denominator)
-
-
随机数<stdlib.h>
int rand(void); void srand(unsigned int sedd); 一般先srand,重置随机数,然后调用rand srand((unsigned int )time(NULL))//需要添加 time.h
-
字符串转换<stdlib.h>
-
int atoi(char const *string)
int a = atoi(" 1f22");//此时的a 值是1
-
long int atol(char const *string)
-
long int strtol(char const *string,char **unused,int base)
参数1 -- 要转换为长整数的字符串。 参数2 -- 对类型为 char* 的对象的引用,其值由函数设置为 参数1 中数值后的下一个字符。 参数3 -- 基数,必须介于 2 和 36(包含)之间,或者是特殊值 0。如果设置为12则有效数字为0-C
-
unsigned long int strtoul
-
浮点型函数
-
三角函数
- double sin(double angle)
- double cos(double angle)
- double tan(double angle)
- double asin(double angle)
- double acos(double angle)
- double atan(double angle)
- double atan2(double x,double y)
-
双曲函数
- double sinh(double angle)
- double cosh(double angle)
- double tanh(double angle)
-
对数和指数函数
- double exp(double x)
- double log(double x)
- double log10(double x)
-
浮点表示形式
-
double frexp(double value,int *exponent)
-
double ldexp(double fractione ,int exponent)
-
double modf(double value,double *ipart)
浮点数的整数部分和小数部分分离: 整数部分存储在第二个参数中 小数直接返回
-
-
幂
- double pow(double x,double y)
- double sqrt(double x)
-
底数,顶数,绝对值和余数
-
double floor(double x)
-
double ceil(double x)
-
double fabs(double x)
-
double fmod(double x, double y)
x/y所得到的余数
-
-
字符串转换
- double atof(char const*string)
- double strtod(char const *string,char **unused)
日期和时间函数
-
处理器时间
-
clock_t clock(void)
CLOCKS_PER_SEC 返回值除上面的宏才能得出秒
-
-
当天时间
-
time_t time(time_t *returned_value)
不能用来计算秒数
-
-
日期和时间转换
-
char *ctime(time_t const *time_value)
得到的字符串格式: Sun Jul 4 04:02:48 1976\n\0
也可以用: asctime (localtime( time_t time_value))来实现
-
double difftime(time_t timel,time_t time2)
计算两个时间的时间差,结果是秒
-
struct tm *gmtime(time_t const *time_value);
-
struct tm *localtime(time_t const *time_value);
-
struct tm
int tm_sec; // seconds after the minute - [0, 60] including leap second int tm_min; // minutes after the hour - [0, 59] int tm_hour; // hours since midnight - [0, 23] int tm_mday; // day of the month - [1, 31] int tm_mon; // months since January - [0, 11] int tm_year; // years since 1900 int tm_wday; // days since Sunday - [0, 6] int tm_yday; // days since January 1 - [0, 365] int tm_isdst; // daylight savings time flag
-
char *asctime(struct tm const *tm_ptr)
-
size_t strftime(char *string,size_t maxsize,char const *format,struct tm const *tm_ptr)
-
time_t mktime(struct tm *tm_ptr)
把tm转换成 time_t
-
非本地跳转<setjmp.h>
setjmp和longjmp函数提供了类似goto语句,但是不局限于函数。常用于深层嵌套的函数调用链。
setjmp(restart);然后别处的 longjmp(restart,value);此时回去之后,在setjmp()会接收到value去判断运行哪个操作
- int setjmp(jmp_buf state)
- void longjmp(jmp_buf state,int value)
信号
SIGABRT 程序异常终止。 SIGFPE 算术运算出错,如除数为 0 或溢出。 SIGILL 非法函数映象,如非法指令。 SIGINT 中断信号,如 ctrl-C。 SIGSEGV 非法访问存储器,如访问不存在的内存单元。 SIGTERM 发送给本程序的终止请求信号。
-
int raise(int sig)
信号发生器,发生sig信号 程序默认执行动作 程序忽略 程序执行自定义的动作
-
void (*signal(int sig, void (*func)(int)))(int)
先省略返回类型 signal(int sig,void (* handler)(int)) 参数1是信号值 参数2是回调函数
现在省略参数 void (*signal())(int)
-
案例
int main() { signal(SIGINT, sighandler);
while(1) { printf("开始休眠一秒钟...\n"); sleep(1); }
return(0); }
void sighandler(int signum) { printf("捕获信号 %d,跳出...\n", signum); exit(1); }
打印可变参数列表<stdarg.h>
- int vprintf(char const *format,va_list arg)
- int vfprintf(FILE *stream,char const *format,va_list arg);
- int vsprintf(char *buffer,char const *format,va_list arg);
执行环境
-
终止执行
-
void abort(void)
触发 SIGABRT 信号 可以忽略此信号
-
void atexit(void (func)(void))
将一些函数注册为退出函数,执行exit()或者return的时候会执行此函数作为收尾
-
void exit(int status)
-
-
断言
-
void assert(int expression)
assert(value != NULL)//如果为假则会输出错误信息 Assertion failed :value != NULL,file.c line 274
#define NDEBUG 此宏可以忽略所有断言判断
-
-
环境
-
char *getenv(char const *name)
查找编译器定义的名字/值
-
-
执行系统命令
- void system(char const *command);
-
排序和查找
-
void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void , const void))
base -- 指向要排序的数组的第一个元素的指针。 nitems -- 由 base 指向的数组中元素的个数。 size -- 数组中每个元素的大小,以字节为单位。 compar -- 用来比较两个元素的函数。
-
void *bsearch(const void *key, const void *base, size_t nitems, size_t size, int (*compar)(const void *, const void *))
key -- 指向要查找的元素的指针,类型转换为 void*。 base -- 指向进行查找的数组的第一个对象的指针,类型转换为 void*。 nitems -- base 所指向的数组中元素的个数。 size -- 数组中每个元素的大小,以字节为单位。 compar -- 用来比较两个元素的函数。 返回找到元素的void *类型的地址
-
locale
LC_ALL 设置下面的所有选项。 LC_COLLATE 影响 strcoll 和 strxfrm 函数。 LC_CTYPE 影响所有字符函数。 LC_MONETARY 影响 localeconv 函数提供的货币信息。 LC_NUMERIC 影响 localeconv 函数提供的小数点格式化和信息。 LC_TIME 影响 strftime 函数。
-
数值和货币格式
-
struct lconv *localeconv(void)
数值和货币的书写格式每个地方都不同,
-
-
lconv
- decimal_point 用于非货币值的小数点字符。
- thousands_sep 用于非货币值的千位分隔符。
- grouping 一个表示非货币量中每组数字大小的字符串。每个字符代表一个整数值,每个整数指定当前组的位数。值为 0 意味着前一个值将应用于剩余的分组。
- int_curr_symbol 国际货币符号使用的字符串。前三个字符是由 ISO 4217:1987 指定的,第四个字符用于分隔货币符号和货币量。
- currency_symbol 用于货币的本地符号。
- mon_decimal_point 用于货币值的小数点字符。 mon_thousands_sep 用于货币值的千位分隔符。
- mon_grouping 一个表示货币值中每组数字大小的字符串。每个字符代表一个整数值,每个整数指定当前组的位数。值为 0 意味着前一个值将应用于剩余的分组。
- positive_sign 用于正货币值的字符。
- negative_sign 用于负货币值的字符。
- int_frac_digits 国际货币值中小数点后要显示的位数。
- frac_digits 货币值中小数点后要显示的位数。
- p_cs_precedes 如果等于 1,则 currency_symbol 出现在正货币值之前。如果等于 0,则 currency_symbol 出现在正货币值之后。
- p_sep_by_space 如果等于 1,则 currency_symbol 和正货币值之间使用空格分隔。如果等于 0,则 currency_symbol 和正货币值之间不使用空格分隔。
- n_cs_precedes 如果等于 1,则 currency_symbol 出现在负货币值之前。如果等于 0,则 currency_symbol 出现在负货币值之后。
- n_sep_by_space 如果等于 1,则 currency_symbol 和负货币值之间使用空格分隔。如果等于 0,则 currency_symbol 和负货币值之间不使用空格分隔。
- p_sign_posn 表示正货币值中正号的位置。
- n_sign_posn 表示负货币值中负号的位置。
p_sign_posn 和 n_sign_posn:值描述
- 0 | 封装值和 currency_symbol 的括号。
- 1 | 放置在值和 currency_symbol 之前的符号。
- 2 | 放置在值和 currency_symbol 之后的符号。
- 3 | 紧挨着放置在值和 currency_symbol 之前的符号。
- 4 | 紧挨着放置在值和 currency_symbol 之后的符号。
-
char *setlocale(int category, const char *locale)
-
category -- 这是一个已命名的常量,指定了受区域设置影响的函数类别。
-
LC_ALL 包括下面的所有选项。
-
LC_COLLATE 字符串比较。参见 strcoll()。//和strcmp有点类似
-
LC_CTYPE 字符分类和转换。例如 strtoupper()。
-
LC_MONETARY 货币格式,针对 localeconv()。
-
LC_NUMERIC 小数点分隔符,针对 localeconv()。
-
LC_TIME 日期和时间格式,针对 strftime()。
-
LC_MESSAGES 系统响应。
-
locale -- 如果 locale 是 NULL 或空字符串 "",则区域名称将根据环境变量值来设置,其名称与上述的类别名称相同。
-
第十七章 经典抽象数据类型
内存分配
- 静态数组
- 动态分配的数组
- 动态分配的链式结构
堆栈(栈)
先进后出
队列
先进先出