系统头文件中的库函数
stdio.h(标准输入输出库)
文件操作函数
-
一:printf:格式化输出函数。
-
#include "stdio.h" int main() { printf("hehe"); return 0; }
-
二:scanf:格式化输入函数。
-
#include "stdio.h" int main() { int n; scanf("%d", &n); printf("%d", n); return 0; }
-
三:fopen、fclose
-
#include "stdio.h" int main() { //文件指针 //声明指针类型 //下定义--打开文件fopen FILE* pf = fopen("test.txt", "w"); //打开形成的文件名字 打开方式 //文件操作 //判断是否成功打开--类似结构体 if (pf == NULL) { perror("fopen"); return 1; } //关闭文件类型 fclose(pf); pf = NULL; return 0; }
#include "stdio.h" struct S { char name[20]; int age; float socre; }; int main() { struct S s = {0}; FILE* pf = fopen("test.jkl", "rb"); if (pf == NULL) { perror("fopen"); return 1; } 读取pf里面的数据,每次读1个,开辟大小为结构体,然后放在s fread(&s,sizeof(struct S),1,pf); printf("%s %d %f\n", s.name, s.age, s.socre); fclose(pf); pf = NULL; return 0; }
四:fread
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *file;
long fileSize;
char *buffer;
size_t bytesRead;
// 打开文件
file = fopen("file.x", "rb");
if (file == NULL) {
fputs("Error opening file\n", stderr);
return 1; // 直接返回错误码
}
// 移动文件指针到文件末尾
fseek(file, 0, SEEK_END);
// 获取文件大小
fileSize = ftell(file);
// 重置文件指针到文件开头
rewind(file);
// 分配内存以存储文件内容
buffer = (char*)malloc(fileSize + 1); // +1 为了字符串的终结符 '\0'(尽管是二进制文件,但多分配一个字节可以避免后续作为字符串处理时的问题)
if (buffer == NULL) {
fputs("Error allocating memory\n", stderr);
fclose(file); // 清理已打开的文件
return 2; // 直接返回错误码
}
// 从文件中读取内容到buffer
bytesRead = fread(buffer, 1, fileSize, file);
if (bytesRead != fileSize) {
// 读取失败或未读取到预期数量的字节
fputs("Error reading file\n", stderr);
free(buffer); // 释放已分配的内存
fclose(file); // 清理已打开的文件
return 3; // 直接返回错误码
}
// 在这里,你可以对buffer中的数据进行处理...
// 但由于这是一个简化的示例,我们只是模拟了处理过程
// 清理资源
free(buffer);
fclose(file);
return 0; // 成功完成
}
五:fwrite
#include "stdio.h"
struct S
{
char name[20];
int age;
float socre;
};
int main()
{
struct S s = {"zhagsan",20,95.5f};
FILE* pf = fopen("test.jkl", "wb");
if (pf == NULL)
{
perror("fopen");
return 1;
}
fwrite(&s,sizeof(struct S),1,pf);
fclose(pf);
pf = NULL;
return 0;
}
六:fprintf
#include "stdio.h"
struct S
{
int n;
float f;
char arr[20];
};
int main()
{
struct S s = { 100,3.14f,"zhangsan" };
FILE* pf = fopen("test.jkl", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
fprintf(pf,"%d %f %s\n",s.n,s.f,s.arr);
fclose(pf);
pf = NULL;
return 0;
}
七:fscanf
#include "stdio.h"
struct S
{
int n;
float f;
char arr[20];
};
int main()
{
struct S s = {0};
FILE* pf = fopen("test.jkl", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
fscanf(pf,"%d %f %s",&(s.n),&(s.f),s.arr);
fclose(pf);
pf = NULL;
return 0;
}
stdlib.h(标准库函数)
内存分配和释放函数
-
一:malloc开辟一个内存
Point*points=(Point *)malloc(sizeof(Point)) 返回值 返回类型 开辟字节大小 如果开辟字节大小是可用数据来表示的话,可以直接写数字上去 eg int len1 = strlen(s1); char* temp = (char*)malloc(2 * len1 + 1*sizeof(char)); ---char 是一个字节,所以可以简化成下面这段代码,+1是为了给”\0”留一个位置 char* temp = (char*)malloc(2 * len1 + 1);
A.malloc函数向内存申请一块连续的空间,并返回起始地址 B.malloc申请空间失败,返回NULL指针 C.malloc可以向内存申请0字节的空间(calloc也差不多)
-
#include "stdio.h" #include "stdlib.h" int main() { char* str; str = (char*)malloc(sizeof(char)); if (str == NULL) { return; } free(str); return 0; }
-
二:calloc开辟多个内存
Int sum; Scanf(“%d”,&sum); Point*points=(Point *)calloc(num,sizeof(Point))//定义5个空间,每一个空间的大小sizeof(Point)个字节
-
#include "stdio.h" #include "stdlib.h" int main() { char* str; int i; scanf("%d", &i); str = (char*)calloc(i,sizeof(char)); if (str == NULL) { return; } free(str); return 0; }
三:realloc修改内存空间
Point*points/pa1=(Point*/int*)realloc(Point*points,28);
表达为 将Point*points修改为28个字节空间大小
开辟空间的三种可能:1.在原来基础上开辟 2.在新的第方式开辟,并且把旧的值传进去,释放掉原来的开辟空间 3.开辟了空指针,需要进行判断并且用一个临时指针来接受
-
Int *ljl=(Point*/int*)realloc(Point*points,28); If(ljl != NULL) { Point*points/pa1=ljl};
-
四: free释放
Free(Point*points/pa1)
用上述的进行设置的动态空间,需要用free去释放,不然会内存泄露。
-
程序终止函数。
-
一:exit
-
#include <stdio.h> #include <stdlib.h> int main() { // 假设这里有一些条件判断 int jkl= 1; // 假设条件不满足,我们想要退出程序 if (jkl) { printf("条件不满足,程序将退出。\n"); exit(1); // 退出程序,并返回1表示错误 } // 如果条件满足,程序将继续执行下面的代码 // 但在这个例子中,由于条件被设置为1,所以下面的代码不会被执行 printf("条件满足,程序继续执行。\n"); // 正常情况下,程序会在main函数末尾隐式地通过返回0来退出 // 但由于我们调用了exit,所以程序会在那里提前退出 return 0; // 这行代码实际上在这个例子中不会被执行 }
-
二:abort
-
#include <stdio.h> #include <stdlib.h> int main() { // 假设这里有一些条件判断 int jkl= 1; // 假设发生了某种错误,我们想要异常终止程序 if (jkl) { printf("发生严重错误,程序将异常终止。\n"); abort(); // 异常终止程序 } // 如果没有错误发生,程序将继续执行下面的代码 // 但在这个例子中,由于设置了jkl为1,所以下面的代码不会被执行 printf("程序正常运行。\n"); // 正常情况下,程序会在main函数末尾隐式地返回0 // 但由于我们调用了abort,所以程序会在那里提前异常终止 return 0; // 这行代码在这个例子中不会被执行 }
-
随机数生成函数
-
rand,srand
-
#include <stdio.h> #include <stdlib.h> #include <time.h> int main() { // 使用当前时间作为随机数生成的种子 srand((unsigned)time(NULL)); // 生成并打印10个随机数 for(int i = 0; i < 10; i++) { // rand() 函数返回一个伪随机数,其值在 0 到 RAND_MAX 之间 // RAND_MAX 是一个在 <stdlib.h> 中定义的常量,表示 rand() 函数能返回的最大值 printf("%d\n", rand()); // 如果你想要一个范围内的随机数,比如 1 到 100,你可以这样做: // printf("%d\n", rand() % 100 + 1); } return 0; }
string.h(字符串处理函数)
一:strcpy
#include <stdio.h>
#include <string.h>
int main()
{
char str1[] = "hello";
char str2[40];
//将str1复制到str2中
strcpy(str2, str1);
printf("str1: %s\nstr2: %s\n", str1, str2);
return 0;
}
二:strnpy
#include <stdio.h>
#include <string.h>
int main ()
{
char str1[]= "To jkl";
char str2[40];
char str3[40];
strncpy ( str2, str1, sizeof(str2) );
puts (str2);
return 0;
}
三:strcat
#include <stdio.h>
#include <string.h>
int main()
{
char str[30];
strcpy(str, "holle");
strcat(str, "world");
puts(str);
return 0;
}
四:strcmp
#include <stdio.h>
#include <string.h>
int main()
{
char key[] = "5";
char j[10];
do {
printf("Guess my favorite number in 1-10? ");
fflush(stdout);
scanf("%79s", j);
} while (strcmp(key, j) != 0);
puts("yes!");
return 0;
}
五:strlen
#include "stdio.h"
#include "string.h"
int main()
{
char str[] = "asf";
int len = 0;
len=strlen(str);
printf("%d\n", len);
return 0;
}
六:strlwr
#include <stdio.h>
#include <ctype.h> // 为了使用 tolower 函数
void my_strlwr(char *str) {
while (*str) { // 遍历字符串直到遇到 '\0'
*str = tolower((unsigned char)*str); // 将当前字符转换为小写
str++;
}
}
int main() {
char str[] = "HELLO, WORLD!";
printf("Original: %s\n", str);
my_strlwr(str); // 调用自定义的 strlwr 函数
printf("Lowercase: %s\n", str);
return 0;
}
七:strupr
#include <stdio.h>
#include <ctype.h> // 为了使用 toupper 函数
void strupr(char* str) {
while (*str) {
*str = toupper((unsigned char)*str); // 将当前字符转换为大写
str++;
}
}
int main() {
char str[] = "Hello, World!";
printf("Original: %s\n", str);
strupr(str);
printf("Uppercase: %s\n", str);
return 0;
}
八:strstr
#include <stdio.h>
#include <string.h>
int main()
{
char str[] = "asdf";
char* jkl;
jkl = strstr(str, "a");
if (jkl != NULL)
{
puts(str);
}
else
{
printf("no");
}
return 0;
}
math.h(数学计算函数)
一:sqrt
#include <stdio.h>
#include <math.h>
double jkl(double x) {
return sqrt(x);
}
int main() {
double number = 9.0;
double result = jkl(number);
printf("%.2f\n",result);
return 0;
}
二:sin,cos,tan
#include <stdio.h>
#include <math.h> // 引入math.h以使用sin函数,但我们不直接使用M_PI
// 定义一个近似的π值
#define PI 3.141592653589793
// 声明一个函数,它接受角度(以度为单位),将其转换为弧度,并返回其正弦值
double sinDegrees(double degrees) {
// 将度转换为弧度
double radians = degrees * (PI / 180.0);
// 使用标准库的sin函数计算正弦值
return sin/cos/tan(radians);
}
int main() {
// 计算45度的正弦值
double angleDegrees = 45.0;
double sineValue = sinDegrees(angleDegrees);
printf("The sine of %.2f degrees is %.6f\n", angleDegrees, sineValue);
return 0;
}
三:exp
#include <stdio.h>
// 定义一个简单的exp函数,使用泰勒级数的前几项来近似
double simple_exp(double x) {
// 定义泰勒级数的前几项系数,这里只取了前5项(实际上可能需要更多项以提高精度)
// 注意:e^x = 1 + x + x^2/2! + x^3/3! + ...
double term = 1.0; // 第一项为1
double sum = 1.0; // 初始和也为1(因为第一项就是1)
double factorial = 1.0; // 阶乘,初始化为1
for (int i = 1; i < 5; ++i) { // 循环4次,因为我们已经有了第一项
factorial *= i; // 计算阶乘
term *= x / factorial; // 计算当前项的值
sum += term; // 累加到总和中
}
return sum;
}
int main() {
double x = 1.0;
double result = simple_exp(x);
printf("exp(%f) ≈ %f\n", x, result);
return 0;
}
四:log
#include <stdio.h>
#include <math.h> // 用于exp函数,仅用于验证
// 使用二分查找法近似计算自然对数log(x)
double simple_log(double x, double epsilon) {
// 假设x > 0,因为对数函数的定义域是正数
if (x <= 0) {
return -1.0; // 返回错误值
}
// 初始猜测值(这里简单地使用x-1,但通常需要更好的初始猜测)
double low = 0.0;
double high = x; // 对于自然对数,一个合理的上限是x本身(因为e^x >= x对所有x成立)
double mid;
while (high - low > epsilon) { // 当区间大小小于epsilon时停止迭代
mid = (low + high) / 2.0;
double exp_mid = exp(mid);
if (exp_mid < x) {
low = mid;
} else {
high = mid;
}
// 注意:上面的二分查找有一个问题,因为它没有处理exp_mid == x的情况,
// 这在实数运算中几乎不可能发生,但理论上应该处理这种情况以避免无限循环。
// 在实际应用中,你可能需要更复杂的逻辑来确保收敛。
}
// 返回中点作为近似值
return mid;
}
int main() {
double x = 2.71828; // e的近似值
double epsilon = 0.0001; // 精度要求
double result = simple_log(x, epsilon);
printf("log(%f) ≈ %f\n", x, result);
// 验证结果(理论上应该接近1,因为log(e) = 1)
printf("Error: %f\n", fabs(result - 1.0));
return 0;
}
五:pow
#include <stdio.h>
// 简单的pow函数实现,使用循环
double simple_pow(double x, int y) {
double result = 1.0;
for (int i = 0; i < y; i++) {
result *= x;
}
return result;
}
int main() {
double base = 2.0;
int exponent = 3;
double result = simple_pow(base, exponent);
printf("%.2f to the power of %d is %.2f\n", base, exponent, result);
return 0;
}
time.h(时间日期处理函数)
一:time
#include <stdio.h>
#include <time.h> // 包含time_t和时间操作函数的定义
// 计算两个时间点之间的差异(以秒为单位)
double calculate_time_difference(time_t start_time, time_t end_time) {
// 简单地返回两个时间点的差
return difftime(end_time, start_time);
}
int main() {
// 获取当前时间
time_t now = time(NULL);
// 假设过了一段时间(这里我们模拟为5秒)
time_t later = now + 5;
// 计算时间差
double difference = calculate_time_difference(now, later);
// 打印结果
printf("The time difference is: %.2f seconds\n", difference);
return 0;
}
二:ctime
#include <stdio.h>
#include <time.h>
// 使用ctime来显示可读的时间字符串
void simple_ctime_display(time_t time_value) {
// 使用ctime将time_t值转换为可读的字符串,并打印它
// 注意:ctime返回的字符串指向一个静态分配的缓冲区,这意味着连续调用可能会覆盖之前的结果
char* time_str = ctime(&time_value);
printf("The time is: %s", time_str);
}
int main() {
// 获取当前时间
time_t now = time(NULL);
// 调用我们自定义的函数来显示时间
simple_ctime_display(now);
return 0;
}
三:strftime
#include <stdio.h>
#include <time.h>
#include <string.h>
// 封装strftime的函数,用于格式化当前时间
void format_current_time(char *buffer, size_t bufsize, const char *format) {
// 获取当前时间
time_t now = time(NULL);
// 使用strftime将时间格式化为字符串
strftime(buffer, bufsize, format, localtime(&now));
}
int main() {
// 准备一个缓冲区来存储格式化后的时间字符串
char formatted_time[80];
// 调用封装的函数,使用"%Y-%m-%d %H:%M:%S"作为时间格式
format_current_time(formatted_time, sizeof(formatted_time), "%Y-%m-%d %H:%M:%S");
// 打印格式化后的时间
printf("Formatted time: %s\n", formatted_time);
return 0;
}
ctype.h(字符类型处理函数)
一:isalpha
#include <stdio.h>
#include <stdbool.h> // 为了使用bool, true, false
// 自定义的isalpha函数
bool my_isalpha(char c) {
// ASCII码中,大写字母A-Z的范围是65-90,小写字母a-z的范围是97-122
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
return true; // 是字母
} else {
return false; // 不是字母
}
}
int main() {
char testChar1 = 'a';
char testChar2 = '3';
char testChar3 = 'A';
printf("'%c' is an alphabet? %s\n", testChar1, my_isalpha(testChar1) ? "Yes" : "No");
printf("'%c' is an alphabet? %s\n", testChar2, my_isalpha(testChar2) ? "Yes" : "No");
printf("'%c' is an alphabet? %s\n", testChar3, my_isalpha(testChar3) ? "Yes" : "No");
return 0;
}
二:isdigit
#include <stdio.h>
#include <stdbool.h> // 为了使用bool, true, false
// 自定义的isdigit函数
bool my_isdigit(char c) {
// ASCII码中,数字0-9的范围是48-57
if (c >= '0' && c <= '9') {
return true; // 是数字
} else {
return false; // 不是数字
}
}
int main() {
char testChar1 = '5';
char testChar2 = 'a';
char testChar3 = '0';
printf("'%c' is a digit? %s\n", testChar1, my_isdigit(testChar1) ? "Yes" : "No");
printf("'%c' is a digit? %s\n", testChar2, my_isdigit(testChar2) ? "Yes" : "No");
printf("'%c' is a digit? %s\n", testChar3, my_isdigit(testChar3) ? "Yes" : "No");
return 0;
}
三:islower
#include <stdio.h>
#include <stdbool.h> // 为了使用bool, true, false
// 自定义的islower函数
bool my_islower(char c) {
// ASCII码中,小写字母a-z的范围是97-122
if (c >= 'a' && c <= 'z') {
return true; // 是小写字母
} else {
return false; // 不是小写字母
}
}
int main() {
char testChar1 = 'a';
char testChar2 = 'A';
char testChar3 = '3';
printf("'%c' is lowercase? %s\n", testChar1, my_islower(testChar1) ? "Yes" : "No");
printf("'%c' is lowercase? %s\n", testChar2, my_islower(testChar2) ? "Yes" : "No");
printf("'%c' is lowercase? %s\n", testChar3, my_islower(testChar3) ? "Yes" : "No");
return 0;
}
四:isupper
#include <stdio.h>
#include <stdbool.h> // 为了使用bool, true, false
// 自定义的isupper函数
bool my_isupper(char c) {
// ASCII码中,大写字母A-Z的范围是65-90
if (c >= 'A' && c <= 'Z') {
return true; // 是大写字母
} else {
return false; // 不是大写字母
}
}
int main() {
char testChar1 = 'A';
char testChar2 = 'a';
char testChar3 = '3';
printf("'%c' is uppercase? %s\n", testChar1, my_isupper(testChar1) ? "Yes" : "No");
printf("'%c' is uppercase? %s\n", testChar2, my_isupper(testChar2) ? "Yes" : "No");
printf("'%c' is uppercase? %s\n", testChar3, my_isupper(testChar3) ? "Yes" : "No");
return 0;
}
五:tolower
#include <stdio.h>
// 自定义的tolower函数
char my_tolower(char c) {
// ASCII码中,大写字母A-Z的范围是65-90
// 小写字母a-z的范围是97-122
// 大写字母转换为小写字母,只需要加上32(因为'a'-'A' = 32)
if (c >= 'A' && c <= 'Z') {
return c + 32; // 转换为小写字母
} else {
return c; // 不是大写字母,直接返回
}
}
int main() {
char testChar1 = 'A';
char testChar2 = 'a';
char testChar3 = '3';
printf("'%c' to lowercase: '%c'\n", testChar1, my_tolower(testChar1));
printf("'%c' to lowercase: '%c'\n", testChar2, my_tolower(testChar2));
printf("'%c' to lowercase: '%c'\n", testChar3, my_tolower(testChar3));
return 0;
}
六:toupper
#include <stdio.h>
// 自定义的toupper函数
char my_toupper(char c) {
// ASCII码中,小写字母a-z的范围是97-122
// 大写字母A-Z的范围是65-90
// 小写字母转换为大写字母,只需要减去32(因为'A'-'a' = 32)
if (c >= 'a' && c <= 'z') {
return c - 32; // 转换为大写字母
} else {
return c; // 不是小写字母,直接返回
}
}
int main() {
char testChar1 = 'a';
char testChar2 = 'A';
char testChar3 = '3';
printf("'%c' to uppercase: '%c'\n", testChar1, my_toupper(testChar1));
printf("'%c' to uppercase: '%c'\n", testChar2, my_toupper(testChar2));
printf("'%c' to uppercase: '%c'\n", testChar3, my_toupper(testChar3));
return 0;
}
errno.h(错误处理函数)
一:errno
#include <stdio.h>
#include <errno.h>
#include <string.h>
// 自定义的错误码
#define MY_SUCCESS 0
#define MY_FAILURE -1
// 模拟可能失败的操作的函数
int my_operation(int param) {
// 假设param小于0时操作失败
if (param < 0) {
// 设置errno以指示错误类型
errno = EINVAL; // EINVAL是一个在<errno.h>中定义的错误码,表示无效参数
return MY_FAILURE;
}
// 操作成功
return MY_SUCCESS;
}
// 检查my_operation函数返回值的函数
void check_operation(int result) {
if (result == MY_FAILURE) {
// 如果操作失败,打印错误信息
printf("Operation failed: %s\n", strerror(errno));
} else {
// 操作成功
printf("Operation succeeded.\n");
}
}
int main() {
// 尝试执行可能失败的操作
int result = my_operation(5); // 应该成功
check_operation(result);
result = my_operation(-1); // 应该失败
check_operation(result);
return 0;
}
二:perror
#include <stdio.h>
#include <errno.h>
#include <string.h>
// 自定义的perror函数
void my_perror(const char *s) {
// 检查s是否为NULL,避免解引用空指针
if (s == NULL) {
fprintf(stderr, "Null pointer error\n");
} else {
// 使用strerror获取errno的错误描述
fprintf(stderr, "%s: %s\n", s, strerror(errno));
}
}
// 一个可能设置errno的函数
void some_operation(int flag) {
if (flag) {
// 假设某些错误发生
errno = EINVAL; // 设置errno为无效参数错误
}
}
int main() {
printf("Before operation, errno is: %d\n", errno); // 通常应为0,除非之前已设置
some_operation(1); // 触发错误
my_perror("Operation failed"); // 使用自定义的perror函数
// 重置errno以避免影响后续调用
errno = 0;
printf("After resetting errno, errno is: %d\n", errno);
return 0;
}
signal.h(信号处理函数)
一:signal
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
// 自定义的信号处理函数
void signal_handler(int signum) {
printf("Caught signal %d\n", signum);
// 清理并退出
// 注意:在实际的程序中,你应该在这里执行必要的清理工作
// 然后退出程序,以避免不确定的行为
exit(signum);
}
int main() {
// 设置SIGINT信号的处理函数为signal_handler
signal(SIGINT, signal_handler);
// 模拟一个长时间运行的过程
printf("Waiting for signal...\n");
while (1) {
sleep(1); // 休眠一秒,等待信号
}
// 注意:由于上面的while循环是无限循环,并且我们没有在信号处理函数中调用exit,
// 这段代码实际上永远不会执行到这里。但是,为了完整性,我还是保留了它。
// 在真实的应用中,你应该在信号处理函数中处理退出逻辑。
return 0;
}
二:raise
#include <stdio.h>
#include <stdlib.h> // 为了使用exit
// 假设的错误码
#define MY_SUCCESS 0
#define MY_ERROR_INVALID_PARAM -1
#define MY_ERROR_GENERIC -2
// 全局错误码(模拟异常对象)
int my_errno = MY_SUCCESS;
// 自定义的“raise”函数,实际上只是设置错误码并可能终止程序
void my_raise(int error_code) {
my_errno = error_code;
fprintf(stderr, "Error: %d\n", error_code);
// 在这里,我们可以选择退出程序或进行其他错误处理
// 例如,exit(EXIT_FAILURE); 但这通常不是最佳实践
// 更好的做法是让调用者检查my_errno并据此处理错误
}
// 可能“抛出”错误的函数
int divide(int numerator, int denominator) {
if (denominator == 0) {
my_raise(MY_ERROR_INVALID_PARAM); // “抛出”错误
return MY_ERROR_INVALID_PARAM; // 返回错误码
}
return numerator / denominator;
}
int main() {
int result = divide(10, 0);
if (result == MY_ERROR_INVALID_PARAM) {
// 处理错误
printf("Caught an error: division by zero.\n");
} else {
// 正常情况
printf("Result: %d\n", result);
}
// 假设我们有一个不同的函数,它也可能失败
result = some_other_function(); // 假设这个函数在某些条件下会调用my_raise
if (result == MY_ERROR_GENERIC) {
// 处理其他类型的错误
printf("Caught a generic error.\n");
}
return 0;
}
// 注意:some_other_function函数在这里没有定义,但它应该遵循类似的错误处理模式