Huazie

一半诗意 一半烟火

总览

函数声明 函数功能
wchar_t *wcsdup(const wchar_t *str); 用于复制宽字符字符串
int wcsicmp(const wchar_t *s1, const wchar_t *s2); 用于比较两个宽字符字符串的大小写不敏感的差异
int wcsicoll(const wchar_t *s1, const wchar_t *s2); 用于比较两个宽字符字符串的大小写不敏感的差异, 并考虑当前本地环境的语言和排序规则
wchar_t *wcslwr(wchar_t *str); 用于将宽字符字符串转换为小写字母形式
wchar_t *wcspbrk(const wchar_t *str, const wchar_t *charset); 用于在宽字符字符串中查找指定字符集中任意一个字符第一次出现的位置
int wcsnicmp(const wchar_t *s1, const wchar_t *s2, size_t n); 用于比较两个宽字符字符串的前若干个字符的大小写不敏感的差异
wchar_t *wcsnset(wchar_t *str, wchar_t ch, size_t n); 用于将宽字符字符串中的前若干个字符设置为指定字符
wchar_t *wcsrev(wchar_t *str); 用于将宽字符字符串反转
wchar_t *wcsset(wchar_t *str, wchar_t ch); 用于将宽字符字符串中的所有字符设置为指定字符
long int wcstoll(const wchar_t* str, wchar_t** endptr, int base); 用于将宽字符串转换为长整形
unsigned long long int wcstoull(const wchar_t* str, wchar_t** endptr, int base); 用于将宽字符串转换为无符号长整型
wchar_t* wcsupr(wchar_t* str); 用于将宽字符串转换为大写
wctrans_t wctrans(const char* property); 用于创建字符转换描述符
wchar_t* wmempcpy(wchar_t* dest, const wchar_t* src, size_t n); 用于将将源宽字符串的前 n 个字节的内容拷贝到目标字符串中
wchar_t* wmemmove(wchar_t* dest, const wchar_t* src, size_t n); 将源宽字符串中指定数量的字节复制到目标宽字符串中,即使目标内存和源内存重叠

1. wcsdup

1.1 函数说明

函数声明 函数功能
wchar_t *wcsdup(const wchar_t *str); 用于复制宽字符字符串

参数:

  • str : 待复制的宽字符串

返回值:

  • 如果成功复制,则返回指向该内存块的指针;
  • 如果内存分配失败,函数将返回 NULL

1.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>

int main(void)
{
// 宽字符字符串 "Hello, world!"
const wchar_t *ws = L"Hello, world!";

// 复制宽字符字符串
wchar_t *ws_copy = wcsdup(ws);

if (ws_copy == NULL)
{
fprintf(stderr, "Error: Failed to allocate memory.\n");
return 1;
}

// 输出原始和副本字符串
wprintf(L"Original string: %ls\n", ws);
wprintf(L"Copy: %ls\n", ws_copy);
// 释放由 wcsdup() 函数分配的内存空间
free(ws_copy);

return 0;
}

1.3 运行结果

2. wcsicmp

2.1 函数说明

函数声明 函数功能
int wcsicmp(const wchar_t *s1, const wchar_t *s2); 用于比较两个宽字符字符串的大小写不敏感的差异

参数:

  • s1 : 待比较的宽字符串1
  • s2 : 待比较的宽字符串2

返回值:

  • 如果 s1 指向的字符串按字典顺序小于 s2 指向的字符串(忽略大小写),则函数返回一个负整数;
  • 如果 s1 等于 s2,则函数返回 0
  • 如果 s1 指向的字符串按字典顺序大于 s2 指向的字符串(忽略大小写),则函数返回一个正整数。

2.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <stdio.h>
#include <wchar.h>

int main(void)
{
// 宽字符字符串 "Hello, huazie!"
const wchar_t *ws1 = L"Hello, huazie!";

// 宽字符字符串 "hello, HUAZIE!"
const wchar_t *ws2 = L"hello, HUAZIE!";

int cmp_result = wcsicmp(ws1, ws2);

// 输出比较结果
if (cmp_result < 0)
{
wprintf(L"%ls is less than %ls.\n", ws1, ws2);
}
else if (cmp_result == 0)
{
wprintf(L"%ls is equal to %ls.\n", ws1, ws2);
}
else
{
wprintf(L"%ls is greater than %ls.\n", ws1, ws2);
}

return 0;
}

2.3 运行结果

3. wcsicoll

3.1 函数说明

函数声明 函数功能
int wcsicoll(const wchar_t *s1, const wchar_t *s2); 用于比较两个宽字符字符串的大小写不敏感的差异, 并考虑当前本地环境的语言和排序规则

参数:

  • s1 : 待比较的宽字符串1
  • s2 : 待比较的宽字符串2

返回值:

  • 如果 s1 指向的字符串按字典顺序小于 s2 指向的字符串(忽略大小写),则函数返回一个负整数;
  • 如果 s1 等于 s2,则函数返回 0
  • 如果 s1 指向的字符串按字典顺序大于 s2 指向的字符串(忽略大小写),则函数返回一个正整数。

3.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <stdio.h>
#include <wchar.h>
#include <locale.h>

int main(void)
{
// 设置本地环境
setlocale(LC_ALL, "");

// 宽字符字符串 "Hello, world!"
const wchar_t *ws1 = L"Hello, huazie!";

// 宽字符字符串 "hello, WORLD!"
const wchar_t *ws2 = L"hello, HUAZIE!";

int cmp_result = wcsicoll(ws1, ws2);

// 输出比较结果
if (cmp_result < 0)
{
wprintf(L"%ls is less than %ls.\n", ws1, ws2);
}
else if (cmp_result == 0)
{
wprintf(L"%ls is equal to %ls.\n", ws1, ws2);
}
else
{
wprintf(L"%ls is greater than %ls.\n", ws1, ws2);
}

return 0;
}

注意: 在使用 wcsicoll() 函数前,需要先调用 setlocale() 函数设置本地环境。

3.3 运行结果

4. wcslwr

4.1 函数说明

函数声明 函数功能
wchar_t *wcslwr(wchar_t *str); 用于将宽字符字符串转换为小写字母形式

参数:

  • str : 待转换的宽字符串

4.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <wchar.h>

int main(void)
{
// 宽字符字符串 "Hello, HUAZIE!"
wchar_t ws[] = L"Hello, HUAZIE!";

// 将字符串转换为小写字母形式
wcslwr(ws);

// 输出转换后的字符串
wprintf(L"%ls\n", ws);

return 0;
}

4.3 运行结果

5. wcspbrk

5.1 函数说明

函数声明 函数功能
wchar_t *wcspbrk(const wchar_t *str, const wchar_t *charset); 用于在宽字符字符串中查找指定字符集中任意一个字符第一次出现的位置

参数:

  • str : 要搜索的宽字符字符串
  • charset : 要搜索的宽字符集合

wcspbrk() 函数会将 str 指向的宽字符字符串中的每个字符与 charset 指向的宽字符集合中的字符进行比较,直到找到其中任意一个相同的字符为止。
返回值:

  • 如果找到了这样的字符,则函数返回指向该字符的指针;
  • 否则,函数返回 NULL

5.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <wchar.h>

int main(void)
{
// 宽字符字符串 "Hello, huazie!"
const wchar_t *ws = L"Hello, huazie!";

// 查找第一个出现在 "abcd" 中的字符
wchar_t *result = wcspbrk(ws, L"abcd");

if (result == NULL)
{
wprintf(L"No matching character found.\n");
}
else
{
wprintf(L"First matching character: %lc\n", *result);
}

return 0;
}

5.3 运行结果

6. wcsnicmp

6.1 函数说明

函数声明 函数功能
int wcsnicmp(const wchar_t *s1, const wchar_t *s2, size_t n); 用于比较两个宽字符字符串的前若干个字符的大小写不敏感的差异

参数:

  • s1 : 待比较的宽字符串1
  • s2 : 待比较的宽字符串2
  • n : 要比较的字符数目

返回值:

  • 如果 s1 指向的字符串按字典顺序小于 s2 指向的字符串(忽略大小写),则函数返回一个负整数;
  • 如果 s1 等于 s2,则函数返回 0
  • 如果 s1 指向的字符串按字典顺序大于 s2 指向的字符串(忽略大小写),则函数返回一个正整数。

6.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <stdio.h>
#include <wchar.h>

int main(void)
{
// 宽字符字符串 "Hello, huazie!"
const wchar_t *ws1 = L"Hello, huazie!";

// 宽字符字符串 "HELLO, HUAZIE!"
const wchar_t *ws2 = L"HELLO, HUAZIE!";

int cmp_result = wcsnicmp(ws1, ws2, 5);

// 输出比较结果
if (cmp_result < 0)
{
wprintf(L"%ls is less than %ls.\n", ws1, ws2);
}
else if (cmp_result == 0)
{
wprintf(L"%ls is equal to %ls.\n", ws1, ws2);
}
else
{
wprintf(L"%ls is greater than %ls.\n", ws1, ws2);
}

return 0;
}

6.3 运行结果

7. wcsnset

7.1 函数说明

函数声明 函数功能
wchar_t *wcsnset(wchar_t *str, wchar_t ch, size_t n); 用于将宽字符字符串中的前若干个字符设置为指定字符

参数:

  • s1 : 要修改的宽字符字符串
  • s2 : 要设置的宽字符
  • n : 要设置的宽字符数目

7.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <wchar.h>

int main(void)
{
// 宽字符字符串 "Hello, huazie!"
wchar_t ws[] = L"Hello, huazie!";

// 将前五个字符设置为 '*'
wcsnset(ws, L'*', 5);

// 输出修改后的字符串
wprintf(L"%ls\n", ws);

return 0;
}

7.3 运行结果

8. wcsrev

8.1 函数说明

函数声明 函数功能
wchar_t *wcsrev(wchar_t *str); 用于将宽字符字符串反转

参数:

  • s1 : 要反转的宽字符字符串

8.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <wchar.h>

int main(void)
{
// 宽字符字符串 "Hello, huazie!"
wchar_t ws[] = L"Hello, huazie!";

// 反转字符串
wcsrev(ws);

// 输出反转后的字符串
wprintf(L"%ls\n", ws);

return 0;
}

8.3 运行结果

9. wcsset

9.1 函数说明

函数声明 函数功能
wchar_t *wcsset(wchar_t *str, wchar_t ch); 用于将宽字符字符串中的所有字符设置为指定字符

参数:

  • str : 要修改的宽字符字符串
  • ch : 要设置的宽字符

9.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include <wchar.h>

int main(void)
{
// 宽字符字符串 "Hello, huazie!"
wchar_t ws[] = L"Hello, huazie!";

// 输出修改前的字符串
wprintf(L"Before: %ls\n", ws);

// 将字符串中的每个字符都设置为 '#'
wcsset(ws, L'#');

// 输出修改后的字符串
wprintf(L"After : %ls\n", ws);

return 0;
}

注意: wcsset() 函数会修改原始字符串,因此需要在操作前确保原始字符串可以被修改。

9.3 运行结果

10. wcstoll

10.1 函数说明

函数声明 函数功能
long int wcstoll(const wchar_t* str, wchar_t** endptr, int base); 用于将宽字符串转换为长整形

参数:

  • str : 要转换成长整型的宽字符串
  • endptr : 一个指向指针的指针,可用于检测是否发生了转换错误,并且返回第一个无法被识别的宽字符位置。当该值为 nullptr 时,不会返回无法被识别的宽字符位置
  • base : 进制数,默认为 10

10.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>

int main()
{
const wchar_t* str = L"123456789";
//const wchar_t* str = L"12345a6789";
//const wchar_t* str = L"a123456789";
wchar_t* endptr;
long int num;

num = wcstoll(str, &endptr, 10);

wprintf(L"The number is %ld\n", num);

return 0;
}

10.3 运行结果

11. wcstoull

11.1 函数说明

函数声明 函数功能
unsigned long long int wcstoull(const wchar_t* str, wchar_t** endptr, int base); 用于将宽字符串转换为无符号长整型

参数:

  • str : 要转换成无符号长整型的宽字符串
  • endptr : 一个指向指针的指针,可用于检测是否发生了转换错误,并且返回第一个无法被识别的宽字符位置。当该值为 nullptr 时,不会返回无法被识别的宽字符位置
  • base : 进制数,默认为 10

11.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>

int main()
{
const wchar_t* str = L"123456789";
//const wchar_t* str = L"12345a6789";
//const wchar_t* str = L"a123456789";
wchar_t* endptr;
unsigned long long int num;

num = wcstoull(str, &endptr, 10);

wprintf(L"The number is %llu\n", num);

return 0;
}

wcstoull() 函数的用法和 wcstoll() 函数类似,不再赘述了。

11.3 运行结果

12. wcsupr

12.1 函数说明

函数声明 函数功能
wchar_t* wcsupr(wchar_t* str); 用于将宽字符串转换为大写

参数:

  • str : 要转换为大写的宽字符串

12.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <wchar.h>

int main(void)
{
// 宽字符字符串 "Hello, huazie!"
wchar_t ws[] = L"Hello, huazie!";

// 将宽字符串转换为大写字母形式
wcsupr(ws);

// 输出转换后的字符串
wprintf(L"%ls\n", ws);

return 0;
}

12.3 运行结果

13. wctrans

13.1 函数说明

函数声明 函数功能
wctrans_t wctrans(const char* property); 用于创建字符转换描述符
wint_t towctrans(wint_t wc, wctrans_t desc); 通过 wctrans() 函数创建的字符转换描述符,可以将一个字符或字符串进行指定类型的转换。

wctrans 参数:

  • property : 转换属性名称

towctrans 参数:

  • wc : 待转换的字符
  • desc : 转换描述符

13.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include <wctype.h>
#include <wchar.h>

int main() {
// 创建一个转换描述符,用于将小写字母转换为大写字母
wctrans_t to_upper = wctrans("toupper");

// 使用转换描述符将 wchar_t 类型字符串中的所有小写字母转换为大写字母
wchar_t str[] = L"hello huazie";
for (int i = 0; str[i] != L'\0'; i++) {
str[i] = towctrans(str[i], to_upper);
}

// 输出结果:"HELLO WORLD"
wprintf(L"%ls\n", str);

return 0;
}

13.3 运行结果

14. wmempcpy

14.1 函数说明

函数声明 函数功能
wchar_t* wmempcpy(wchar_t* dest, const wchar_t* src, size_t n); 用于将将源宽字符串的前 n 个字节的内容拷贝到目标字符串中

参数:

  • dest : 目标宽字符串
  • src : 源宽字符串
  • n : 要拷贝的字节数

14.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include <wchar.h>
#include <string.h>

int main()
{
const wchar_t* src = L"Hello, Huazie!";
wchar_t dest[20];

wprintf(L"Original string: %ls\n", src);

// 将源字符串内容拷贝到目标字符串中
wchar_t* ptr = wmempcpy(dest, src, wcslen(src) * sizeof(wchar_t));
*ptr = L'\0';

wprintf(L"Copied string: %ls\n", dest);

return 0;
}

14.3 运行结果

15. wmemmove

15.1 函数说明

函数声明 函数功能
wchar_t* wmemmove(wchar_t* dest, const wchar_t* src, size_t n); 将源宽字符串中指定数量的字节复制到目标宽字符串中,即使目标内存和源内存重叠

参数:

  • dest : 目标宽字符串
  • src : 源宽字符串
  • n : 要移动的字节数

15.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
#include <wchar.h>
#include <string.h>

int main()
{
wchar_t str[30] = L"Hello, Huazie!";

wprintf(L"Original string: %ls\n", str);

// 将字符串中前5个字符移动到后面
wmemmove(str + 6, str, 5 * sizeof(wchar_t));

wprintf(L"Moved string: %ls\n", str);

return 0;
}

15.3 运行结果

总览

函数声明 函数功能
wchar_t *wcstok(wchar_t *wcs, const wchar_t *delim, wchar_t **ptr); 用于将一个长字符串拆分成几个短字符串(标记),并返回第一个标记的地址
wchar_t *wcstok(wchar_t *wcs, const wchar_t *delim); 用于将一个长字符串拆分成几个短字符串(标记),并返回第一个标记的地址
long int wcstol(const wchar_t* str, wchar_t** endptr, int base); 用于将字符串转换为长整型数字的函数
unsigned long int wcstoul(const wchar_t* str, wchar_t** endptr, int base); 用于将字符串转换为无符号长整型数字
size_t wcsxfrm(wchar_t* dest, const wchar_t* src, size_t n); 将一个 Unicode 字符串转换为一个 “可排序” 的字符串。该新字符串中的字符序列反映了源字符串中的字符顺序和大小写信息,以便进行字典序比较。
wctype_t wctype(const char* property); 用于确定给定的宽字符类别
int wctob(wint_t wc); 用于将给定的宽字符转换为其对应的字节表示
int wctomb(char* s, wchar_t wc); 用于将给定的宽字符转换为其对应的多字节字符表示
void* wmemchr(const void* s, wchar_t c, size_t n); 用于在宽字符数组中查找给定的宽字符
int wmemcmp(const wchar_t* s1, const wchar_t* s2, size_t n); 用于比较两个宽字符数组的前 n 个宽字符
wchar_t* wmemcpy(wchar_t* dest, const wchar_t* src, size_t n); 用于将一个宽字符数组的前 n 个宽字符复制到另一个宽字符数组
wchar_t* wmemset(wchar_t* s, wchar_t c, size_t n); 用于将一个宽字符数组的前 n 个宽字符设置为给定的宽字符值
int wprintf(const wchar_t* format, ...); 用于格式化输出宽字符字符串
ssize_t write(int fd, const void* buf, size_t count); 用于将数据写入文件描述符
int wscanf(const wchar_t* format, ...); 用于从标准输入流(stdin)读取格式化的宽字符输入

1. wcstok

1.1 函数说明

函数声明 函数功能
wchar_t *wcstok(wchar_t *wcs, const wchar_t *delim, wchar_t **ptr); 用于将一个长字符串拆分成几个短字符串(标记),并返回第一个标记的地址
wchar_t *wcstok(wchar_t *wcs, const wchar_t *delim); 用于将一个长字符串拆分成几个短字符串(标记),并返回第一个标记的地址

参数:

  • wcs : 被分割的字符串
  • delim : 分割符字符串,包含多个字符
  • ptr : 指向保存上次调用后的指针的指针,首次调用时需赋值为 NULL

1.2 演示示例

windows 下两个参数的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <wchar.h>
#include <stdio.h>

int main() {
wchar_t str[] = L"Hello, huazie! This is wcstok demo.";
wchar_t* token;

// 第一次调用
token = wcstok(str, L" ,.!?");
while (token != NULL)
{
wprintf(L"%ls\n", token);
token = wcstok(NULL, L" ,.!?");
}

return 0;
}

1.3 运行结果

2. wcstol

2.1 函数说明

函数声明 函数功能
long int wcstol(const wchar_t* str, wchar_t** endptr, int base); 用于将字符串转换为长整型数字的函数

参数:

  • str : 要转换的字符串
  • endptr : 可选输出参数,指向第一个不能转换成数字字符的字符的指针
  • base : 数字基数,介于 236 之间;
    base 参数为 0 时,wcstol() 函数会自动检测数字基数:
    • 如果输入字符串以 "0x""0X" 开头,则将基数设置为 16
    • 如果输入字符串以 "0" 开头,则将基数设置为 8
    • 如果不是这些情况,则将基数设置为 10

2.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>

int main()
{
//const wchar_t* str = L"123456";
//const wchar_t* str = L"123a456";
//const wchar_t* str = L"a123456";
const wchar_t* str = L"0xFF";
wchar_t* endptr;
long int num;

//num = wcstol(str, &endptr, 10);
num = wcstol(str, &endptr, 0);
if (endptr == str)
printf("Invalid input.\n");
else
printf("The number is %ld\n", num);

return 0;
}

注意: 如果输入字符串无法转换为数字,则 wcstol() 函数返回 0,并将 endptr 指向输入字符串的起始位置。所以,在使用 wcstol() 函数时,建议检查 endptrstr 是否相同,以确定输入是否有效。

2.3 运行结果




3. wcstoul

3.1 函数说明

函数声明 函数功能
unsigned long int wcstoul(const wchar_t* str, wchar_t** endptr, int base); 用于将字符串转换为无符号长整型数字

参数:

  • str : 要转换的字符串
  • endptr : 可选输出参数,指向第一个不能转换成数字字符的字符的指针
  • base : 数字基数,介于 236 之间;
    base 参数为 0 时,wcstol() 函数会自动检测数字基数:
    • 如果输入字符串以 "0x""0X" 开头,则将基数设置为 16
    • 如果输入字符串以 "0" 开头,则将基数设置为 8
    • 如果不是这些情况,则将基数设置为 10

3.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>

int main()
{
const wchar_t* str = L"123a456";
wchar_t* endptr;
unsigned long int num;

num = wcstoul(str, &endptr, 10);
if (endptr == str)
printf("Invalid input.\n");
else
printf("The number is %lu\n", num);

return 0;
}

wcstoul() 函数的用法和 wcstol() 函数类似,这里就不一一列举了

3.3 运行结果

4. wcsxfrm

4.1 函数说明

函数声明 函数功能
size_t wcsxfrm(wchar_t* dest, const wchar_t* src, size_t n); 将一个 Unicode 字符串转换为一个 “可排序” 的字符串。该新字符串中的字符序列反映了源字符串中的字符顺序和大小写信息,以便进行字典序比较。

参数:

  • dest : 存储转换后字符串的目标缓冲区
  • src: 要转换的源字符串
  • n : 目标缓冲区的最大长度

4.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>

#define ARRAY_SIZE 5

int main()
{
const wchar_t* arr[ARRAY_SIZE] = { L"Tom", L"Alice", L"Huazie", L"David", L"Charlie" };
wchar_t sorted_arr[ARRAY_SIZE][50];
size_t i;

for (i = 0; i < ARRAY_SIZE; i++)
{
wcsxfrm(sorted_arr[i], arr[i], sizeof(sorted_arr[i]));
}

// 使用 qsort 对字符串数组排序
qsort(sorted_arr, ARRAY_SIZE, sizeof(sorted_arr[0]), wcscmp);

// 排序后输出
wprintf(L"Sorted array:\n");
for (i = 0; i < ARRAY_SIZE; i++)
{
wprintf(L"%ls\n", sorted_arr[i]);
}

return 0;
}

在上面的示例代码中,

  • 首先,我们定义一个包含 5Unicode 字符串的字符串数组 arr,每个字符串代表一个人名;
  • 然后,定义一个大小为 5x50 的二维字符数组 sorted_arr,用于存储排序后的字符串;
  • 接着,使用 wcsxfrm() 函数将每个 Unicode 字符串转换为可排序字符串,并将结果存储在 sorted_arr 数组中;
  • 再然后,使用 qsort() 函数按字典序对 sorted_arr 数组中的字符串进行排序;
  • 再接着,使用 wprintf() 函数输出排序后的字符串;
  • 最后结束程序。

4.3 运行结果

5. wctype

5.1 函数说明

函数声明 函数功能
wctype_t wctype(const char* property); 用于确定给定的宽字符类别

参数:

  • property : 一个指向表示宽字符属性名称的字符串字面量的指针

常见的宽字符属性及含义如下:

属性名称 含义
"alnum" 字母数字字符
"alpha" 字母字符
"blank" 空格或水平制表符字符
"cntrl" 控制字符
"digit" 数字字符
"graph" 可打印字符(除空格字符外)
"lower" 小写字母字符
"print" 可打印字符
"punct" 标点符号字符
"space" 空白字符
"upper" 大写字母字符
"xdigit" 十六进制数字字符

返回值:

  • 如果指定的属性存在,则返回相应的宽字符类型;
  • 如果指定的属性不存在,则返回零。

5.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
#include <wchar.h>
#include <wctype.h>

int main()
{
wchar_t ch = L',';
wctype_t punct_wt;

// 获取标点符号字符类型
punct_wt = wctype("punct");

// 判断指定的宽字符是否为标点符号
if (iswctype(ch, punct_wt)) {
wprintf(L"%lc is a punctuation character.\n", ch);
} else {
wprintf(L"%lc is not a punctuation character.\n", ch);
}

return 0;
}

注意: 在调用 wctype() 函数时,应该传递一个有效的宽字符属性名称作为参数,详见 5.1 的表格所示。

5.3 运行结果

6. wctob

6.1 函数说明

函数声明 函数功能
int wctob(wint_t wc); 用于将给定的宽字符转换为其对应的字节表示

参数:

  • wc : 一个宽字符值

返回值:

  • 如果能转换成功,则返回返回与之对应的字节表示;
  • 如果无法将给定宽字符转换为字节表示,则返回 EOF

6.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <wchar.h>

int main()
{
wchar_t ch = L'?';
int byte;

// 将 Unicode 字符转换为字节表示
byte = wctob(ch);

// 输出字节值
printf("Byte value of %lc: %d (0x%02X)\n", ch, byte, byte);

return 0;
}

注意: 在使用 wctob() 函数时,应该确保系统当前的本地化环境和编码方式与程序中使用的字符编码一致。如果字符编码不一致,可能会导致错误的结果或未定义行为。

6.3 运行结果

7. wctomb

7.1 函数说明

函数声明 函数功能
int wctomb(char* s, wchar_t wc); 用于将给定的宽字符转换为其对应的多字节字符表示

参数:

  • s : 一个指向字符数组的指针
  • wc : 一个宽字符值

返回值:

  • 如果能转换成功,则将 wc 转换为其对应的多字节字符表示,存储在 s 指向的字符数组中;
  • 如果 s 是空指针,则不执行任何操作,只返回转换所需的字符数;
  • 如果无法将给定宽字符转换为多字节字符表示,则返回 -1

7.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>

int main()
{
wchar_t ch = L'?';
char mb[MB_CUR_MAX];
int len;

// 将 Unicode 字符转换为多字节字符表示
len = wctomb(mb, ch);

// 输出转换结果
if (len >= 0)
{
printf("Multibyte representation of %lc: ", ch);
for (int i = 0; i < len; i++) {
printf("%02X ", (unsigned char) mb[i]);
}
printf("\n");
}
else
{
printf("Failed to convert %lc to multibyte character.\n", ch);
}

return 0;
}

在上面的示例程序中,wctomb() 函数被用来将 Unicode 字符 ',' 转换为其对应的多字节字符表示,并将结果保存在字符数组 mb 中。然后,程序输出每个字节的十六进制值。

注意: 在使用 wctomb() 函数时,应该根据当前的本地化环境和编码方式调整字符数组的大小。可以使用 MB_CUR_MAX 宏来获取当前编码方式下一个多字节字符所需的最大字节数,从而确定字符数组的大小。

7.3 运行结果

8. wmemchr

8.1 函数说明

函数声明 函数功能
void* wmemchr(const void* s, wchar_t c, size_t n); 用于在宽字符数组中查找给定的宽字符

参数:

  • s : 一个指向宽字符数组的指针
  • c : 要查找的宽字符值
  • n : 要搜索的字节数

返回值:

  • 如果找到了 c,则返回指向该位置的指针;
  • 否则返回空指针。

8.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
#include <wchar.h>

int main()
{
const wchar_t str[] = L"Hello, Huazie!";
const wchar_t ch = L'u';
wchar_t* pch;

// 在宽字符数组中查找给定的宽字符
// 使用 wcslen() 函数来获取 str 的长度,以指定要搜索的字节数 n
pch = wmemchr(str, ch, wcslen(str));

// 根据 pch,来判断是否找到,并输出结果
if (pch)
wprintf(L"Found '%lc' at position %d.\n", ch, (int)(pch - str));
else
wprintf(L"Could not find '%lc'.\n", ch);

return 0;
}

8.3 运行结果

9. wmemcmp

9.1 函数说明

函数声明 函数功能
int wmemcmp(const wchar_t* s1, const wchar_t* s2, size_t n); 用于比较两个宽字符数组的前 n 个宽字符

参数:

  • s1 : 待比较的宽字符串1
  • s2 : 待比较的宽字符串2
  • n : 要比较的字节数

返回值:

  • 如果两个数组相等,则返回零;
  • 如果 s1s2 小,则返回负数;
  • 如果 s1s2 大,则返回正数。

9.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <wchar.h>

int main()
{
const wchar_t str1[] = L"Hello";
const wchar_t str2[] = L"Huazie";
int result;

// 比较两个宽字符数组
result = wmemcmp(str1, str2, wcslen(str1));

// 根据result,来判断,并输出结果
if (result == 0)
wprintf(L"%ls and %ls are equal.\n", str1, str2);
else if (result < 0)
wprintf(L"%ls is less than %ls.\n", str1, str2);
else
wprintf(L"%ls is greater than %ls.\n", str1, str2);

return 0;
}

9.3 运行结果

10. wmemcpy

10.1 函数说明

函数声明 函数功能
wchar_t* wmemcpy(wchar_t* dest, const wchar_t* src, size_t n); 用于将一个宽字符数组的前 n 个宽字符复制到另一个宽字符数组

参数:

  • dest : 目标宽字符串
  • src : 源宽字符串
  • n : 要复制的字节数

10.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <wchar.h>
#include <string.h>

int main()
{
const wchar_t src[] = L"Hello, Huazie!";
wchar_t dest[20];

// 将一个宽字符数组复制到另一个宽字符数组
wmemcpy(dest, src, wcslen(src) + 1);

// 输出结果
wprintf(L"Source string: %ls\n", src);
wprintf(L"Destination string: %ls\n", dest);

return 0;
}

注意: 在使用 wmemcpy() 函数时,应该确保目标数组有足够的空间来存储源数组的内容,以免发生缓冲区溢出。在上面的示例中,我们使用 wcslen() 函数来获取源数组的长度,然后加上 1,以包括字符串结尾的空字符 '\0'

10.3 运行结果

11. wmemset

11.1 函数说明

函数声明 函数功能
wchar_t* wmemset(wchar_t* s, wchar_t c, size_t n); 用于将一个宽字符数组的前 n 个宽字符设置为给定的宽字符值

参数:

  • s : 一个指向宽字符数组的指针
  • c : 要设置的宽字符值
  • n : 要设置的字节数

11.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include <wchar.h>
#include <string.h>

int main()
{
wchar_t str[20]= L"Hello Huazie!";

// 修改前
wprintf(L"Before: %ls\n", str);

// 将一个宽字符数组的所有元素设置为给定的宽字符值X
wmemset(str, L'X', wcslen(str));

// 修改后
wprintf(L"After : %ls\n", str);

return 0;
}

在上面的示例程序中,

  • 首先,我们定义一个宽字符数组 str,并初始化为 "Hello Huazie!";
  • 接着,调用 wprintf() 函数输出修改之前的宽字符数组 str
  • 然后,调用 wmemset() 函数将宽字符数组 str 的所有元素都设置为 ‘X’;
  • 最后,再调用 wprintf() 函数输出修改之后的宽字符数组 str,并结束程序。

11.3 运行结果

12. wprintf

12.1 函数说明

函数声明 函数功能
int wprintf(const wchar_t* format, ...); 用于格式化输出宽字符字符串

参数:

  • format : 一个宽字符格式化字符串
  • … : 可选参数

12.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
#include <wchar.h>

int main()
{
wchar_t name[] = L"Huazie";
int age = 25;
double height = 1.75;

// 输出格式化的宽字符字符串
wprintf(L"%ls %d %.2f\n", name, age, height);

return 0;
}

12.3 运行结果

13. write

13.1 函数说明

函数声明 函数功能
ssize_t write(int fd, const void* buf, size_t count); 用于将数据写入文件描述符

参数:

  • fd : 要写入的文件描述符
  • buf: 写入数据的缓冲区
  • count: 写入的字节数

返回值:

  • 如果写入成功,则返回实际写入的字节数;
  • 如果出现错误,则返回 -1

13.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
#include <unistd.h>

int main()
{
const char msg[] = "Hello, Huazie!\n";
int nbytes;

// 向标准输出流写入数据
nbytes = write(STDOUT_FILENO, msg, sizeof(msg) - 1);

// 输出结果
if (nbytes == -1)
{
perror("write");
return 1;
}

return 0;
}

注意: 在使用 write() 函数时,应该确保给定的文件描述符是有效的,并且缓冲区中有足够的数据可供写入,以免发生未定义的行为

13.3 运行结果

14. wscanf

14.1 函数说明

函数声明 函数功能
int wscanf(const wchar_t* format, ...); 用于从标准输入流(stdin)读取格式化的宽字符输入

参数:

  • format : 一个宽字符格式化字符串
  • … : 可选参数

14.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
#include <wchar.h>

int main()
{
wchar_t name[20];
int age;

// 从标准输入流读取格式化的宽字符输入
wprintf(L"Please nput your name and age: ");
wscanf(L"%ls %d", name, &age);

// 输出结果
wprintf(L"name: %ls age: %d\n", name, age);

return 0;
}

14.3 运行结果

总览

函数声明 函数功能
wchar_t * wcscat(wchar_t *dest, const wchar_t *src); 用于将一个宽字符字符串追加到另一个宽字符字符串的末尾
wchar_t *wcschr(const wchar_t *str, wchar_t wc); 用于在宽字符串中查找指定字符的位置
int wcscmp(const wchar_t *str1, const wchar_t *str2); 用于比较两个宽字符串的大小;它将两个字符串逐个字符进行比较,直到遇到不同的字符或者其中一个字符串结束为止
int wcscoll(const wchar_t *str1, const wchar_t *str2); 用于比较两个宽字符串的大小
wchar_t *wcscpy(wchar_t *dest, const wchar_t *src); 用于将一个宽字符串复制到另一个字符串中
size_t wcsftime(wchar_t *str, size_t maxsize, const wchar_t *format, const struct tm *timeptr); 用于将日期和时间格式化为宽字符字符串
size_t wcslen(const wchar_t *str); 用于计算宽字符串的长度
wchar_t *wcsncat(wchar_t *dest, const wchar_t *src, size_t n); 用于将一个宽字符串的一部分追加到另一个宽字符串末尾
int wcsncmp(const wchar_t *str1, const wchar_t *str2, size_t n); 用于比较两个宽字符串的前若干个字符是否相同
wchar_t *wcsncpy(wchar_t *dest, const wchar_t *src, size_t n); 用于将一个宽字符串的一部分复制到另一个宽字符串中
size_t wcsrtombs(char *dest, const wchar_t **src, size_t n, mbstate_t *ps); 用于将宽字符串转换为多字节字符串
wchar_t *wcsstr(const wchar_t *haystack, const wchar_t *needle); 用于在一个宽字符串中查找另一个宽字符串
size_t wcsspn(const wchar_t *str, const wchar_t *accept); 用于查找宽字符串中连续包含某些字符集合中的字符的最长前缀
double wcstod(const wchar_t *nptr, wchar_t **endptr); 用于将宽字符串转换为双精度浮点数

1. wcscat

1.1 函数说明

函数声明 函数功能
wchar_t * wcscat(wchar_t *dest, const wchar_t *src); 用于将一个宽字符字符串追加到另一个宽字符字符串的末尾

参数:

  • dest : 目标字符串
  • src : 源字符串

1.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
#include <wchar.h>

int main() {
wchar_t dest[30] = L"Hello";
const wchar_t *src = L", Huazie!";

wcscat(dest, src);

wprintf(L"%ls\n", dest);

return 0;
}

在上面的示例代码中,

  • 首先,我们定义了一个大小为 30wchar_t 数组 dest,并初始化为 "Hello";
  • 然后,定义了一个指向常量宽字符串的指针 src,指向字符串 ", Huazie!"
  • 接着。调用 wcscat() 函数将 src 字符串中的所有字符追加到 dest 字符串的末尾,形成新的宽字符字符串 "Hello, Huazie!"
  • 最后,使用 wprintf() 函数将新的字符串输出到控制台。

注意: 在使用 wcscat() 函数时,需要确保目标字符串 dest 的空间足够大,以容纳源字符串 src 的所有字符和一个结束符(\0)。如果目标字符串的空间不足,可能会导致数据覆盖和未定义行为。

1.3 运行结果

2. wcschr

2.1 函数说明

函数声明 函数功能
wchar_t *wcschr(const wchar_t *str, wchar_t wc); 用于在宽字符串中查找指定字符的位置

参数:

  • str : 要查找的宽字符串
  • wc : 要查找的宽字符

返回值:

  • 如果在 str 字符串中查找到第一个与 wc 相等的宽字符,则返回该字符在字符串中的地址;
  • 否则没有找到匹配字符,则返回空指针。

2.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
#include <wchar.h>

int main()
{
const wchar_t *str = L"hello, huazie";
wchar_t c = L'u';

wchar_t *p = wcschr(str, c);

if (p != NULL)
printf("Found %lc at position %d.\n", c, p - str);
else
printf("%lc not found.\n", c);

return 0;
}

在上面的示例代码中,

  • 首先,我们定义了一个宽字符串 str,并初始化为 "hello, huazie"
  • 然后,定义了一个宽字符 c,值为 'u'
  • 接着调用 wcschr() 函数在 str 字符串中查找字符 c,并将返回结果保存在指针变量 p 中;
  • 最后,根据返回值判断是否找到了匹配字符,并输出相应的信息。

2.3 运行结果

3. wcscmp

3.1 函数说明

函数声明 函数功能
int wcscmp(const wchar_t *str1, const wchar_t *str2); 用于比较两个宽字符串的大小;它将两个字符串逐个字符进行比较,直到遇到不同的字符或者其中一个字符串结束为止

参数:

  • str1: 待比较的宽字符串1
  • str2: 待比较的宽字符串2

返回值:

  • 如果 str1 小于 str2,则返回一个负整数;
  • 如果 str1 等于 str2,则返回 0;
  • 如果 str1 大于 str2,则返回一个正整数。

3.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
#include <wchar.h>

int main()
{
const wchar_t *str1 = L"hello";
const wchar_t *str2 = L"huazie";

int result = wcscmp(str1, str2);

if (result < 0)
printf("%ls is less than %ls.\n", str1, str2);
else if (result == 0)
printf("%ls is equal to %ls.\n", str1, str2);
else
printf("%ls is greater than %ls.\n", str1, str2);

return 0;
}

在上述的示例代码中,

  • 首先,我们定义了两个宽字符串 str1str2,分别初始化为 "hello""huazie"
  • 然后,调用 wcscmp() 函数比较两个字符串的大小,并将返回结果保存在变量 result 中;
  • 接着根据 result 的值,输出相应的比较结果;
  • 最后结束程序。

3.3 运行结果

4. wcscoll

4.1 函数说明

函数声明 函数功能
int wcscoll(const wchar_t *str1, const wchar_t *str2); 用于比较两个宽字符串的大小

参数:

  • str1: 待比较的宽字符串1
  • str2: 待比较的宽字符串2

4.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <wchar.h>
#include <locale.h>

int main()
{
setlocale(LC_ALL, ""); // 设置本地化环境

const wchar_t *str1 = L"hello";
const wchar_t *str2 = L"huazie";

int result = wcscoll(str1, str2);

if (result < 0)
printf("%ls is less than %ls.\n", str1, str2);
else if (result == 0)
printf("%ls is equal to %ls.\n", str1, str2);
else
printf("%ls is greater than %ls.\n", str1, str2);

return 0;
}

在上述的示例代码中,

  • 首先,我们调用 setlocale() 函数设置本地化环境为当前系统默认设置;
  • 然后,定义了两个宽字符串 str1str2,分别初始化为 “hello” 和 “huazie”;
  • 接着,调用 wcscoll() 函数比较两个字符串的大小,并将返回结果保存在变量 result 中。
  • 最后根据 result 的值,输出相应的比较结果。

注意: 在使用 wcscoll() 函数比较宽字符串大小时,需要确保本地化环境正确设置,以便该函数能够正常工作。如果没有设置本地化环境或者设置错误,可能会导致比较结果不准确。

4.3 运行结果

5. wcscpy

5.1 函数说明

函数声明 函数功能
wchar_t *wcscpy(wchar_t *dest, const wchar_t *src); 用于将一个宽字符串复制到另一个字符串中

参数:

  • dest : 目标字符串
  • src : 源字符串

5.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
#include <wchar.h>

int main()
{
wchar_t dest[20];
const wchar_t *src = L"Hello, huazie!";

wcscpy(dest, src);

wprintf(L"%ls\n", dest);

return 0;
}

在上述的示例代码中,

  • 首先,我们定义了一个大小为 20wchar_t 数组 dest
  • 然后,定义了一个指向常量宽字符串的指针 src,指向字符串 “Hello, huazie!”;
  • 接着,调用 wcscpy() 函数将 src 字符串中的所有字符复制到 dest 字符串中,形成新的宽字符字符串 dest
  • 最后,使用 wprintf() 函数将新的字符串输出到控制台。

5.3 运行结果

6. wcsftime

6.1 函数说明

函数声明 函数功能
size_t wcsftime(wchar_t *str, size_t maxsize, const wchar_t *format, const struct tm *timeptr); 用于将日期和时间格式化为宽字符字符串

参数:

  • str : 输出结果的缓冲区
  • maxsize : 缓冲区的大小
  • format : 格式化字符串
  • timeptr : 包含日期和时间信息的结构体指针

6.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <wchar.h>
#include <time.h>

int main()
{
time_t current_time;
struct tm *time_info;
wchar_t buffer[80];

time(&current_time);
time_info = localtime(&current_time);

wcsftime(buffer, 80, L"%c", time_info);
wprintf(L"The current date and time is: %ls\n", buffer);

return 0;
}

在上面的示例代码中,

  • 首先,我们定义了一个变量 current_time 来存储当前时间,以及一个指向 struct tm 类型的指针 time_info
  • 然后,调用 time() 函数获取当前时间,并使用 localtime() 函数将时间转换为本地时间,存储在 time_info 指针变量中;
  • 接着,调用 wcsftime() 函数将日期和时间格式化为宽字符字符串,并存储到缓冲区 buffer 中;
  • 最后,使用 wprintf() 函数输出格式化后的字符串。

6.3 运行结果

7. wcslen

7.1 函数说明

函数声明 函数功能
size_t wcslen(const wchar_t *str); 用于计算宽字符串的长度

参数:

  • str : 要计算长度的宽字符串

7.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
#include <wchar.h>

int main()
{
const wchar_t *str = L"Hello, huazie!";
size_t len = wcslen(str);

wprintf(L"The length of '%ls' is %zu.\n", str, len);

return 0;
}

在上面的示例代码中,

  • 首先,我们定义了一个指向常量宽字符串的指针 str,指向字符串 "Hello, huazie!"
  • 然后,调用 wcslen() 函数计算 str 字符串的长度,并将结果保存在变量 len 中;
  • 最后,使用 wprintf() 函数输出字符串的长度。

7.3 运行结果

8. wcsncat

8.1 函数说明

函数声明 函数功能
wchar_t *wcsncat(wchar_t *dest, const wchar_t *src, size_t n); 用于将一个宽字符串的一部分追加到另一个宽字符串末尾

参数:

  • dest : 目标字符串
  • src : 源字符串
  • n : 要追加的字符数

8.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
#include <wchar.h>

int main()
{
wchar_t dest[20] = L"Hello, ";
const wchar_t *src = L"huazie!";
size_t n = 3;

wcsncat(dest, src, n);

wprintf(L"%ls\n", dest);

return 0;
}

在上述的示例代码中,

  • 首先,我们定义了一个大小为 20wchar_t 数组 dest,并初始化为 "Hello, "
  • 然后,定义了一个指向常量宽字符串的指针 src,指向字符串 "huazie!"
  • 接着,调用 wcsncat() 函数将 src 字符串中的前 3 个字符追加到 dest 字符串的末尾,形成新的宽字符字符串 dest
  • 最后,使用 wprintf() 函数将新的字符串输出到控制台。

8.3 运行结果

9. wcsncmp

9.1 函数说明

函数声明 函数功能
int wcsncmp(const wchar_t *str1, const wchar_t *str2, size_t n); 用于比较两个宽字符串的前若干个字符是否相同

参数:

  • str1 : 待比较的宽字符串1
  • str2 : 待比较的宽字符串2
  • n : 要比较的字符数

返回值:
将字符串 str1 和字符串 str2 中的前 n 个字符进行比较

  • 如果两个字符串相同,返回值为 0
  • 如果字符串 str1 在前 n 个字符中的第一个不同于字符串 str2 对应字符的字符大于字符串 str2 对应字符的字符,返回值为正数;
  • 如果字符串 str1 在前 n 个字符中的第一个不同于字符串 str2 对应字符的字符小于字符串 str2 对应字符的字符,返回值为负数。

9.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
#include <wchar.h>

int main()
{
const wchar_t *str1 = L"hello";
const wchar_t *str2 = L"huazie";
size_t n = 3;

int result = wcsncmp(str1, str2, n);

if (result < 0)
printf("%ls is less than %ls in the first %zu characters.\n", str1, str2, n);
else if (result == 0)
printf("%ls is equal to %ls in the first %zu characters.\n", str1, str2, n);
else
printf("%ls is greater than %ls in the first %zu characters.\n", str1, str2, n);

return 0;
}

9.3 运行结果

10. wcsncpy

10.1 函数说明

函数声明 函数功能
wchar_t *wcsncpy(wchar_t *dest, const wchar_t *src, size_t n); 用于将一个宽字符串的一部分复制到另一个宽字符串中

参数:

  • dest : 目标字符串
  • src : 源字符串
  • n : 要复制的字符数

10.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <wchar.h>

int main()
{
wchar_t dest[20];
const wchar_t *src = L"Hello, huazie!";
size_t n = 5;

wcsncpy(dest, src, n);
dest[n] = L'\0';

wprintf(L"%ls\n", dest);

return 0;
}

在上面的示例代码中,

  • 首先,我们定义了一个大小为 20wchar_t 数组 dest,以及一个指向常量宽字符串的指针 src,指向字符串 "Hello, huazie!"
  • 然后,调用 wcsncpy() 函数将 src 字符串中的前 5 个字符复制到 dest 字符串中,形成新的宽字符字符串 dest
  • 最后,手动添加空字符 \0 以确保字符串结束,并使用 wprintf() 函数将新的字符串输出到控制台。

10.3 运行结果

11. wcsrtombs

11.1 函数说明

函数声明 函数功能
size_t wcsrtombs(char *dest, const wchar_t **src, size_t n, mbstate_t *ps); 用于将宽字符串转换为多字节字符串

参数:

  • dest : 输出结果的缓冲区
  • src : 指向源字符串的指针
  • n : 要转换的最大字符数
  • ps : 一个指向转换状态的指针

11.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
#include <locale.h>

int main()
{
setlocale(LC_ALL, "");

const wchar_t *src = L"Hello, huazie!";
size_t n = wcslen(src) + 1;

char *dest = (char *) malloc(n * sizeof(char));

if (dest == NULL)
{
fprintf(stderr, "Memory allocation failed.\n");
return EXIT_FAILURE;
}

mbstate_t state = {0};

wcsrtombs(dest, &src, n, &state);

printf("%s\n", dest);

free(dest);

return 0;
}

在上面的示例代码中,

  • 首先,我们调用 setlocale() 函数设置程序的本地化环境,以便可以正确地进行宽字符和多字节字符之间的转换;
  • 然后,定义了一个指向常量宽字符串的指针 src,指向字符串 "Hello, huazie!"
  • 接着,根据源字符串的长度分配了足够大小的缓冲区 dest,并初始化为 0
  • 再然后,调用 wcsrtombs() 函数将宽字符串 src 转换为多字节字符串,并存储到缓冲区 dest 中;
  • 最后,使用 printf() 函数输出多字节字符串,并释放目标缓存区的内存。

注意: 在使用 wcsrtombs() 函数进行宽字符和多字节字符转换时,需要确保程序的本地化环境已经正确设置,否则可能会导致转换失败或者输出结果不正确。此外,在分配缓冲区 dest 的大小时,可以考虑将源字符串的长度加 1,以容纳字符串的结尾空字符(\0)。最后在使用完毕后要记得释放缓冲区的内存。

11.3 运行结果

12. wcsstr

12.1 函数说明

函数声明 函数功能
wchar_t *wcsstr(const wchar_t *haystack, const wchar_t *needle); 用于在一个宽字符串中查找另一个宽字符串

参数:

  • haystack : 要查找的宽字符串
  • needle : 要查找的子串

返回值:

  • 如果从 haystack 字符串中查找到第一个匹配 needle 子串的位置,则返回指向匹配位置的指针;
  • 否则未找到匹配的子串,返回空指针(NULL)。

12.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
#include <wchar.h>

int main()
{
const wchar_t *haystack = L"Hello, huazie!";
const wchar_t *needle = L"huazie";

wchar_t *result = wcsstr(haystack, needle);

if (result != NULL)
wprintf(L"The substring '%ls' was found at position %d.\n", needle, result - haystack);
else
wprintf(L"The substring '%ls' was not found in '%ls'.\n", needle, haystack);

return 0;
}

在上述的示例代码中,

  • 首先,我们定义了一个指向常量宽字符串的指针 haystack,指向字符串 "Hello, huazie!"
  • 然后,定义了一个指向常量宽字符串的指针 needle,指向字符串 "huazie"
  • 接着,调用 wcsstr() 函数在 haystack 字符串中查找子串 needle,并将结果指针保存在变量 result 中。
  • 最后,根据 result 的值,输出相应的查找结果。

注意: 在使用 wcsstr() 函数查找子串时,该函数会自动遍历整个字符串,直到找到匹配的子串或者结束字符串。如果要查找的子串在字符串中多次出现,该函数将返回第一次出现的位置,并不会考虑后续的匹配。

12.3 运行结果

13. wcsspn

13.1 函数说明

函数声明 函数功能
size_t wcsspn(const wchar_t *str, const wchar_t *accept); 用于查找宽字符串中连续包含某些字符集合中的字符的最长前缀

参数:

  • str : 要查找的宽字符串
  • accept : 一个包含要接受字符集合的宽字符串

13.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
#include <wchar.h>

int main()
{
const wchar_t *str = L"123456789a0";
const wchar_t *accept = L"0123456789";

size_t length = wcsspn(str, accept);

wprintf(L"The length of the prefix that contains digits is %zu.\n", length);

return 0;
}

在上述的示例代码中,

  • 首先,我们定义了一个指向常量宽字符串的指针 str,指向字符串 "123456789a0"
  • 然后,定义了一个指向常量宽字符串的指针 accept,指向字符串 "0123456789",表示数字字符的集合;
  • 接着,调用 wcsspn() 函数查找 str 字符串中连续包含数字字符集合中的字符的最长前缀,并将返回结果保存在变量 length 中。
  • 最后,根据 length 的值,调用 wprintf() 函数 输出 最长前缀的长度。

注意: 在使用 wcsspn() 函数查找宽字符串中的字符集合时,该函数会自动遍历整个字符串,直到找到第一个不在字符集合中的字符或者结束字符串。如果要查找的字符集合为空串,则返回 0

13.3 运行结果

14. wcstod

14.1 函数说明

函数声明 函数功能
double wcstod(const wchar_t *nptr, wchar_t **endptr); 用于将宽字符串转换为双精度浮点数

参数:

  • nptr : 要转换的宽字符串
  • endptr : 一个指向指针的指针,用于存储第一个无法解析的字符的位置

返回值:

  • 如果从 nptr 字符串中解析出一个双精度浮点数,则返回该数值;
  • 如果 nptr 字符串不包含有效的浮点数,则返回 0
  • 如果存在无法解析的字符,存储其位置到 endptr 指针中。

14.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
#include <wchar.h>

int main()
{
const wchar_t *str = L"3.14159265358979323846";
//const wchar_t *str = L"3.141592653589793a23846";
//const wchar_t *str = L"a3.14159265358979323846";
wchar_t *end;

double number = wcstod(str, &end);

if (end == str)
wprintf(L"No digits were found.\n");
else if (*end != L'\0')
wprintf(L"Invalid character at position %ld: '%lc'.\n", end - str, *end);
else
wprintf(L"The parsed number is %.20lf.\n", number);

return 0;
}

在上面的示例代码中,

  • 首先,我们定义了一个指向常量宽字符串的指针 str,指向字符串 "3.14159265358979323846"
  • 然后,调用 wcstod() 函数将字符串转换为双精度浮点数,并将结果保存在变量 number 中。
  • 最后,根据函数的返回结果 numberendptr 指针所指向的值,输出相应的转换结果。

注意: 在使用 wcstod() 函数转换宽字符串为双精度浮点数时,要确保字符串中只包含有效的浮点数表示,否则可能会导致转换错误或者未定义行为。

14.3 运行结果



总览

函数声明 函数功能
void va_start(va_list ap, last_arg); 用于初始化一个 va_list 类型的变量,使其指向可变参数列表中的第一个参数
type va_arg(va_list ap, type); 用于从可变参数列表中获取下一个参数,并将其转换为指定的类型
void va_copy(va_list dest, va_list src); 用于将一个 va_list 类型的变量复制到另一个变量中
void va_end(va_list ap); 用于清理一个 va_list 类型的变量
int vfprintf(FILE *stream, const char *format, va_list arg); 用于将格式化输出写入到指定的文件流中
int vfscanf(FILE *stream, const char *format, va_list arg); 用于将指定文件流中的格式化输入读取到指定变量中
int vprintf(const char *format, va_list ap); 它使用格式化字符串 format 中的指令来指定输出的格式,并将后续的可变参数按照指令指定的格式输出到标准输出流 stdout
int vscanf(const char *format, va_list arg); 它使用格式化字符串 format 中的指令来指定输入的格式,并从标准输入流 stdin 中读取数据,并将数据按照指令指定的格式存储到相应的变量中
int vsprintf(char *str, const char *format, va_list ap); 它使用格式化字符串 format 中的指令来指定输出的格式,并将后续的可变参数按照指令指定的格式输出到字符数组 str 中。
int vsscanf(const char *str, const char *format, va_list ap); 它使用格式化字符串 format 中的指令来指定输入的格式,并从字符数组 str 中读取数据,并将数据按照指令指定的格式存储到相应的变量中

1. va_start

1.1 函数说明

函数声明 函数功能
void va_start(va_list ap, last_arg); 用于初始化一个 va_list 类型的变量,使其指向可变参数列表中的第一个参数

参数:

  • ap: 一个指向 va_list 类型的变量的指针,表示要初始化的可变参数列表
  • last_arg: 一个指向最后一个固定参数的指针,用于确定可变参数列表的起始位置

1.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <stdio.h>
#include <stdarg.h>

void print_args(int count, ...)
{
va_list args1, args2;
int i;

va_start(args1, count); /* 初始化可变参数列表 */

/* 复制可变参数列表 */
va_copy(args2, args1);

for (i = 0; i < count; i++)
{
int arg1 = va_arg(args1, int); /* 获取下一个参数 */
int arg2 = va_arg(args2, int);
printf("arg[%d] = %d %d\n", i, arg1, arg2);
}

va_end(args2); /* 清理复制的可变参数列表 */
va_end(args1); /* 清理原始可变参数列表 */
}

int main()
{
print_args(3, 10, 20, 30);
return 0;
}

在上面的示例代码中,

  • 我们首先调用自定义的 print_args() 函数,并传入了 4 个入参,第一个为 可变参数的个数,后面三个为具体的整数型可变参数。
  • 然后在print_args() 函数内部,我们首先定义了两个 va_list 类型的变量 args1args2,并使用 va_start() 函数初始化 args1 变量。
  • 接着,我们使用 va_copy() 函数将 args1 复制到 args2 中,并使用 for 循环和 两个 va_arg() 函数来分别访问这两个可变参数列表,并依次输出每个参数的值。
  • 最后,我们使用两次 va_end() 函数来清理这两个可变参数列表。

1.3 运行结果

2. va_arg

2.1 函数说明

函数声明 函数功能
type va_arg(va_list ap, type); 用于从可变参数列表中获取下一个参数,并将其转换为指定的类型

参数:

  • ap : 一个指向 va_list 类型的变量的指针,表示要访问的可变参数列表
  • type : 一个类型说明符,表示下一个参数的类型

2.2 演示示例

可参考 1.2 中所示

3. va_copy

3.1 函数说明

函数声明 函数功能
void va_copy(va_list dest, va_list src); 用于将一个 va_list 类型的变量复制到另一个变量中

参数:

  • dest : 一个指向 va_list 类型的变量的指针,表示目标可变参数列表
  • src : 另一个指向 va_list 类型的变量的指针,表示要被复制的可变参数列表

3.2 演示示例

可参考 1.2 中所示

4. va_end

4.1 函数说明

函数声明 函数功能
void va_end(va_list ap); 用于清理一个 va_list 类型的变量

参数:

  • ap: 一个指向 va_list 类型的变量的指针,表示要清理的可变参数列表

4.2 演示示例

可参考 1.2 中所示

5. vfprintf

5.1 函数说明

函数声明 函数功能
int vfprintf(FILE *stream, const char *format, va_list arg); 用于将格式化输出写入到指定的文件流中

参数:

  • stream : 要写入数据的文件流指针
  • format : 格式化字符串,用来指定要输出的内容和格式
  • arg : 一个 va_list 类型的变量,包含了可变参数列表

5.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

FILE *fp;

int vfpf(const char *fmt, ...)
{
va_list argptr;
int cnt;

va_start(argptr, fmt);
cnt = vfprintf(fp, fmt, argptr);
va_end(argptr);

return cnt;
}

int main()
{
int inumber;
float fnumber;
char string[4];

fp = tmpfile();
if (fp == NULL)
{
perror("tmpfile() call");
exit(1);
}

vfpf("%d %f %s", 30, 90.0, "abc");

rewind(fp);

fscanf(fp,"%d %f %s", &inumber, &fnumber, string);

printf("%d %.2f %s\n", inumber, fnumber, string);

fclose(fp);

return 0;
}

在上述的示例代码中,

  • 我们首先声明了三个变量 inumberfnumberstring
  • 然后,调用 tmpfile() 函数创建一个临时文件,并将返回的文件指针赋值给全局变量 fp。如果创建文件失败,则打印错误信息并退出程序;
  • 接着,调用自定义的 vfpf() 函数来向临时文件中写入数据。它里面使用 vfprintf() 函数将格式化输出写入到一个文件流中;
  • 再然后,调用 rewind() 函数将文件指针重新定位到文件开头;
  • 再接着使用 fscanf() 函数从文件中读取数据,并使用 printf() 函数中输出从文件中读取的数据【其中浮点数部分保留两位小数】
  • 最后调用 fclose() 函数关闭文件指针,并结束程序

5.3 运行结果

6. vfscanf

6.1 函数说明

函数声明 函数功能
int vfscanf(FILE *stream, const char *format, va_list arg); 用于将指定文件流中的格式化输入读取到指定变量中

参数:

  • stream : 要读取数据的文件流指针
  • format : 格式化字符串,用来指定要读取的内容和格式
  • arg : 一个 va_list 类型的变量,包含了可变参数列表

返回值:

  • 如果读取成功,返回成功读取并赋值给变量的项目数;
  • 如果出现错误,则返回负数。

6.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

FILE *fp;

int vfsf(const char *fmt, ...) {
va_list argptr;
int cnt;

va_start(argptr, fmt);
cnt = vfscanf(fp, fmt, argptr);
va_end(argptr);

return cnt;
}

int main()
{
int inumber;
float fnumber;
char string[4];

fp = tmpfile();
if (fp == NULL)
{
perror("tmpfile() call");
exit(1);
}

fprintf(fp, "%d %f %s", 30, 90.0, "abc");

rewind(fp);

vfsf("%d %f %s", &inumber, &fnumber, string);

printf("%d %.2f %s\n", inumber, fnumber, string);

fclose(fp);

return 0;
}

在上面的示例代码中,

  • 我们首先声明了三个变量 inumberfnumberstring
  • 然后,程序调用 tmpfile() 函数创建一个临时文件,并将返回的文件指针赋值给全局变量 fp。如果创建文件失败,则打印错误信息并退出程序;
  • 接着,我们使用 fprintf() 函数将三个数据(一个整型数字、一个浮点数和一个字符串)写入该文件中;
  • 再然后,调用 rewind() 函数将文件指针重新定位到文件开头;
  • 再接着,我们调用自定义的 vfsf() 函数,里面使用 vfscanf() 函数从文件中读取数据;
  • 最后,打印出从文件中读取的数据,并关闭临时文件,退出程序。

6.3 运行结果

7. vprintf

7.1 函数说明

函数声明 函数功能
int vprintf(const char *format, va_list ap); 它使用格式化字符串 format 中的指令来指定输出的格式,并将后续的可变参数按照指令指定的格式输出到标准输出流 stdout

参数:

  • format : 格式化字符串,用来指定要打印的内容和格式
  • va_list : 一个 va_list 类型的变量,包含了可变参数列表

7.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
#include <stdarg.h>

void myprint(const char *format, ...)
{
va_list args;
va_start(args, format);
vprintf(format, args);
va_end(args);
}

int main()
{
int a = 10;
float b = 3.14;
char s[] = "hello";

myprint("a=%d, b=%.2f, s=%s\n", a, b, s);
return 0;
}

在上面的示例代码中,

  • 我们首先定义了三个变量 整形 a 、浮点型 b 和 字符数组 s
  • 然后,调用自定义的 myprint() 函数将这些变量的值输出到标准输出流 stdout 中;
    myprint() 函数中,
    • 我们首先使用 va_start() 宏初始化一个 va_list 变量 args
    • 然后调用 vprintf() 函数将格式化字符串和参数列表传递给该函数进行输出;
    • 最后使用 va_end() 宏清理 args 变量。
  • 最后结束程序。

7.3 运行结果

8. vscanf

8.1 函数说明

函数声明 函数功能
int vscanf(const char *format, va_list arg); 它使用格式化字符串 format 中的指令来指定输入的格式,并从标准输入流 stdin 中读取数据,并将数据按照指令指定的格式存储到相应的变量中

参数:

  • format : 格式化字符串,用来指定要读取的内容和格式
  • va_list : 一个 va_list 类型的变量,包含了可变参数列表

8.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
#include <stdarg.h>

void myscan(const char *format, ...)
{
va_list args;
va_start(args, format);
vscanf(format, args);
va_end(args);
}

int main()
{
int a;
float b;
char s[10];

myscan("%d%f%s", &a, &b, s);
printf("a=%d, b=%.2f, s=%s\n", a, b, s);
return 0;
}

在上面的示例代码中,

  • 我们首先定义了三个变量 整形 a 、浮点型 b 和 字符数组 s
  • 然后,调用自定义的 myscan() 函数从标准输入流 stdin 中读取数据,并将数据存储到这些变量中
    myscan() 函数中,
    • 我们首先使用 va_start() 宏初始化一个 va_list 变量 args
    • 然后调用 vscanf() 函数将格式化字符串和参数列表传递给该函数进行输入;
    • 最后使用 va_end() 宏清理 args 变量。
  • 最后我们打印输出上面输入的两个变量的数据,并结束程序。

8.3 运行结果

9. vsprintf

9.1 函数说明

函数声明 函数功能
int vsprintf(char *str, const char *format, va_list ap); 它使用格式化字符串 format 中的指令来指定输出的格式,并将后续的可变参数按照指令指定的格式输出到字符数组 str 中。

参数:

  • str: 用来存储格式化数据的字符数组的指针
  • format : 格式化字符串,用来指定要输出的内容和格式
  • va_list : 一个 va_list 类型的变量,包含了可变参数列表

9.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <stdarg.h>

void myprint(const char *format, ...)
{
char buffer[100];
va_list args;
va_start(args, format);
vsprintf(buffer, format, args);
va_end(args);
printf("%s", buffer);
}

int main()
{
int a = 10;
float b = 3.1415;
char s[] = "huazie";

myprint("a=%d, b=%.4f, s=%s\n", a, b, s);
return 0;
}

在上面的示例代码中,

  • 我们首先定义了三个变量 整形 a 、浮点型 b 和 字符数组 s
  • 然后,调用自定义的 myprint() 函数将格式化字符串和这些变量的值输出到字符数组 buffer 中,并打印输出字符数组 buffer
    myprint() 函数中,
    • 我们首先使用 va_start() 宏初始化一个 va_list 变量 args
    • 然后调用 vsprintf() 函数将格式化字符串和参数列表传递给该函数进行输出,并将输出结果存储到 buffer 数组中;
    • 最后使用 va_end() 宏清理 args 变量。
  • 最后结束程序。

9.3 运行结果

10. vsscanf

10.1 函数说明

函数声明 函数功能
int vsscanf(const char *str, const char *format, va_list ap); 它使用格式化字符串 format 中的指令来指定输入的格式,并从字符数组 str 中读取数据,并将数据按照指令指定的格式存储到相应的变量中

参数:

  • str: 用来读取的格式化数据的字符数组的指针
  • format : 格式化字符串,用来指定要读取的内容和格式
  • va_list : 一个 va_list 类型的变量,包含了可变参数列表

10.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <stdarg.h>

void myscan(const char *str, const char *format, ...)
{
va_list args;
va_start(args, format);
vsscanf(str, format, args);
va_end(args);
}

int main()
{
int a;
float b;
char s[10];
char buffer[] = "10 3.1415 huazie";

myscan(buffer, "%d%f%s", &a, &b, s);
printf("a=%d, b=%.4f, s=%s\n", a, b, s);
return 0;
}

在上面的示例代码中,

  • 我们首先定义了四个变量 整形 a 、浮点型 b 、 字符数组 s 和 字符数组 buffer
  • 然后,调用自定义的 myscan() 函数从字符数组 buffer 中读取数据,并将数据存储到另外 3 个变量中;
    myscan() 函数中,
    • 我们首先使用 va_start() 宏初始化一个 va_list 变量 args
    • 然后调用 vsscanf() 函数将字符数组 buffer 和格式化字符串以及参数列表传递给该函数进行输入,并将数据存储到相应的变量中;
    • 最后使用 va_end() 宏清理 args 变量。
  • 最后我们打印输出上面从字符数组 buffer 中读取并输入的三个变量的数据,并结束程序。

10.3 运行结果

参考

  1. [API Reference Document]

总览

函数声明 函数功能
char *ultoa(unsigned long value, char *str, int base); 用于将无符号长整型数转换成指定基数下的字符串表示
int ungetc(int c, FILE *stream); 用于将字符推回输入流中
int ungetch(int c); 用于将字符推回输入流中
int unix2dos(const char *src_file, const char *dst_file); 用于将文本文件的行末标志符从 Unix 风格的 \n 转换为 Windows/DOS 风格的 \r\n
int dos2unix(const char *src_file, const char *dst_file); 用于将将文本文件的行末标志符从 Windows/DOS 风格的 \r\n 转换为 Unix 风格的 \n
int unlink(const char *pathname); 用于删除指定文件
int unlock(int handle, long offset, long length); 它不是标准 C 库中的函数,而是 Linux/Unix 系统下用于文件锁定和解锁的函数
BOOL UnlockFile(HANDLE hFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh, DWORD nNumberOfBytesToUnlockLow, DWORD nNumberOfBytesToUnlockHigh); 用于对文件进行解锁操作

1. ultoa

1.1 函数说明

函数声明 函数功能
char *ultoa(unsigned long value, char *str, int base); 用于将无符号长整型数转换成指定基数下的字符串表示

参数:

  • value : 要转换的无符号长整型数
  • str : 用于存储转换后的字符串
  • base : 要使用的进制数,可以为 2、8、10 或 16

函数 ultoa() 将参数 value 转换为以 base 进制表示的形式,并将结果存储在缓冲区 str 中。如果转换成功,则返回指向 str 的指针。

注意: 函数 ultoa() 不会检查缓冲区是否足够大,因此调用者需要确保缓冲区足够大以避免发生缓冲区溢出。

1.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
#include <stdlib.h>

int main()
{
unsigned long num = 0xDEADBEEF;
char str[20];

_ultoa(num, str, 16);

printf("The hexadecimal representation of %lu is %s\n", num, str);

return 0;
}

1.3 运行结果

2. ungetc

2.1 函数说明

函数声明 函数功能
int ungetc(int c, FILE *stream); 用于将字符推回输入流中

参数:

  • c : 要推回的字符
  • stream : 要推回字符的文件指针

2.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <stdio.h>

//int ungetc(int c, FILE *stream);

int main()
{
int c;
FILE *fp = fopen("test.txt", "r");

if (fp == NULL)
{
printf("Failed to open file\n");
return 1;
}

// 读取一个字符
c = fgetc(fp);

if (c == EOF)
{
printf("Failed to read character\n");
return 1;
}

printf("Read character: %c\n", c);

// 推回字符到输入流中
if (ungetc(c, fp) == EOF)
{
printf("Failed to unget character\n");
return 1;
}

// 再次读取字符
c = fgetc(fp);

if (c == EOF)
{
printf("Failed to read character\n");
return 1;
}

printf("Read character again: %c\n", c);

fclose(fp);
return 0;
}

在上面的示例代码中,

  • 我们首先打开了一个名为 test.txt 的文本文件;
  • 接着,使用 fgetc() 函数从中读取一个字符;
  • 然后,我们使用 ungetc() 函数将该字符推回输入流中;
  • 再接着使用 fgetc() 函数从输入流中读取字符;
  • 最后,我们使用 printf() 函数将两次读取的字符打印到标准输出流中。

注意: 在使用 ungetc() 函数推回字符之前,必须先读取一个字符并检查其是否成功读取。否则,ungetc() 函数将无法确定将字符推回哪个位置。

2.3 运行结果

3. ungetch

3.1 函数说明

函数声明 函数功能
int ungetch(int c); 用于将字符推回输入流中

参数:

  • c : 要推回的字符

3.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
#include <ctype.h>
#include <conio.h>

int main()
{
int i=0;
char ch;

puts("Input an integer followed by a char:");

while((ch = getche()) != EOF && isdigit(ch))
i = 10 * i + ch - 48;

if (ch != EOF)
ungetch(ch);

printf("\n\ni = %d, next char in buffer = %c\n", i, getch());
return 0;
}

在上述的示例代码中,

  • 我们首先输出一条提示信息 "Input an integer followed by a char:"
  • 接着,通过循环调用 getche() 函数从输入流中逐个读取字符,并检查它是否是数字字符。如果是数字字符,则将其转换为整数并存储在变量 i 中。
  • 然后,在读取到非数字字符时,使用 ungetch() 函数将该字符推回输入流中,以保留它供后续使用。
  • 最后,使用 getch() 函数从输入流中读取一个字符,并打印出读取到的下一个字符和此时 i 的值。

注意: getch()ungetch() 函数通常只在 Windows 平台上可用,因此这段代码可能不可移植到其他操作系统或编译器中。

3.3 运行结果

4. unix2dos

4.1 函数说明

函数声明 函数功能
int unix2dos(const char *src_file, const char *dst_file); 用于将文本文件的行末标志符从 Unix 风格的 \n 转换为 Windows/DOS 风格的 \r\n
int dos2unix(const char *src_file, const char *dst_file); 用于将将文本文件的行末标志符从 Windows/DOS 风格的 \r\n 转换为 Unix 风格的 \n

参数:

  • src_file : 要转换的源文件名
  • dst_file : 转换后保存到的目标文件名

返回值:

  • 如果转换成功,则返回 0
  • 否则返回一个 非零值, 表示错误代码。

4.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include <stdio.h>
#include <stdlib.h>

int unix2dos(const char *src_file, const char *dst_file);
int dos2unix(const char *src_file, const char *dst_file);

int main()
{
int status;

// 将 Unix 格式的文件转换为 DOS 格式
status = unix2dos("input_unix.txt", "output_dos.txt");
if (status != 0)
{
printf("Failed to convert file: %d\n", status);
return 1;
}

// 将 DOS 格式的文件转换为 Unix 格式
status = dos2unix("input_dos.txt", "output_unix.txt");
if (status != 0)
{
printf("Failed to convert file: %d\n", status);
return 1;
}

printf("File conversion successful\n");
return 0;
}

int unix2dos(const char *src_file, const char *dst_file)
{
FILE *in = fopen(src_file, "r");
FILE *out = fopen(dst_file, "w");

if (in == NULL || out == NULL)
return -1;

int c;

while ((c = fgetc(in)) != EOF)
{
if (c == '\n')
fputc('\r', out);
fputc(c, out);
}

fclose(in);
fclose(out);

return 0;
}

int dos2unix(const char *src_file, const char *dst_file)
{
FILE *in = fopen(src_file, "r");
FILE *out = fopen(dst_file, "w");

if (in == NULL || out == NULL)
return -1;

int c;
int prev = -1;

while ((c = fgetc(in)) != EOF)
{
if (prev == '\r' && c == '\n')
{
// skip CR character
prev = c;
continue;
}
fputc(c, out);
prev = c;
}

fclose(in);
fclose(out);

return 0;
}

5. unlink

5.1 函数说明

函数声明 函数功能
int unlink(const char *pathname); 用于删除指定文件

参数:

  • pathname : 要删除的文件路径名

5.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <stdlib.h>

int main()
{
int status;

// 删除指定文件
status = unlink("huazie.txt");
if (status != 0)
{
printf("Failed to delete file: %d\n", status);
return 1;
}

printf("File deletion successful\n");
return 0;
}

在上面的示例代码中,我们使用 unlink() 函数删除了当前目录下名为 huazie.txt 的文件。如果 unlink() 函数返回值不为 0,则说明删除操作失败,可能是由于权限不足、文件不存在或其他原因导致的。如果删除操作成功,则会输出一条简短的提示信息 "File deletion successful"

注意: 由于删除操作无法撤销,并且被删除的文件内容将无法恢复,因此在使用 unlink() 函数删除文件时需要小心谨慎,建议在执行此类敏感操作之前进行备份或确认。

5.3 运行结果

6. unlock

6.1 函数说明

函数声明 函数功能
int unlock(int handle, long offset, long length); 它不是标准 C 库中的函数,而是 Linux/Unix 系统下用于文件锁定和解锁的函数

参数:

  • handle : 要解锁的文件句柄
  • offset: 解锁操作的起始偏移量(以字节为单位)。通常情况下,偏移量应该为正整数,代表从文件开头开始的偏移量。如果 offset 参数小于零,则将从文件末尾开始向前计算偏移量。
  • length: 要解锁的字节数

6.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <io.h>
#include <fcntl.h>
#include <sys\stat.h>
#include <process.h>
#include <share.h>
#include <stdio.h>
#include <sys\locking.h>

int main(void)
{
int handle, status;
long length;
// 打开名为 test.txt 的文件
handle = sopen("test.txt",O_RDONLY,SH_DENYNO,S_IREAD);

if (handle < 0)
{
printf("sopen failed\n");
exit(1);
}
// 获取文件长度
length = filelength(handle);
// 锁定上面打开的文件
status = lock(handle,0L,length/2);
// 检查锁定操作是否成功,返回0,表示成功,返回非0,则加锁失败
if (status == 0)
printf("lock succeeded\n");
else
printf("lock failed\n");
// 对上面锁定的文件进行解除锁定
status = unlock(handle,0L,length/2);
// 检查解除锁定操作是否成功,返回0,表示成功,返回非0,则解锁失败
if (status == 0)
printf("unlock succeeded\n");
else
printf("unlock failed\n");
// 关闭文件句柄
close(handle);
return 0;
}

7. UnlockFile

7.1 函数说明

函数声明 函数功能
BOOL UnlockFile(HANDLE hFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh, DWORD nNumberOfBytesToUnlockLow, DWORD nNumberOfBytesToUnlockHigh); 用于对文件进行解锁操作

参数:

  • hFile : 要解锁的文件句柄
  • dwFileOffsetLow 和 dwFileOffsetHigh: 解锁操作的起始偏移量(以字节为单位)。由于文件大小可能超过 4GB,因此需要使用两个参数表示完整的偏移量
  • nNumberOfBytesToUnlockLow 和 nNumberOfBytesToUnlockHigh: 要解锁的字节数。同样地,这些参数也需要使用两个参数表示完整的字节数

7.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <windows.h>
#include <stdio.h>

int main() {
HANDLE file_handle;
DWORD bytes_written;
OVERLAPPED overlapped = {0};
DWORD offset = 0;
DWORD length = 0;
BOOL status;

// 打开指定文件并获取文件句柄
file_handle = CreateFile("test.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
if (file_handle == INVALID_HANDLE_VALUE)
{
printf("Failed to open file\n");
return 1;
}

// 将字符串写入文件
const char *data = "Hello, world!";
status = WriteFile(file_handle, data, strlen(data), &bytes_written, &overlapped);
if (!status)
{
printf("Failed to write to file\n");
CloseHandle(file_handle);
return 1;
}

// 锁定文件的前半部分
length = GetFileSize(file_handle, NULL) / 2;
status = LockFile(file_handle, offset, 0, length, 0);
if (!status)
{
printf("Failed to lock file\n");
CloseHandle(file_handle);
return 1;
}

printf("File locked successfully\n");

// 解锁文件的前半部分
status = UnlockFile(file_handle, offset, 0, length, 0);
if (!status)
printf("Failed to unlock file\n");
else
printf("File unlocked successfully\n");

// 关闭文件句柄并返回
CloseHandle(file_handle);
return 0;
}

在上面的示例代码中,

  • 我们首先使用 Windows API 中的 CreateFile() 函数打开名为 test.txt 的文件,并获取其文件句柄;
  • 然后,我们使用 WriteFile() 函数将字符串写入文件;
  • 接着,我们使用 LockFile() 函数对文件进行锁定操作,并使用 UnlockFile() 函数进行解锁操作;
  • 最后,我们关闭文件句柄并退出程序。

注意:在使用 UnlockFile() 函数时,需要确保已经使用 CreateFile() 或其他文件打开函数打开了文件,并获得了有效的文件句柄。

7.3 运行结果

参考

  1. [API Reference Document]
  2. [LockFile function]

总览

函数声明 函数功能
double tan(double x) 计算 以弧度 x 为单位的角度的正切值(double)
float tanf(float x) 计算 以弧度 x 为单位的角度的正切值(float)
long double tanl(long double x) 计算 以弧度 x 为单位的角度的正切值(long double)
double tanh(double x); 计算 x 的双曲正切值(double)
float tanhf(float x); 计算 x 的双曲正切值(float)
long double tanhl(long double x); 计算 x 的双曲正切值(long double)
off_t tell(int fd); 用于返回文件指针当前位置相对于文件开头的偏移量
long int telldir(DIR *dirp); 获取目录流的当前位置
int textheight(char *string); 用于获取当前文本模式下字符的高度
int textwidth(char *string); 用于获取当前文本模式下字符的宽度
time_t time(time_t *timer); 可以用于获取从 1970 年 1 月 1 日 00:00:00 UTC 到当前时间的秒数
FILE *tmpfile(void); 可以用于在临时目录中创建一个唯一的临时文件,并返回文件指针
char *tmpnam(char *s); 用于创建一个唯一的临时文件名
int toascii(int c); 将一个字符转换为其对应的 ASCII 码值
int tolower(int c); 可以用于将一个 ASCII 字符转换为小写字母
int toupper(int c); 可以用于将一个 ASCII 字符转换为大写字母
double trunc(double x); 截取 x 的小数部分,并返回整数部分(double)
float truncf(float x); 截取 x 的小数部分,并返回整数部分(float)
long double truncl(long double x); 截取 x 的小数部分,并返回整数部分(long double)
void tzset(void); 可以用于设置时区信息
double tgamma(double x); 用于计算 Gamma 函数(double)
float tgammaf(float x); 用于计算 Gamma 函数(float)
long double tgammal(long double x); 用于计算 Gamma 函数(long double)

1. tan,tanf,tanl

1.1 函数说明

函数声明 函数功能
double tan(double x) 计算 以弧度 x 为单位的角度的正切值(double)
float tanf(float x) 计算 以弧度 x 为单位的角度的正切值(float)
long double tanl(long double x) 计算 以弧度 x 为单位的角度的正切值(long double)

1.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <math.h>

int main()
{
double x = 45.0;
double tan_value = tan(x * M_PI / 180.0);
printf("The tangent of %lf degrees is %lf\n", x, tan_value);

float xf = 60.0f;
float tan_valuef = tanf(xf * M_PI / 180.0f);
printf("The tangent of %f degrees is %f\n", xf, tan_valuef);

long double xL = 30.0l;
long double tan_valueL = tanl(xL * M_PI / 180.0l);
printf("The tangent of %Lf degrees is %Lf\n", xL, tan_valueL);
return 0;
}

1.3 运行结果

2. tanh,tanhf,tanhl

2.1 函数说明

函数声明 函数功能
double tanh(double x); 计算 x 的双曲正切值(double)
float tanhf(float x); 计算 x 的双曲正切值(float)
long double tanhl(long double x); 计算 x 的双曲正切值(long double)

2.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include <math.h>

int main()
{
double x = 1.0;
double tan_value = tanh(x);
printf("%lf 的双曲正切值是 %lf\n", x, tan_value);

float y = 2.0f;
float tanh_value = tanhf(y);
printf("%f 的双曲正切值是 %f\n", y, tanh_value);

long double z = 3.0l;
long double tanhl_value = tanhl(z);
printf("%Lf 的双曲正切值是 %Lf\n", z, tanhl_value);

return 0;
}

2.3 运行结果

3. tell

3.1 函数说明

函数声明 函数功能
off_t tell(int fd); 用于返回文件指针当前位置相对于文件开头的偏移量

参数:

  • fd : 是文件描述符,表示要查询的文件

3.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

int main()
{
char buf[100];
int fd = open("test.txt", O_RDONLY);
off_t offset = tell(fd);
printf("当前的文件偏移量是 %ld\n", offset);

int nread = read(fd, buf, sizeof(buf));
offset = tell(fd);
printf("读取了 %d 个字节后,文件偏移量是 %ld\n", nread, offset);

close(fd);
return 0;
}

在上面这个示例中,

  • 首先我们打开了一个名为 test.txt 的文件,并使用 tell() 函数获取了当前的文件偏移量。
  • 然后我们用 read() 函数读取了一些数据,并再次使用 tell() 函数来获取新的文件偏移量。
  • 最后我们使用 close() 函数关闭文件。

注意:tell() 函数和 lseek 函数的功能类似,但有一个重要的区别:tell() 函数只用于查询当前位置,而不能修改文件指针的位置。如果要修改文件指针的位置,请使用 lseek() 函数。

下面我们来看看,使用 lseek() 函数来演示上面的 tell() 函数的示例 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

int main()
{
char buf[100];
int fd = open("test.txt", O_RDONLY);
off_t offset = lseek(fd, 0, SEEK_CUR);
printf("当前的文件偏移量是 %ld\n", offset);

int nread = read(fd, buf, sizeof(buf));
offset = lseek(fd, 0, SEEK_CUR);
printf("读取了 %d 个字节后,文件偏移量是 %ld\n", nread, offset);

close(fd);
return 0;
}

3.3 运行结果


4. telldir

4.1 函数说明

函数声明 函数功能
long int telldir(DIR *dirp); 获取目录流的当前位置

参数:

  • dirp : 指向 DIR 类型结构体的指针

4.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
#include <dirent.h>

int main()
{
DIR *dirp;
struct dirent *direntp;

// 打开当前工作目录
dirp = opendir(".");

if (dirp == NULL)
{
printf("无法打开目录。\n");
return 1;
}

// 遍历目录下的所有文件和子目录
while ((direntp = readdir(dirp)) != NULL)
{
printf("%s\n", direntp->d_name);
}

closedir(dirp);

return 0;
}

4.3 运行结果

5. textheight,textwidth

5.1 函数说明

函数声明 函数功能
int textheight(char *string); 用于获取当前文本模式下字符的高度
int textwidth(char *string); 用于获取当前文本模式下字符的宽度

参数:

  • string : 要查询的字符串

5.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <graphics.h>

int main() {
initwindow(640, 480, "Example");
char str[] = "Hello, world!";
int height = textheight(str); // 当前文本模式下字符的高度
int width = textwidth(str); // 当前文本模式下字符的宽度
outtextxy(100, 100, str);
outtextxy(100, 120, "Height: ");
outtextxy(170, 120, itoa(height, str, 10));
outtextxy(100, 140, "Width: ");
outtextxy(170, 140, itoa(width, str, 10));
getch();
closegraph();
return 0;
}

5.3 运行结果

6. time

6.1 函数说明

函数声明 函数功能
time_t time(time_t *timer); 可以用于获取从 1970 年 1 月 1 日 00:00:00 UTC 到当前时间的秒数

参数:

  • timer : 一个指向 time_t 类型对象的指针,如果不想使用此参数,可以将它设置为 NULL

6.2 演示示例

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
#include <time.h>

int main()
{
time_t curtime;
time(&curtime);
printf("当前时间是 %s", ctime(&curtime));
return 0;
}

在上面的示例中,

  • 首先我们使用 time() 函数来获取当前时间的秒数;
  • 然后使用 ctime() 函数将其转换为可读的日期和时间格式;
  • 最后,再用将日期和时间字符串输出到标准输出流中。

6.3 运行结果

7. tmpfile

7.1 函数说明

函数声明 函数功能
FILE *tmpfile(void); 可以用于在临时目录中创建一个唯一的临时文件,并返回文件指针

7.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>

int main()
{
FILE *fp;
char str[60];

fp = tmpfile();
if (fp == NULL)
{
perror("打开临时文件失败");
return 1;
}

fputs("这是一个临时文件", fp);
rewind(fp);
fgets(str, sizeof(str), fp);
printf("从临时文件读取的内容是: %s", str);

fclose(fp);
return 0;
}

在上述的示例中,

  • 首先我们使用 tmpfile() 函数创建一个临时文件;
  • 接着使用 fputs() 函数将字符串 "这是一个临时文件" 写入该文件;
  • 然后,我们使用 rewind() 函数将文件指针移动到文件开始处;
  • 再接着,使用 fgets() 函数从临时文件中读取数据并将其存储到字符串数组 str 中;
  • 最后,我们输出从临时文件中读取的数据,并关闭临时文件。

注意: 使用 tmpfile() 创建的临时文件只在程序运行期间存在,并在程序终止时自动删除。如果需要在程序运行期间保留临时文件,请使用 tmpnam()mkstemp() 等函数来创建文件。

7.3 运行结果

8. tmpnam

8.1 函数说明

函数声明 函数功能
char *tmpnam(char *s); 用于创建一个唯一的临时文件名

参数:

  • s : 一个指向字符数组的指针,用于存储临时文件名。如果 s 等于 NULL,则函数会返回指向静态内存区的指针,该内存区包含了唯一的临时文件名

8.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>

int main()
{
char tmpname[L_tmpnam];
char *filename;

filename = tmpnam(tmpname);
printf("临时文件名是:%s\n", filename);

return 0;
}

在上面的示例中,

  • 我们首先使用 tmpnam() 函数创建一个唯一的临时文件名;
  • 然后将其存储到字符数组 tmpname 中;
  • 最后,我们输出该临时文件名。

注意: 使用 tmpnam() 创建的临时文件名只在程序运行期间存在,不具有真正唯一性,因此可能存在一定程度的风险。如果需要创建一个具有真正唯一性的临时文件,请考虑使用 mkstemp() 或类似的函数。

8.3 运行结果

9. toascii

9.1 函数说明

函数声明 函数功能
int toascii(int c); 将一个字符转换为其对应的 ASCII 码值

参数:

  • c : 要转换的字符

9.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
#include <ctype.h>

int main()
{
char ch = 'A';

// 将字符转换为其对应的 ASCII 码值
int ascii_val = toascii(ch);

printf("字符 %c 的 ASCII 码值为 %d\n", ch, ascii_val);

return 0;
}

注意 : toascii() 函数已经过时,不建议在新代码中使用。在 C99 标准中,改用更安全的 isascii() 函数来检查字符是否为 7-bit ASCII 字符,并使用位掩码操作或其他算法来将非 ASCII 字符转换为相应的 7-bit ASCII 码值。

知识点: 7-bit ASCII,也称为美国信息交换标准代码 (American Standard Code for Information Interchange),是一种基于英语的字符编码系统,使用 7 个二进制位(即一个字节)表示每个字符。它涵盖了拉丁字母、数字、标点符号和一些特殊符号,共计 128 个字符。

9.3 运行结果

10. tolower

10.1 函数说明

函数声明 函数功能
int tolower(int c); 可以用于将一个 ASCII 字符转换为小写字母

参数:

  • c : 要转换的字符

10.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <ctype.h>

int main()
{
char str[] = "Hello, World!";
int i = 0;

printf("转换前字符串: %s\n", str);

printf("转换后字符串: ");
while (str[i]) {
putchar(tolower(str[i]));
i++;
}

return 0;
}

10.3 运行结果

11. toupper

11.1 函数说明

函数声明 函数功能
int toupper(int c); 可以用于将一个 ASCII 字符转换为大写字母

参数:

  • c : 要转换的字符

11.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <ctype.h>

int main()
{
char str[] = "Hello, World!";
int i = 0;

printf("转换前字符串: %s\n", str);

printf("转换后字符串: ");
while (str[i]) {
putchar(toupper(str[i]));
i++;
}

return 0;
}

11.3 运行结果

12. trunc,truncf,truncl

12.1 函数说明

函数声明 函数功能
double trunc(double x); 截取 x 的小数部分,并返回整数部分(double)
float truncf(float x); 截取 x 的小数部分,并返回整数部分(float)
long double truncl(long double x); 截取 x 的小数部分,并返回整数部分(long double)

12.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
#include <math.h>

int main()
{
double x = 3.14159;
float y = 2.71828f;
long double z = 1.41421356L;

// 截去 double 类型浮点数的小数部分
double a = trunc(x);

// 截去 float 类型浮点数的小数部分
float b = truncf(y);

// 截去 long double 类型浮点数的小数部分
long double c = truncl(z);

printf("double 类型 %.5lf 的整数部分为 %.0lf\n", x, a);
printf("float 类型 %.5f 的整数部分为 %.0f\n", y, b);
printf("long double 类型 %.8Lf 的整数部分为 %.0Lf\n", z, c);

return 0;
}

12.3 运行结果

13. tzset

13.1 函数说明

函数声明 函数功能
void tzset(void); 可以用于设置时区信息

13.2 演示示例

UNIX/Linux 下示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define _XOPEN_SOURCE 700

int main()
{
time_t rawtime;
struct tm *timeinfo;

// 设置时区为 UTC
setenv("TZ", "UTC", 1);
tzset();

time(&rawtime);
timeinfo = localtime(&rawtime);
printf("当前时间是:%s", asctime(timeinfo));

return 0;
}

windows 下示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
#include <windows.h>
#include <time.h>

int main()
{
time_t rawtime;
struct tm *timeinfo;

TIME_ZONE_INFORMATION tzinfo;
GetTimeZoneInformation(&tzinfo);

// 将 WCHAR* 转换为 char*
int len = WideCharToMultiByte(CP_UTF8, 0, tzinfo.StandardName, -1, NULL, 0, NULL, NULL);
char* standard_name = (char*) malloc(len * sizeof(char));
WideCharToMultiByte(CP_UTF8, 0, tzinfo.StandardName, -1, standard_name, len, NULL, NULL);

_putenv_s("TZ", standard_name);
tzset();

time(&rawtime);
timeinfo = localtime(&rawtime);
printf("当前时间是:%s", asctime(timeinfo));

free(standard_name);
return 0;
}

在上述示例代码中,

  • 首先定义变量 rawtimetimeinfo,分别用于存储当前时间和时间结构体。
  • 接着使用 GetTimeZoneInformation() 函数获取当前系统时区信息,并将其存储在 tzinfo 变量中。
  • 然后使用 WideCharToMultiByte() 函数将 tzinfo.StandardName 转换为 UTF-8 编码的字符串,并将其存储在 standard_name 变量中。
  • 再接着使用 putenv_s() 函数将 standard_name 设置为环境变量 TZ 的值,并使用 tzset 函数更新本地时区信息。
  • 再然后使用 localtime() 函数将 rawtime 转换为时间结构体 timeinfo
  • 之后使用 asctime() 函数将时间结构体 timeinfo 转换为字符串格式,并输出到标准输出流中。
  • 最后释放 standard_name 分配的内存空间,并正常结束程序。

13.3 运行结果

14. tgamma,tgammaf,tgammal

14.1 函数说明

函数声明 函数功能
double tgamma(double x); 用于计算 Gamma 函数(double)
float tgammaf(float x); 用于计算 Gamma 函数(float)
long double tgammal(long double x); 用于计算 Gamma 函数(long double)

14.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include <math.h>

int main()
{
double x = 5.0;
float y = 7.2f;
long double z = 2.5L;

double result1 = tgamma(x);
float result2 = tgammaf(y);
long double result3 = tgammal(z);

printf("tgamma(%lf) = %lf\n", x, result1);
printf("tgammaf(%f) = %f\n", y, result2);
printf("tgammal(%Lf) = %Lf\n", z, result3);

return 0;
}

知识点: 伽玛函数(Gamma 函数),也叫欧拉第二积分,是阶乘函数在实数与复数上扩展的一类函数。

14.3 运行结果

参考

  1. [API Reference Document]
  2. [ASCII]

总览

函数声明 函数功能
char * strdup(const char *s); 用于将一个以 NULL 结尾的字符串复制到新分配的内存空间中
int stricmp(const char *s1, const char *s2); 用于比较两个字符串的字母序是否相等,忽略大小写
char *strerror(int errnum); 用于将指定的错误码转换为相应的错误信息
int strcmpi(const char *s1, const char *s2); 用于比较两个字符串的字母序是否相等,忽略大小写
int strncmp(const char *s1, const char *s2, size_t n); 用于比较两个字符串的前n个字符是否相等
int strncmpi(const char *s1, const char *s2, size_t n); 用于比较两个字符串的前n个字符是否相等,忽略大小写
char *strncpy(char *dest, const char *src, size_t n); 用于将一个字符串的一部分拷贝到另一个字符串中
int strnicmp(const char *s1, const char *s2, size_t n); 用于比较两个字符串的前n个字符是否相等,忽略大小写
char *strnset(char *str, int c, size_t n); 用于将一个字符串的前n个字符都设置为指定的字符
char *strpbrk(const char *str1, const char *str2); 用于在一个字符串中查找任意给定字符集合中的字符的第一次出现位置
char *strrchr(const char *str, int character); 在给定的字符串中查找指定字符的最后一个匹配项
char *strrev(char *str); 将给定字符串中的所有字符顺序颠倒,并返回颠倒后的字符串
char *strset(char *str, int character); 用于设置给定字符串中的所有字符为指定的值,并返回修改后的字符串
size_t strspn(const char *str1, const char *str2); 计算字符串 str1 中包含在字符串 str2 中的前缀子字符串长度,并返回该长度值
char *strstr(const char *str1, const char *str2); 在字符串 str1 中查找第一个出现的字符串 str2,如果找到了,则返回指向该位置的指针;否则,返回 NULL
double strtod(const char *str, char **endptr); 将字符串 str 转换为一个浮点数(double 类型),并返回该浮点数。如果发生了转换错误,则返回 0.0,并且可以通过 endptr 指针返回指向第一个无法转换的字符的指针。
char *strtok(char *str, const char *delim); 用于将一个字符串分割成多个子字符串
long int strtol(const char *str, char **endptr, int base); 将字符串 str 转换为一个长整型数(long int 类型)
char *strupr(char *str); 将字符串 str 中的所有小写字母转换为大写字母,并返回指向该字符串的指针
void swab(const void *src, void *dest, ssize_t nbytes); 将源缓冲区中的每两个相邻字节进行互换,然后将结果存储到目标缓冲区中
int system(const char *command); 执行一个 shellcmd 命令,并等待命令的完成

1. strdup

1.1 函数说明

函数声明 函数功能
char * strdup(const char *s); 用于将一个以 NULL 结尾的字符串复制到新分配的内存空间中

注意: strdup() 函数返回指向新分配的内存空间的指针,如果空间不足则返回 NULL。调用者负责释放返回的指针所指向的内存空间。 strdup() 函数与strcpy() 函数类似,但是它会动态地分配内存空间,而 strcpy() 需要调用者提供足够大的目标缓冲区。

1.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()
{
char *source = "Hello World!";
char *destination = strdup(source);

if(destination != NULL)
{
printf("Original string: %s\n", source);
printf("Duplicated string: %s\n", destination);
free(destination); // 释放内存,避免内存泄漏
}

return 0;
}

1.3 运行结果

2. stricmp

2.1 函数说明

函数声明 函数功能
int stricmp(const char *s1, const char *s2); 用于比较两个字符串的字母序是否相等,忽略大小写

返回值:

  • 如果 s1s2 代表的字符串相等(忽略大小写),则返回 0
  • 如果 s1s2 小,则返回负数;
  • 如果 s1s2 大,则返回正数。

2.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdio.h>
#include <string.h>

int main()
{
char *s1 = "Hello";
char *s2 = "hElLo";

int result = stricmp(s1, s2); // 忽略大小写比较

if(result == 0)
{
printf("The strings are equal.\n");
}
else if(result < 0)
{
printf("%s is less than %s.\n", s1, s2);
}
else
{
printf("%s is greater than %s.\n", s1, s2);
}

return 0;
}

2.3 运行结果

3. strerror

3.1 函数说明

函数声明 函数功能
char *strerror(int errnum); 用于将指定的错误码转换为相应的错误信息

参数:

  • errnum : 要转换为错误信息的错误码,通常是由系统调用或库函数返回的错误码。

返回值:
指向错误信息字符串的指针,该字符串描述了与错误码相关的错误

3.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
#include <string.h>
#include <errno.h>

int main()
{
FILE *file = fopen("nonexistent.txt", "r");

if(file == NULL)
{
int errcode = errno; // 获取发生的错误码
printf("Error opening file: %s\n", strerror(errcode)); // 将错误码转换为错误信息并打印
}
else
{
printf("File opened successfully.\n");
fclose(file);
}

return 0;
}

3.3 运行结果

4. strcmpi

4.1 函数说明

函数声明 函数功能
int strcmpi(const char *s1, const char *s2); 用于比较两个字符串的字母序是否相等,忽略大小写

返回值:

  • 如果 s1s2 代表的字符串相等(忽略大小写),则返回 0
  • 如果 s1s2 小,则返回负数;
  • 如果 s1s2 大,则返回正数。

4.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdio.h>
#include <string.h>

int main()
{
char *s1 = "Hello";
char *s2 = "hElLo";

int result = strcmpi(s1, s2); // 忽略大小写比较

if(result == 0)
{
printf("The strings are equal.\n");
}
else if(result < 0)
{
printf("%s is less than %s.\n", s1, s2);
}
else
{
printf("%s is greater than %s.\n", s1, s2);
}

return 0;
}

看到这里,可能会疑惑 上面不是已经有了 忽略大小写的字符串比较了嘛?

strcmpistricmp 有什么区别呢?

虽然它们的实现功能相同,但是不同的编译器或操作系统可能会提供其中一个或两个函数。在具备这两个函数的系统中,strcmpi 常常作为 VC(Visual C++)Borland C++ 的扩展库函数,而 stricmp 则是 POSIX 标准中定义的函数,在许多 类UNIX系统 上可用。因此,如果需要编写可移植的代码,则应该使用 stricmp 函数,而不是 strcmpi 函数。

4.3 运行结果

5. strncmp

5.1 函数说明

函数声明 函数功能
int strncmp(const char *s1, const char *s2, size_t n); 用于比较两个字符串的前n个字符是否相等

参数:

  • s1 : 待比较的第一个字符串
  • s2 : 待比较的第二个字符串
  • n : 要比较的字符数

返回值:

  • 如果 s1s2 代表的字符串相等(忽略大小写),则返回 0
  • 如果 s1s2 小,则返回负数;
  • 如果 s1s2 大,则返回正数。

5.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdio.h>
#include <string.h>

int main()
{
char *s1 = "Hello World";
char *s2 = "Hell!";

int result = strncmp(s1, s2, 4); // 比较前4个字符

if(result == 0)
{
printf("The first 4 characters are equal.\n");
}
else if(result < 0)
{
printf("The first 4 characters of %s are less than %s.\n", s1, s2);
}
else
{
printf("The first 4 characters of %s are greater than %s.\n", s1, s2);
}

return 0;
}

5.3 运行结果

6. strncmpi

6.1 函数说明

函数声明 函数功能
int strncmpi(const char *s1, const char *s2, size_t n); 用于比较两个字符串的前n个字符是否相等,忽略大小写

参数:

  • s1 : 待比较的第一个字符串
  • s2 : 待比较的第二个字符串
  • n : 要比较的字符数

返回值:

  • 如果 s1s2 代表的字符串相等(忽略大小写),则返回 0
  • 如果 s1s2 小,则返回负数;
  • 如果 s1s2 大,则返回正数。

6.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdio.h>
#include <string.h>

int main()
{
char *s1 = "Hello World";
char *s2 = "heLL!";

int result = strncmpi(s1, s2, 4); // 比较前4个字符,忽略大小写

if(result == 0)
{
printf("The first 4 characters are equal (case insensitive).\n");
}
else if(result < 0)
{
printf("The first 4 characters of %s are less than %s (case insensitive).\n", s1, s2);
}
else
{
printf("The first 4 characters of %s are greater than %s (case insensitive).\n", s1, s2);
}

return 0;
}

注意: strncmpi 函数不是 C 语言标准库中的函数,但在某些编译器或操作系统中可能会提供。

7. strncpy

7.1 函数说明

函数声明 函数功能
char *strncpy(char *dest, const char *src, size_t n); 用于将一个字符串的一部分拷贝到另一个字符串中

参数:

  • dest : 目标字符串
  • src : 源字符串
  • n : 要拷贝的字符数

7.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
#include <string.h>

int main()
{
char dest[20];
const char *src = "Hello";

strncpy(dest, src, 8); // 拷贝前8个字符

printf("The copied string is: %s\n", dest);

return 0;
}

当源字符串长度小于 n 时,strncpy() 函数将在目标字符串的末尾填充 \0 字符以达到指定的拷贝长度 n

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <string.h>

int main()
{
char dest[6];
const char *src = "Hello World";

strncpy(dest, src, 5); // 拷贝前5个字符

dest[5] = '\0'; // 手动添加末尾的\0字符

printf("The copied string is: %s\n", dest);

return 0;
}

如果源字符串长度大于等于 n 个字符,strncpy() 函数将会拷贝源字符串的前 n 个字符到目标字符串中,并且不会自动添加末尾的 \0 字符。这种情况下,目标字符串可能不是以 \0 字符结尾,因此需要手动在拷贝后的目标字符串中添加 \0 字符。

7.3 运行结果

8. strnicmp

8.1 函数说明

函数声明 函数功能
int strnicmp(const char *s1, const char *s2, size_t n); 用于比较两个字符串的前n个字符是否相等,忽略大小写

参数:

  • s1 : 待比较的第一个字符串
  • s2 : 待比较的第二个字符串
  • n : 要比较的字符数

返回值:

  • 如果 s1s2 代表的字符串相等(忽略大小写),则返回 0
  • 如果 s1s2 小,则返回负数;
  • 如果 s1s2 大,则返回正数。

8.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdio.h>
#include <string.h>

int main()
{
const char *s1 = "Hello World";
const char *s2 = "heLL!";

int result = strnicmp(s1, s2, 4); // 比较前4个字符,忽略大小写

if(result == 0)
{
printf("The first 4 characters are equal (case insensitive).\n");
}
else if(result < 0)
{
printf("The first 4 characters of %s are less than %s (case insensitive).\n", s1, s2);
}
else
{
printf("The first 4 characters of %s are greater than %s (case insensitive).\n", s1, s2);
}

return 0;
}

8.3 运行结果

9. strnset

9.1 函数说明

函数声明 函数功能
char *strnset(char *str, int c, size_t n); 用于将一个字符串的前n个字符都设置为指定的字符

参数:

  • str: 要进行操作的字符串
  • c: 要设置的字符
  • n : 要设置的字符数

9.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
#include <string.h>

int main() {
char str[20] = "Hello World";
printf("Before: %s\n", str);

strnset(str, '*', 5); // 将前5个字符都设置为*

printf("After: %s\n", str);

return 0;
}

注意: strnset() 函数是非标准函数,并不是所有的编译器和操作系统都支持该函数。如果需要跨平台兼容,请使用标准库函数 memset() 来实现类似的功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
#include <string.h>

int main()
{
char str[20] = "Hello World";
printf("Before: %s\n", str);

memset(str, '*', 5); // 将前5个字符都设置为*

printf("After: %s\n", str);

return 0;
}

上述示例使用了标准库函数 memset 来将 str 的前 5 个字符都设置为 *

9.3 运行结果

10. strpbrk

10.1 函数说明

函数声明 函数功能
char *strpbrk(const char *str1, const char *str2); 用于在一个字符串中查找任意给定字符集合中的字符的第一次出现位置

参数:

  • str1 : 要进行搜索的字符串
  • str2 : 要查找的字符集合

注意: 如果在str1中没有找到str2中的任何字符,则 strpbrk 函数返回NULL 指针

10.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
#include <string.h>

int main()
{
char str[] = "Hello World";
char *ptr;

ptr = strpbrk(str, "aeiou"); // 查找元音字母

if (ptr != NULL)
{
printf("Found vowel '%c' at position: %lld\n", *ptr, ptr - str + 1);
}
else
{
printf("No vowel found.\n");
}

return 0;
}

10.3 运行结果

11. strrchr

11.1 函数说明

函数声明 函数功能
char *strrchr(const char *str, int character); 在给定的字符串中查找指定字符的最后一个匹配项

参数:

  • str : 要进行搜索的字符串
  • character : 要查找的字符,其 ASCII 值由整数表示

返回值:

  • 如果匹配到,返回匹配字符的地址;
  • 如果没有找到匹配项,则返回 NULL。

11.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdio.h>
#include <string.h>

int main ()
{
const char str[] = "Hello World!";

printf("在 '%s' 中查找字符 'o' 的最后一次出现:\n", str);
char *last_o = strrchr(str, 'o');

if (last_o)
printf("最后一个 'o' 的位置:%lld\n", last_o - str);
else
printf("未找到匹配的字符。\n");

printf("在 '%s' 中查找字符 'w' 的最后一次出现:\n", str);
char *last_w = strrchr(str, 'w');

if (last_w)
printf("最后一个 'w' 的位置:%lld\n", last_w - str);
else
printf("未找到匹配的字符。\n");

return 0;
}

11.3 运行结果

12. strrev

12.1 函数说明

函数声明 函数功能
char *strrev(char *str); 将给定字符串中的所有字符顺序颠倒,并返回颠倒后的字符串

参数:

  • str : 要反转的的字符串

注意:因为 strrev() 函数是一个非标准的库函数,许多编译器可能并不支持该函数,所以在使用该函数之前,请确保你的编译器支持它。

12.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
#include <string.h>

int main ()
{
char str[50];

printf("输入一个字符串:");
scanf("%s", str);

printf("原始字符串:%s\n", str);
printf("反转后的字符串:%s\n", strrev(str));

return 0;
}

12.3 运行结果

13. strset

13.1 函数说明

函数声明 函数功能
char *strset(char *str, int character); 用于设置给定字符串中的所有字符为指定的值,并返回修改后的字符串

参数:

  • str : 要修改的字符串
  • character : 要设置的字符,其 ASCII 值由整数表示

13.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
#include <string.h>

int main ()
{
char str[50];

printf("请输入一个字符串:");
scanf("%s", str);

printf("原始字符串:%s\n", str);
printf("将所有字符设置为 'X' 后的字符串:%s\n", strset(str, 'X'));

return 0;
}

13.3 运行结果

14. strspn

14.1 函数说明

函数声明 函数功能
size_t strspn(const char *str1, const char *str2); 计算字符串 str1 中包含在字符串 str2 中的前缀子字符串长度,并返回该长度值

参数:

  • str1 : 要搜索的字符串
  • str2 : 包含要搜索的字符集合的 字符串

14.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
#include <string.h>

int main ()
{
const char str[] = "Hello World!";
const char charset[] = "lHeoWrd";

size_t length = strspn(str, charset);

printf("在 '%s' 中,最长的前缀子串 '%s' 包含于 '%s' 中。长度为 %zu\n",
str, strndup(str, length), charset, length);

return 0;
}

上述示例代码运行后,如果出现 error: 'strndup' was not declared in this scope ,说明当前的编译器不支持 strndup() 函数。

因为 strndup() 函数是 C11 新增的函数,因此可能不是所有编译器都支持。

那我们就用如下的方式来替换一下 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main ()
{
const char str[] = "Hello World!";
const char charset[] = "lHeoWrd";

size_t length = strspn(str, charset);

char *substr = (char *)malloc(length + 1);
memcpy(substr, str, length);
substr[length] = '\0';

printf("在 '%s' 中,最长的前缀子串 '%s' 包含于 '%s' 中。长度为 %zu\n",
str, substr, charset, length);

free(substr);
return 0;
}

14.3 运行结果

15. strstr

15.1 函数说明

函数声明 函数功能
char *strstr(const char *str1, const char *str2); 在字符串 str1 中查找第一个出现的字符串 str2,如果找到了,则返回指向该位置的指针;否则,返回 NULL

参数:

  • str1 : 源字符串
  • str2 : 要查找的子字符串

15.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
#include <string.h>

int main ()
{
const char str[] = "Hello World!";
const char substr[] = "World";

char *result = strstr(str, substr);

if (result)
printf("在 '%s' 中找到了子串 '%s'。子串起始位置是 '%s'\n", str, substr, result);
else
printf("在 '%s' 中未找到子串 '%s'\n", str, substr);

return 0;
}

15.3 运行结果

16. strtod

16.1 函数说明

函数声明 函数功能
double strtod(const char *str, char **endptr); 将字符串 str 转换为一个浮点数(double 类型),并返回该浮点数。如果发生了转换错误,则返回 0.0,并且可以通过 endptr 指针返回指向第一个无法转换的字符的指针。
参数:
  • str : 要转换为浮点数的字符串
  • endptr : 可选参数,用于存储第一个无法转换的字符的指针地址

16.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <stdlib.h>

int main ()
{
const char str[] = "3.14";
// const char str[] = "3.1a4";
// const char str[] = "a3.14";
char *endptr;

double num = strtod(str, &endptr);

printf("输入字符串为 '%s'\n", str);
printf("转换后的浮点数为 %f\n", num);

if (endptr == str)
printf("无法进行任何转换。\n");
else if (*endptr != '\0')
printf("字符串 '%s' 的末尾非法字符是 '%c'\n", str, *endptr);

return 0;
}

16.3 运行结果



17. strtok

17.1 函数说明

函数声明 函数功能
char *strtok(char *str, const char *delim); 用于将一个字符串分割成多个子字符串

参数:

  • str : 要被分割的 字符串。第一次调用时,应该将其设置为要被分割的字符串的地址;以后的调用中,该参数应该为 NULL
  • delim: 分隔符字符集合,用于指定子字符串的分割标准

返回值: 分割后的第一个子字符串,并在每次调用时修改传入的原始字符串 str,使其指向下一个要被分割的子字符串

17.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include <string.h>

int main ()
{
const char str[] = "Hello,World!How are you?";
const char delim[] = ", !";
char *token;

token = strtok((char *)str, delim);

while (token != NULL)
{
printf("%s\n", token);
token = strtok(NULL, delim);
}

return 0;
}

在上述的示例中,

  • 我们首先定义了字符串 str 和 字符集合 delim
  • 然后使用 strtok() 函数将字符串 str 按照字符集合 delim 中的分隔符进行分割。每次调用 strtok() 函数时,它会返回分割出的第一个子字符串,并且会修改 str 指向下一个将要被分割的子字符串。
  • 最后我们不断循环调用 strtok() 函数,并输出返回的每个子字符串,直到没有更多的子字符串可以分割为止

17.3 运行结果

18. strtol

18.1 函数说明

函数声明 函数功能
long int strtol(const char *str, char **endptr, int base); 将字符串 str 转换为一个长整型数(long int 类型)

参数:

  • str : 要被转换为长整型数的字符串
  • endptr : 可选参数,用于存储第一个无法转换的字符的指针地址
  • base: 转换的进制数,必须是 236 之间的有效数字或者 0。为 0 表示采用默认的进制数,即可以解释成合法的整数的最大进制数(一般是 10

返回值:

  • 如果成功转换,返回一个长整型数;
  • 如果发生了转换错误,则返回 0,并且可以通过 endptr 指针返回指向第一个无法转换的字符的指针。

18.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <stdlib.h>

int main ()
{
const char str[] = "101011";
// const char str[] = "10101a1";
// const char str[] = "a101011";
char *endptr;

long int num = strtol(str, &endptr, 2);

printf("输入字符串为 '%s'\n", str);
printf("转换后的十进制数为 %ld\n", num);

if (endptr == str)
printf("无法进行任何转换。\n");
else if (*endptr != '\0')
printf("字符串 '%s' 的末尾非法字符是 '%c'\n", str, *endptr);

return 0;
}

18.3 运行结果



19. strupr

19.1 函数说明

函数声明 函数功能
char *strupr(char *str); 将字符串 str 中的所有小写字母转换为大写字母,并返回指向该字符串的指针

参数:

  • str : 要进行大小写转换的字符串

19.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
#include <string.h>

int main ()
{
char str[] = "Hello, World!";
printf("原始字符串为 '%s'\n", str);
strupr(str);
printf("转换后的字符串为 '%s'\n", str);
return 0;
}

19.3 运行结果

20. swab

20.1 函数说明

函数声明 函数功能
void swab(const void *src, void *dest, ssize_t nbytes); 将源缓冲区中的每两个相邻字节进行互换,然后将结果存储到目标缓冲区中

参数:

  • str : 源缓冲区的指针
  • dest : 目标缓冲区的指针
  • nbytes : 需要交换的字节数

20.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
#include <string.h>
#include <unistd.h>

int main ()
{
char src[] = "Hello, World!";
char dest[15];
printf("原始字符串为 '%s'\n", src);
swab(src, dest, strlen(src));
printf("转换后的字符串为 '%s'\n", dest);
return 0;
}

上面示例中,我在一开始演示时,因为没有加上 #include <unistd.h> 这个头文件,导致出现如下错误:

20.3 运行结果

21. system

21.1 函数说明

函数声明 函数功能
int system(const char *command); 执行一个 shellcmd 命令,并等待命令的完成

参数:

  • command : 要执行的 shellcmd 命令。

21.2 演示示例

下面演示 执行 ls -lshell 命令,笔者是在 windows环境下运行,故会出错,详见运行结果那里

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <stdlib.h>

int main ()
{
const char command[] = "ls -l";

printf("执行命令: '%s'\n", command);

int status = system(command);

if (status != 0)
printf("执行出错!\n");

return 0;
}

再来看下,演示使用 dir 命令,在 windows 下可以输出当前目录下的所有文件和子目录

1
2
3
4
5
6
7
8
#include <stdlib.h>

int main ()
{
const char command[] = "dir";
system(command);
return 0;
}

21.3 运行结果

总览

函数声明 函数功能
unsigned int sleep(unsigned int seconds); 它是 C 语言标准库中的函数,用于使当前进程挂起一定的时间。在挂起期间,操作系统会将该进程从调度队列中移除,直到指定的时间过去为止。
void Sleep(DWORD milliseconds); 它是 Windows API 中的一部分,与 sleep 函数类似,它可以使当前线程挂起一段时间。
int sopen(const char* filename, int access, int sharemode, int shflag, ...); 它是 Microsoft Visual C++ 中的一个函数,用于打开文件并返回文件句柄。与标准库中的 fopen 函数不同,sopen 函数支持以二进制方式打开文件,并且可以指定文件读写方式、共享模式和文件访问权限等参数。
void sound(int frequency); 用于发出声音,sound 函数会持续发出声音,直到调用 nosound 函数停止
int spawnl(int mode, const char *cmdname, const char *arg0, ..., NULL); 它是在 Windows 平台上使用的函数,用于启动另一个程序,并等待该程序运行结束后再继续执行本程序
int spawnle(int mode, const char *cmdname, const char *arg0, ..., const char *envp[]); 它是在 Windows 平台上使用的函数,可以启动另一个程序,并通过指定的环境变量传递参数
int sprintf(char *str, const char *format, ...); 用于将格式化的字符串输出到指定的缓冲区中
int snprintf(char *str, size_t size, const char *format, ...); 用于将格式化的字符串输出到指定的缓冲区中,类似于 sprintf 函数,但它可以限制输出字符串的长度,避免缓冲区溢出
double sqrt(double x); 计算 x 的平方根(double)
float sqrtf(float x); 计算 x 的平方根 (float)
long double sqrtl(long double x); 计算 x 的平方根 (long double)
void srand(unsigned int seed); 用于初始化伪随机数生成器
int sscanf(const char *str, const char *format, ...); 用于从字符串中读取数据并进行格式化转换
int stat(const char *path, struct stat *buf); 用于获取文件或目录的属性信息,例如文件大小、创建时间、修改时间等。这些属性信息都被保存在一个名为 struct stat 的结构体中。
int stime(const time_t *t); 它是是 Unix/Linux 系统中的一个系统调用函数,用于设置系统时间
char *stpcpy(char *dest, const char *src); 用于复制一个字符串到另一个字符串缓冲区,并返回目标字符串的结尾指针
char* strcat(char* dest, const char* src); 用于将一个字符串拼接到另一个字符串的末尾
char* strchr(const char* str, int c); 用于查找字符串中第一次出现指定字符的位置,并返回该位置的指针
int strcmp(const char* str1, const char* str2); 用于比较两个字符串是否相等
char* strcpy(char* dest, const char* src); 用于将一个字符串复制到另一个字符串缓冲区中
size_t strcspn(const char* str, const char* charset); 用于查找字符串中第一次出现指定字符集合中任何字符的位置,并返回该位置的索引

1. sleep

1.1 函数说明

函数声明 函数功能
unsigned int sleep(unsigned int seconds); 它是 C 语言标准库中的函数,用于使当前进程挂起一定的时间。在挂起期间,操作系统会将该进程从调度队列中移除,直到指定的时间过去为止。
void Sleep(DWORD milliseconds); 它是 Windows API 中的一部分,与 sleep 函数类似,它可以使当前线程挂起一段时间。

sleep 函数参数:

  • seconds : 要挂起的时间,单位为秒

Sleep 函数参数:

  • milliseconds: 要挂起的时间,单位为毫秒

1.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
#include <unistd.h>

int main()
{
printf("Start sleeping...\n");
sleep(5);
printf("Wake up!\n");

return 0;
}

在使用 sleep() 函数时,将会使当前线程或者进程暂停指定的时间,以便给其他进程或线程执行机会,同时也可以用来控制程序的运行速度。

虽然 sleep() 函数很简单,但是需要注意以下几点:

  1. sleep() 的精度并不高,它所挂起的时间可能会略微超过要求的时间。
  2. sleep() 函数是阻塞式的,即在调用 sleep() 函数期间,该进程不能进行任何其他操作,包括响应信号等。
  3. 在使用 sleep() 函数期间,如果发生信号,那么 sleep() 函数将被中断,该进程将继续运行。
1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
#include <Windows.h>

int main()
{
printf("Start sleeping...\n");
Sleep(5000); // 暂停 5 秒钟
printf("Wake up!\n");

return 0;
}

由于 Sleep() 函数是阻塞式的,因此该函数调用期间,当前线程将被阻塞。在函数调用结束后,该线程将恢复运行。

Windows 系统下使用 Sleep() 函数时,需要注意以下几点:

  1. Sleep() 函数以毫秒为单位指定时间,精度比 sleep() 函数更高。
  2. 在调用 Sleep() 函数期间,当前线程将被阻塞,不能进行任何其他操作,包括响应信号等。
  3. 在使用 Sleep() 函数期间,如果发生信号,那么 Sleep() 函数将被中断,该线程将继续运行。

1.3 运行结果

2. sopen

2.1 函数说明

函数声明 函数功能
int sopen(const char* filename, int access, int sharemode, int shflag, ...); 它是 Microsoft Visual C++ 中的一个函数,用于打开文件并返回文件句柄。与标准库中的 fopen 函数不同,sopen 函数支持以二进制方式打开文件,并且可以指定文件读写方式、共享模式和文件访问权限等参数。

参数:

  • filename : 要打开的文件名
  • access : 指定文件的访问方式,可以是以下值之一:
    • _O_RDONLY:只读方式打开文件
    • _O_WRONLY:只写方式打开文件
    • _O_RDWR:读写方式打开文件
    • _O_APPEND:在文件末尾追加数据
    • _O_CREAT:如果文件不存在,则创建文件
    • _O_TRUNC:如果文件已存在,清空文件内容
    • _O_EXCL:与 _O_CREAT 配合使用,如果文件已经存在则打开失败
  • sharemode : 指定文件共享模式,可以是以下值之一:
    • _SH_DENYRW:独占方式打开文件,其他进程不能读取或写入该文件
    • _SH_DENYWR:共享读取方式打开文件,其他进程不能写入该文件
    • _SH_DENYRD:共享写入方式打开文件,其他进程不能读取该文件
    • _SH_DENYNO:共享方式打开文件,其他进程可以读取和写入该文件
  • shflag : 指定文件属性标志,可以是以下值之一:
    • _S_IWRITE:文件可写
    • _S_IREAD:文件可读
  • … : 可选参数。如果指定了 _O_CREAT 参数,则需要指定文件的访问权限

2.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
#include <sys/stat.h>

#define _SH_DENYNO 0x40

int main()
{
int handle;
char buffer[1024];

// 打开文件并读取数据
handle = sopen("output.bin", _O_RDONLY, _SH_DENYNO, _S_IREAD);
if (handle == -1)
{
printf("Failed to open file!\n");
return 1;
}
read(handle, buffer, sizeof(buffer));
printf("File content: %s\n", buffer);

// 关闭文件句柄
close(handle);

return 0;
}

指定文件共享模式,如果没有对应的宏常量,则可以定义如下:

1
2
3
4
#define _SH_DENYRW 0x10
#define _SH_DENYWR 0x20
#define _SH_DENYRD 0x30
#define _SH_DENYNO 0x40

2.3 运行结果


3. sound

3.1 函数说明

函数声明 函数功能
void sound(int frequency); 用于发出声音
void nosound(void); sound 函数会持续发出声音,直到调用 nosound 函数停止

参数:

  • frequency : 要发出的声音的频率,单位为赫兹(Hz)

3.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
#include <windows.h>

int main()
{
printf("Playing sound...\n");
sound(1000); // 发出 1000 Hz 音调
Sleep(5000); // 等待 5 秒钟
nosound(); // 停止发声
printf("Sound stopped.\n");
return 0;
}

Windows 下如果上述出现 error: 'sound' was not declared in this scope,可以使用如下:

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
#include <windows.h>

int main()
{
printf("Playing sound...\n");
Beep(1000, 5000); // 发出 1000 Hz 音调,持续 5 秒钟
printf("Sound stopped.\n");
return 0;
}

注意:Windows 平台上建议使用 Beep() 函数代替 sound() 函数,因为 Beep() 函数不需要特殊的硬件支持,并且可移植性更好。

4. spawnl

4.1 函数说明

函数声明 函数功能
int spawnl(int mode, const char *cmdname, const char *arg0, ..., NULL); 它是在 Windows 平台上使用的函数,用于启动另一个程序,并等待该程序运行结束后再继续执行本程序

参数:

  • mode : 执行模式,可以为 P_WAITP_NOWAIT
  • cmdname : 要执行的程序名称
  • arg0: 要传递给程序的命令行参数,以 NULL 结尾

4.2 演示示例

4.2.1 test.c

1
2
3
4
5
6
7
#include <stdio.h>

int main()
{
printf("Hello World\n");
return 0;
}

4.2.2 spawnl 演示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <process.h>
#include <stdio.h>

int main(void)
{
int result;

// 要执行的程序名和参数列表
const char* cmdname = "test.exe";
const char* arg0 = NULL;

// 执行程序
result = spawnl(P_WAIT, cmdname, cmdname, arg0, NULL);
if (result == -1)
{
perror("Error from spawnl");
exit(1);
}
return 0;
}

如果在使用 spawnl() 函数时遇到了 "Error from spawnl: Invalid argument" 错误,有可能是由于参数传递不正确或要执行的程序不存在等原因导致的。

以下是一些可能导致该错误的情况:

  1. 要执行的程序不存在或路径不正确。
  2. cmdname 参数包含非法字符或格式不正确。
  3. 参数列表没有以 NULL 结尾。
  4. 要执行的程序需要管理员权限,但当前用户没有足够的权限。

4.3 运行结果

5. spawnle

5.1 函数说明

函数声明 函数功能
int spawnle(int mode, const char *cmdname, const char *arg0, ..., const char *envp[]); 它是在 Windows 平台上使用的函数,可以启动另一个程序,并通过指定的环境变量传递参数

参数:

  • mode : 执行模式,可以为 P_WAITP_NOWAIT
  • cmdname : 要执行的程序名称
  • arg0 : 要传递给程序的命令行参数,以 NULL 结尾
  • envp : 要传递给程序的环境变量

5.2 演示示例

5.2.1 SubEnvTest.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <process.h>
#include <processenv.h>
#include <stdio.h>

int main(int argc, char *argv[], char **envp)
{
printf("SubEnvTest Command line arguments:\n");
for (int i=0; i<argc; i++)
printf("[%d] : %s\n", i, argv[i]);
printf("exec %s, Hello, %s\n", argv[0], argv[1]);

for (int i = 0; envp[i] != NULL; i++)
{
printf("%s\n", envp[i]);
}
return 0;
}

5.2.2 spawnle 演示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <stdlib.h>
#include <process.h>

int main(int argc, char *argv[], char *envp[])
{
int result;

// 启动 SubEnvTest.exe,并传递当前环境变量
result = spawnle(P_WAIT, "SubEnvTest.exe", "SubEnvTest.exe", NULL, envp);
if (result == -1)
{
printf("Error: %d\n", errno);
return 1;
}

return 0;
}

5.3 运行结果

6. sprintf

6.1 函数说明

函数声明 函数功能
int sprintf(char *str, const char *format, ...); 用于将格式化的字符串输出到指定的缓冲区中

参数:

  • str : 指向字符数组(缓冲区)的指针,用于存储生成的格式化字符串
  • format : 用于指定要生成的格式化文本
  • … : 用于填充格式化字符串中的占位符

6.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>

int main()
{
char buffer[128];
int value = 123;

// 将整数转换为字符串并保存到 buffer 中
sprintf(buffer, "The value is %d.", value);
printf("%s\n", buffer);

return 0;
}

6.3 运行结果

7. snprintf

7.1 函数说明

函数声明 函数功能
int snprintf(char *str, size_t size, const char *format, ...); 用于将格式化的字符串输出到指定的缓冲区中,类似于 sprintf 函数,但它可以限制输出字符串的长度,避免缓冲区溢出

参数:

  • str : 指向字符数组(缓冲区)的指针,用于存储生成的格式化字符串
  • size : 指定缓冲区可写入的最大字节数
  • format : 用于指定要生成的格式化文本
  • … : 用于填充格式化字符串中的占位符

7.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>

int main()
{
char buffer[5];
int value = 123456;

// 将整数转换为字符串并保存到 buffer 中,最大可写入长度为 sizeof(buffer) - 1
snprintf(buffer, sizeof(buffer), "%d", value);
printf("%s\n", buffer); // 输出 "1234"

return 0;
}

7.3 运行结果

8. sqrt,sqrtf,sqrtl

8.1 函数说明

函数声明 函数功能
double sqrt(double x); 计算 x 的平方根(double)
float sqrtf(float x); 计算 x 的平方根 (float)
long double sqrtl(long double x); 计算 x 的平方根 (long double)

参数:

  • x : 要计算平方根的数

8.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
#include <math.h>

int main()
{
double x = 2.0;
float y = 3.0f;
long double z = 4.0L;

printf("sqrt(%.1f) = %.2f\n", x, sqrt(x));
printf("sqrtf(%.1f) = %.2f\n", y, sqrtf(y));
printf("sqrtl(%.1Lf) = %.2Lf\n", z, sqrtl(z));

return 0;
}

8.3 运行结果

9. srand

9.1 函数说明

函数声明 函数功能
void srand(unsigned int seed); 用于初始化伪随机数生成器

参数:

  • seed : 用于设置伪随机数生成器的种子值。不同的种子值会产生不同的随机数序列。

9.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main()
{
int i;

// 使用当前时间作为种子值
srand(time(NULL));

// 生成 10 个随机数并输出到控制台
for (i = 0; i < 10; i++)
{
printf("%d ", rand());
}
printf("\n");

return 0;
}

注意: 如果不设置种子值,则每次程序运行时都会得到相同的随机数序列。因此,我们在实际开发中,常常使用时间戳或其他随机值来作为种子值,以确保生成的随机数具有更好的随机性。

9.3 运行结果

10. sscanf

10.1 函数说明

函数声明 函数功能
int sscanf(const char *str, const char *format, ...); 用于从字符串中读取数据并进行格式化转换

参数:

  • str : 要读取数据的字符串
  • format : 格式字符串,用于指定要读取的数据的类型、数量和顺序
  • … : 指向要写入的变量的指针

10.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>

int main()
{
char str[] = "hello world 123";
char buf[16];
int num;

// 从字符串中读取一个字符串和一个整数
if (sscanf(str, "%s %*s %d", buf, &num) == 2)
{
printf("String: %s\n", buf);
printf("Number: %d\n", num);
}

return 0;
}

在上述的示例代码中,我们使用 sscanf() 函数从字符串 "hello world 123" 中读取一个字符串和一个整数,并输出到控制台。

注意: 在格式字符串中,%s 表示读取一个字符串,%d 表示读取一个整数。另外,%*s 表示读取并忽略一个字符串。

10.3 运行结果

11. stat

11.1 函数说明

函数声明 函数功能
int stat(const char *path, struct stat *buf); 用于获取文件或目录的属性信息,例如文件大小、创建时间、修改时间等。这些属性信息都被保存在一个名为 struct stat 的结构体中。

参数:

  • path : 要获取属性信息的文件或目录路径
  • buf : 指向 struct stat 结构体的指针,用于存储获取到的属性信息

返回值:

  • 如果执行成功,则返回 0
  • 否则返回 -1 并设置相应的错误码(存储在 errno 变量中)

11.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <sys/stat.h>

int main()
{
struct stat file_stat;

// 获取文件属性信息
if (stat("test.txt", &file_stat) == 0) {
printf("File size: %ld bytes\n", file_stat.st_size);
printf("Creation time: %ld\n", file_stat.st_ctime);
printf("Modification time: %ld\n", file_stat.st_mtime);
}

return 0;
}

11.3 运行结果

12. stime

12.1 函数说明

函数声明 函数功能
int stime(const time_t *t); 它是是 Unix/Linux 系统中的一个系统调用函数,用于设置系统时间

参数:

  • t: 指向一个 time_t 类型变量的指针,表示要设置的系统时间

返回值:

  • 如果执行成功,则返回 0
  • 否则返回 -1 并设置相应的错误码(存储在 errno 变量中)

12.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <stdio.h>
#include <time.h>
#include <unistd.h>

int main()
{
time_t t;

// 获取当前时间
time(&t);

// 输出当前时间
printf("Current time: %s", ctime(&t));

// 设置系统时间为 2022 年 1 月 1 日
struct tm new_time;
new_time.tm_sec = 0;
new_time.tm_min = 0;
new_time.tm_hour = 0;
new_time.tm_mday = 1;
new_time.tm_mon = 0;
new_time.tm_year = 122;
new_time.tm_wday = 6;
new_time.tm_yday = 0;
new_time.tm_isdst = -1;

t = mktime(&new_time);
stime(&t);

// 短暂等待,确保时间设置完成
sleep(1);

// 再次输出当前时间
time(&t);
printf("New time: %s", ctime(&t));

return 0;
}

在如上的示例代码中,

  • 我们首先使用 time() 函数获取当前时间,并输出到控制台;
  • 然后,我们设置系统时间为 2022 年 1 月 1 日,并等待一秒钟以确保时间设置完成。
  • 最后,我们再次输出当前时间,以验证时间设置是否成功。

注意: stime() 函数只能在 Linux/Unix 系统上使用,并且需要 root 权限才能调用。另外,在修改系统时间时应谨慎行事,以避免对系统和应用程序造成不可预料的影响。

13. stpcpy

13.1 函数说明

函数声明 函数功能
char *stpcpy(char *dest, const char *src); 用于复制一个字符串到另一个字符串缓冲区,并返回目标字符串的结尾指针

参数:

  • dest : 目标字符串的缓冲区,必须具有足够的空间来存储源字符串
  • src : 要复制的源字符串。

返回值: 一个指向目标字符串结尾的指针

13.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <string.h>

int main()
{
char src[] = "Hello world";
char dest[32];

char *end = stpcpy(dest, src);

printf("Source string: %s\n", src);
printf("Destination string: %s\n", dest);
printf("End pointer: %p\n", end);

return 0;
}

在上述的示例代码中,我们使用 stpcpy() 函数将源字符串 "Hello world" 复制到目标字符串 dest 中,并输出两个字符串以及目标字符串的结尾指针。

注意: stpcpy() 函数只能在支持 ISO C99POSIX.1-2001 标准的系统上使用,对于其他系统,可能需要使用 strcpy() 函数代替。此外,应始终确保目标字符串缓冲区具有足够的空间来存储源字符串,以避免发生缓冲区溢出。

14. strcat

14.1 函数说明

函数声明 函数功能
char* strcat(char* dest, const char* src); 用于将一个字符串拼接到另一个字符串的末尾

参数:

  • dest : 目标字符串的缓冲区,必须具有足够的空间来存储源字符串
  • src : 要拼接的源字符串

返回值: 一个指向目标字符串结尾的指针

14.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <string.h>

int main()
{
char str1[32] = "Hello";
char str2[] = " world!";

printf("Before: str1=%s str2=%s\n", str1, str2);

strcat(str1, str2);

printf("After: str1=%s\n", str1);

return 0;
}

14.3 运行结果

15. strchr

15.1 函数说明

函数声明 函数功能
char* strchr(const char* str, int c); 用于查找字符串中第一次出现指定字符的位置,并返回该位置的指针

参数:

  • src : 要查找的字符串
  • c: 要查找的字符,是一个整数值

15.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include <string.h>

int main()
{
char str[] = "Hello world";
char* p;

p = strchr(str, 'o');

if (p != NULL) {
printf("Found character '%c' at position %ld\n", *p, p - str);
}
else {
printf("Character not found.\n");
}

return 0;
}

注意: strchr() 函数只能查找单个字符,如果要查找一个子字符串,应使用 strstr() 函数代替。另外,在查找字符时,需要将字符转换为整数值传递给 strchr() 函数,以避免发生类型错误。

15.3 运行结果

16. strcmp

16.1 函数说明

函数声明 函数功能
int strcmp(const char* str1, const char* str2); 用于比较两个字符串是否相等

参数:

  • str1 : 要比较的第一个字符串
  • str2 : 要比较的第二个字符串

返回值: 一个整数,表示两个字符串之间的大小关系

  • 如果 str1 小于 str2,则返回负整数;
  • 如果 str1 大于 str2,则返回正整数;
  • 如果 str1 等于 str2,则返回 0。

16.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <string.h>

int main()
{
char str1[] = "hello World";
char str2[] = "hello world";

int result = strcmp(str1, str2);

if (result < 0) {
printf("'%s' is less than '%s'\n", str1, str2);
}
else if (result 0) {
printf("'%s' is greater than '%s'\n", str1, str2);
}
else {
printf("'%s' is equal to '%s'\n", str1, str2);
}

return 0;
}

16.3 运行结果

17. strcpy

17.1 函数说明

函数声明 函数功能
char* strcpy(char* dest, const char* src); 用于将一个字符串复制到另一个字符串缓冲区中

参数:

  • dest : 目标字符串的缓冲区,必须具有足够的空间来存储源字符串
  • src : 要复制的源字符串

返回值: 一个指向目标字符串结尾的指针

17.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
#include <string.h>

int main() {
char src[] = "Hello world";
char dest[32];

strcpy(dest, src);

printf("Source string: %s\n", src);
printf("Destination string: %s\n", dest);

return 0;
}

注意: strcpy() 函数只能用于复制以 \0 结尾的字符串,否则可能导致未定义的行为或内存损坏。在调用 strcpy() 函数之前,应确保目标字符串缓冲区具有足够的空间来容纳源字符串,以避免发生缓冲区溢出。

17.3 运行结果

18. strcspn

18.1 函数说明

函数声明 函数功能
size_t strcspn(const char* str, const char* charset); 用于查找字符串中第一次出现指定字符集合中任何字符的位置,并返回该位置的索引

参数:

  • src : 要查找的字符串
  • charset : 要查找的字符集合

18.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
#include <string.h>

int main()
{
char str[] = "Hello world";
char charset[] = "owd";

size_t index = strcspn(str, charset);

if (index != strlen(str))
{
printf("Found character '%c' at position %ld\n", str[index], index);
}
else
{
printf("No matching characters found.\n");
}

return 0;
}

在上述的示例代码中,我们使用 strcspn() 函数在字符串 "Hello world" 中查找字符集合 "owd" 中的任何字符,并输出找到的字符及其在字符串中的位置索引。

18.3 运行结果

总览

函数声明 函数功能
void setlinestyle( int linestyle, unsigned upattern, int thickness ); 设置当前绘图窗口的线条样式、线型模式和线条宽度
void *setmem(void *dest, size_t n, int c); 用于将指定内存区域的每个字节都设置为指定的值
int setmode(int fd, int mode); 它是 Windows 系统下的特定库函数,用于将指定文件的 I/O 模式设置为文本模式或二进制模式
void setpalette(int colornum, int color); 设置调色板的颜色
void setrgbpalette(int colornum, int red, int green, int blue); 用于设置当前绘图窗口的调色板中某个颜色的 RGB
void settextjustify(int horiz, int vert); 用于设置文本输出的对齐方式
void settextstyle(int font, int direction, int charsize); 用于设置当前文本输出的字体、方向和大小
void settime(struct time *timep); 设置当前系统时间
void setusercharsize(int multx, int dirx, int multy, int diry); 用于设置用户定义的字符大小
int setvbuf(FILE *stream, char *buf, int type, unsigned size); 用于设置文件流的缓冲方式
void setviewport(int left, int top, int right, int bottom, int clipflag); 用于设置绘图窗口的视口范围
void setvisualpage(int pagenum); 用于设置图形窗口中用户可见的页面
void setwritemode(int mode); 用于设置绘画操作的写入模式
void (*signal(int signum, void (*handler)(int)))(int); 用于设置指定信号的处理方式。当系统接收到某个信号时,会调用相应的信号处理函数来处理该信号。在调用 signal 函数时,需要指定要处理的信号以及相应的信号处理函数。
double sin(double x); 用于计算一个角度(以弧度为单位)的正弦值(double)
float sinf(float x); 用于计算一个角度(以弧度为单位)的正弦值(float)
long double sinl(long double x); 用于计算一个角度(以弧度为单位)的正弦值(long double)
void sincos(double x, double* sinVal, double* cosVal); 用于同时计算一个角度(以弧度为单位)的正弦值和余弦值
void sincosf(float x, float* sinVal, float* cosVal); 用于同时计算一个角度(以弧度为单位)的正弦值和余弦值
void sincosl(long double x, long double* sinVal, long double* cosVal); 用于同时计算一个角度(以弧度为单位)的正弦值和余弦值
double sinh(double x); 用于计算一个数的双曲正弦值
float sinhf(float x); 用于计算一个数的双曲正弦值
long double sinhl(long double x); 用于计算一个数的双曲正弦值

1. setlinestyle

1.1 函数说明

函数声明 函数功能
void setlinestyle( int linestyle, unsigned upattern, int thickness ); 设置当前绘图窗口的线条样式、线型模式和线条宽度

参数:

  • linestyle : 线条样式,取值范围为 0 到 4,不同的值对应着不同的线条样式,详见如下表格
  • upattern : 线型模式,它是一个 16 位的无符号整数,用二进制位表示线型模式,其中 1 表示绘制线条,0 表示空白。例如,如果 upattern 的值是 0x00FF,则表示绘制一段线条,然后空白一段,重复这个过程直到结束。如果 upattern 的值是 0x5555,则表示绘制一段虚线。
  • thickness : 线条宽度,取值范围为 1 到 10,表示线条的像素宽度
线条样式 描述
SOLID_LINE 0 实线
DOTTED_LINE 1 虚线
CENTER_LINE 2 点线
DASHED_LINE 3 长短线
USERBIT_LINE 4 双点线

1.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <graphics.h>
#include <string.h>

/* the names of the line styles supported */
char *lname[] = {
"SOLID_LINE",
"DOTTED_LINE",
"CENTER_LINE",
"DASHED_LINE",
"USERBIT_LINE"
};

int main(void)
{
int gdriver = DETECT, gmode;

int style, midx, midy, userpat;
char stylestr[40];

initgraph(&gdriver, &gmode, "");

midx = getmaxx() / 2;
midy = getmaxy() / 2;

userpat = 1;

for (style=SOLID_LINE; style<=USERBIT_LINE; style++)
{
setlinestyle(style, userpat, 1);

strcpy(stylestr, lname[style]);

line(0, 0, midx-10, midy);

rectangle(100, 100, getmaxx() - 100, getmaxy() - 100);

outtextxy(midx, midy, stylestr);

getch();
cleardevice();
}

closegraph();
return 0;
}

1.3 运行结果

2. setmem

2.1 函数说明

函数声明 函数功能
void *setmem(void *dest, size_t n, int c); 用于将指定内存区域的每个字节都设置为指定的值

参数:

  • dest : 要设置的内存区域的指针
  • n : 要设置的字节数
  • c : 要设置的值

·注意: setmem() 并不是标准 C 函数,而是 POSIX 标准库函数,因此可能并不被所有平台所支持。如果您的编译器或操作系统不支持 setmem() 函数,可以使用标准 C 库函数 memset() 来代替

2.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
char *str = (char *)malloc(10); // 分配 10 字节的内存空间

// 将 str 中的每个字节都设置为 'A'
setmem(str, 10, 'A');

printf("%s\n", str);

free(str);

return 0;
}

在上面的示例程序中,

  • 我们首先使用 malloc() 函数分配了 10 字节的内存空间,并将其赋值给指针变量 str。
  • 然后,我们使用 setmem() 函数将 str 指向的内存区域的每个字节都设置为 'A'
  • 最后,我们输出 str 的内容并使用 free() 函数释放了分配的内存空间。

3. setmode

3.1 函数说明

函数声明 函数功能
int setmode(int fd, int mode); 它是 Windows 系统下的特定库函数,用于将指定文件的 I/O 模式设置为文本模式或二进制模式

参数:

  • fd : 要设置模式的文件描述符,通常使用 fileno() 函数将文件指针转换为文件描述符
  • mode : 要设置的模式,它可以取以下两个值中的一个:
    • _O_BINARY:二进制模式
    • _O_TEXT:文本模式

注意:Windows 系统中,文本模式和二进制模式之间的区别在于换行符的处理方式。在文本模式下,Windows 将回车符(\r)和换行符(\n)组成的字符序列映射为单个换行符(\n),因此在读取文本文件时可以正确处理换行符。在二进制模式下,Windows 不对回车符和换行符做任何转换,因此在读取文本文件时可能会出现问题。

3.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
#include <fcntl.h>

int main()
{
int result;
result = setmode(fileno(stdin), O_TEXT);
if (result == -1)
perror("Mode not available\n");
else
printf("Mode successfully switched\n");
return 0;
}

在上面的示例程序中,我们首先使用 setmode() 函数将标准输入流的模式从二进制模式切换到文本模式;如果调用成功,则返回 0,否则返回 -1,并将错误信息存储在全局变量 errno 中。在程序中,我们使用 perror() 函数来输出错误信息。如果调用成功,则输出一条提示信息。

注意: setmode() 函数只适用于 Windows 系统下的 C/C++ 编程,并且不是标准库函数,因此在跨平台编程时应该避免使用它。在 Unix/Linux 系统下,也可以使用 fcntl() 函数来设置文件描述符的模式。

3.3 运行结果

4. setpalette

4.1 函数说明

函数声明 函数功能
void setpalette(int colornum, int color); 设置调色板的颜色

参数:

  • colornum : 要设置的调色板中的颜色数量
  • color : 是一个整数类型的值,用于表示调色板中的颜色。这个参数可以是一个 RGB 值,也可以是一个预定义颜色名称,例如 REDBLUE

4.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <graphics.h>

int main()
{
int gd = DETECT, gm;
initgraph(&gd, &gm, "");

// 将第 5 种颜色设置为红色
setpalette(5, RED);

// 绘制一条红色的直线
setcolor(5);
line(100, 100, 200, 100);

getch();
closegraph();
return 0;
}

4.3 运行结果

5. setrgbpalette

5.1 函数说明

函数声明 函数功能
void setrgbpalette(int colornum, int red, int green, int blue); 用于设置当前绘图窗口的调色板中某个颜色的 RGB

参数:

  • colornum : 要修改的颜色索引,取值范围为 0~255
  • red、green 和 blue 要设置的 RGB 值,取值范围为 0~255

5.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <graphics.h>

int main()
{
int gd = DETECT, gm;
initgraph(&gd, &gm, "");

setbkcolor(WHITE);
cleardevice();

// 将第 5 种颜色设置为蓝绿色
setrgbpalette(5, 0, 128, 128);

// 绘制一条蓝绿色的斜线
setcolor(5);
line(100, 100, 200, 200);

getch();
closegraph();
return 0;
}

在上述的这个示例程序中,

  • 我们首先使用 setbkcolor() 函数设置背景颜色为白色,然后清除原有屏幕使前面设置生效。
  • 接着我们使用 setrgbpalette() 函数将第 5 种颜色设置为蓝绿色,并使用 setcolor() 函数将绘图颜色设为索引值 5(即蓝绿色);
  • 最后使用 line() 函数绘制了一条斜线。

5.3 运行结果

6. settextjustify

6.1 函数说明

函数声明 函数功能
void settextjustify(int horiz, int vert); 用于设置文本输出的对齐方式

参数:

  • horiz : 水平对齐方式,可以取以下值:
    • LEFT_TEXT:左对齐
    • CENTER_TEXT:居中对齐
    • RIGHT_TEXT:右对齐
  • vert : 垂直对齐方式,可以取以下值:
    • TOP_TEXT:顶部对齐
    • CENTER_TEXT:居中对齐
    • BOTTOM_TEXT:底部对齐

6.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <graphics.h>

int main()
{
int gd = DETECT, gm;
initgraph(&gd, &gm, "");

// 设置文本输出的对齐方式为居中对齐
settextjustify(CENTER_TEXT, CENTER_TEXT);

// 输出一行居中对齐的文本
outtextxy(getmaxx() / 2, getmaxy() / 2, "Hello, world!");

getch();
closegraph();
return 0;
}

在上述的示例程序中,我们使用 settextjustify() 函数将文本输出的对齐方式设置为居中对齐,然后使用 outtextxy() 函数在窗口的中心输出一行文本。

注意: 在使用 settextjustify() 函数设置对齐方式时,必须指定正确的参数值,并且同时考虑水平和垂直方向的对齐方式,否则可能会导致文本输出位置错误。

6.3 运行结果

7. settextstyle

7.1 函数说明

函数声明 函数功能
void settextstyle(int font, int direction, int charsize); 用于设置当前文本输出的字体、方向和大小

参数:

  • font : 要使用的字体编号,可以取以下值:
    • DEFAULT_FONT:默认字体
    • TRIPLEX_FONT:粗体三线字体
    • SMALL_FONT:小号字体
    • SANS_SERIF_FONT:无衬线字体
    • GOTHIC_FONT:哥特式字体
    • SCRIPT_FONT:手写字体
  • direction : 文本输出的方向,可以取以下值:
    • HORIZ_DIR:水平方向(从左到右)
    • VERT_DIR:垂直方向(从下到上)
  • horiz : 水平对齐方式,可以取以下值:
    • DEFAULT_WIDTHDEFAULT_HEIGHT:默认大小
    • TRIPLEX_WIDTHTRIPLEX_HEIGHT:大号尺寸
    • SMALL_WIDTHSMALL_HEIGHT:小号尺寸

7.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <graphics.h>

int main()
{
int gd = DETECT, gm;
initgraph(&gd, &gm, "");

// 设置文本输出的字体、方向和大小
settextstyle(TRIPLEX_FONT, HORIZ_DIR, 4);

// 输出一行文本
outtextxy(100, 100, "Hello, world!");

getch();
closegraph();
return 0;
}

在上述的示例程序中,我们使用 settextstyle() 函数将文本输出的字体设置为粗体三线字体、方向设置为水平方向、大小设置为大号尺寸,然后使用 outtextxy() 函数在窗口的指定位置输出一行文本。

注意: 在使用 settextstyle() 函数设置文本样式时,必须指定正确的参数值,并且根据具体需求灵活选择字体、方向和大小,否则可能会导致文本输出不符合预期。

7.3 运行结果

8. settime

8.1 函数说明

函数声明 函数功能
void settime(struct time *timep); 设置当前系统时间
参数:
  • timep : 用于存储当前系统时间的结构体变量

8.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <dos.h>

int main(void)
{
struct time t;

gettime(&t);
printf("The current minute is: %d\n", t.ti_min);
printf("The current hour is: %d\n", t.ti_hour);
printf("The current hundredth of a second is: %d\n", t.ti_hund);
printf("The current second is: %d\n", t.ti_sec);

t.ti_min++;
settime(&t);

return 0;
}

在上述的程序中,

  • 我们首先定义了一个 struct time 类型的变量 t,用于存储当前系统时间。然后使用 gettime() 函数获取当前时间,并将小时、分钟、秒和百分之一秒等信息存储到 t 变量的对应成员变量中。
  • 接着,程序使用 printf() 函数输出了当前的分钟数、小时数、百分之一秒数和秒数。这里使用了 %d 占位符来指定输出整数类型的值。
  • 最后,程序将 t 变量的分钟数加上了 1,然后使用 settime() 函数将修改后的时间写入系统时钟中。

注意 : 这个程序依赖于 DOS 系统提供的日期和时间相关函数,可能无法在其他操作系统或环境下运行。此外,直接修改系统时间可能会对计算机的正常运行产生影响,因此应该谨慎使用。
在现代的 Windows 操作系统中,DOS 环境已经被废弃,因此这个程序可能无法正常工作。如果要获取和修改当前系统时间,可以使用操作系统提供的相关 API 或系统调用接口实现。例如,在 Windows 平台上,可以使用 GetSystemTime()SetSystemTime() 等函数来获取和设置系统时间。

9. setusercharsize

9.1 函数说明

函数声明 函数功能
void setusercharsize(int multx, int dirx, int multy, int diry); 用于设置用户定义的字符大小

参数:

  • multx : 水平放大倍数,取值为正整数
  • dirx : 水平方向,取值为 1-1。当 dirx 的值为 1 时,字符不进行左右翻转;当 dirx 的值为 -1 时,字符进行左右翻转
  • multy : 垂直放大倍数,取值为正整数
  • diry : 垂直方向,取值为 1-1。当 diry 的值为 1 时,字符不进行上下翻转;当 diry 的值为 -1 时,字符进行上下翻转。

9.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <graphics.h>

int main()
{
int gd = DETECT, gm;
initgraph(&gd, &gm, "");

// 设置字符的大小为水平方向放大 2 倍、垂直方向放大 3 倍
setusercharsize(2, 1, 3, 1);

// 输出一行文本
outtextxy(100, 100, "Hello, world!");

getch();
closegraph();
return 0;
}

在上述这个示例程序中,我们使用 setusercharsize() 函数将当前字符的大小设置为水平方向放大 2 倍、垂直方向放大 3 倍,然后使用 outtextxy() 函数在窗口的指定位置输出一行文本。

注意: 在使用 setusercharsize() 函数设置字符大小时,必须指定正确的参数值,并且考虑到水平和垂直方向的缩放倍数,否则可能会导致字符输出不符合预期。

9.3 运行结果

10. setvbuf

10.1 函数说明

函数声明 函数功能
int setvbuf(FILE *stream, char *buf, int type, unsigned size); 用于设置文件流的缓冲方式

参数:

  • stream : 要设置缓冲方式的文件指针,可以是标准输入流(stdin)、标准输出流(stdout)或标准错误流(stderr),也可以是通过 fopen() 函数打开的文件指针
  • buf : 缓冲区指针,可以是一个已经分配好的缓冲区,也可以是 NULL。如果 buf 参数为 NULL,则 setvbuf() 函数将自动为文件流分配一块缓冲区
  • type : 缓冲类型,可以取以下值:
    • _IONBF:不使用缓冲区,直接从或向设备读写数据
    • _IOLBF:行缓冲,每行数据结束后刷新缓冲区
    • _IOFBF:全缓冲,填满缓冲区后才进行读写操作
  • size: 缓冲区大小,如果 buf 参数不为 NULL,则 size 参数指定了缓冲区大小;如果 buf 参数为 NULL,则 size 参数指定了系统为缓冲区分配的大小。size 参数只对全缓冲方式有效,行缓冲和无缓存方式忽略该参数

10.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>

int main(void)
{
FILE *input, *output;
char bufr[512];

input = fopen("file.in", "r+b");
output = fopen("file.out", "w");

if (setvbuf(input, bufr, _IOFBF, 512) != 0)
printf("failed to set up buffer for input file\n");
else
printf("buffer set up for input file\n");

if (setvbuf(output, NULL, _IOLBF, 132) != 0)
printf("failed to set up buffer for output file\n");
else
printf("buffer set up for output file\n");

fclose(input);
fclose(output);
return 0;
}

在上述的示例程序中,

  • 我们首先定义了两个文件指针变量 inputoutput,分别表示输入文件和输出文件。
  • 然后调用 fopen() 函数打开输入文件和输出文件,并将返回的文件指针保存到对应的变量中。
  • 接着,程序使用 setvbuf() 函数分别为输入文件和输出文件设置缓冲方式。对于输入文件,使用 _IOFBF 缓冲类型和大小为 512 字节的缓冲区;对于输出文件,使用 _IOLBF 缓冲类型和大小为 132 字节的缓冲区(此处 bufr 缓冲区为空指针)。在设置完缓冲方式后,程序根据 setvbuf() 函数的返回值判断是否设置成功,如果返回值不为 0,则说明设置失败,否则说明设置成功,并输出相应的提示信息。
  • 最后,程序使用 fclose() 函数关闭输入文件和输出文件。

注意: 在使用文件流进行读写操作时,必须在适当的时候进行缓冲区清理操作,以避免数据丢失或者读取到过期数据等问题。另外,需要根据具体需求选择合适的缓冲方式和缓冲区大小,以实现最优的性能和稳定性。

10.3 运行结果

11. setviewport

11.1 函数说明

函数声明 函数功能
void setviewport(int left, int top, int right, int bottom, int clipflag); 用于设置绘图窗口的视口范围

参数:

  • left : 视口矩形的左上角横坐标,取值为正整数或 0
  • top: 视口矩形的左上角纵坐标,取值为正整数或 0
  • right: 视口矩形的右下角横坐标,取值为正整数
  • bottom: 视口矩形的右下角纵坐标,取值为正整数
  • clipflag: 裁剪标志,可以取以下值:
    • CLIP_ON:开启裁剪模式,只显示视口内的图形;
    • CLIP_OFF:关闭裁剪模式,显示整个画面。

11.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <graphics.h>

#define CLIP_ON 1

int main()
{
int gd = DETECT, gm;
initgraph(&gd, &gm, "");

setcolor(RED);
rectangle(100, 100, 300, 200);

// 将视口范围设置为矩形 (150, 150) - (250, 250)
setviewport(150, 150, 250, 250, CLIP_ON);

setcolor(GREEN);
rectangle(0, 0, 400, 300);

getch();
closegraph();
return 0;
}

在上面的示例程序中,

  • 我们首先使用 rectangle() 函数绘制了一个红色的矩形;
  • 然后使用 setviewport() 函数将视口范围设置为矩形 (150, 150) - (250, 250);
  • 最后使用 rectangle() 函数绘制了一个绿色的矩形,但这里只有在视口范围的矩形才显示出来。

注意: 在使用 setviewport() 函数设置视口范围时,必须指定正确的参数值,并考虑到裁剪模式的影响,否则可能会导致图形显示不符合预期。

11.3 运行结果

12. setvisualpage

12.1 函数说明

函数声明 函数功能
void setvisualpage(int pagenum); 用于设置图形窗口中用户可见的页面

参数:

  • pagenum : 要设置的可视化页面页码,整数类型。

在双缓冲绘图中,我们通常会使用两个页面来绘制图像,一个是前台页面,另一个是后台页面。当我们绘制完一个完整的画面时,可以通过调用 setactivepage() 函数将后台页面切换到前台页面以显示出来。而 setvisualpage() 函数则用于设置用户当前看到的页面,它实际上是将指定的页面置于前台,从而更新屏幕上显示的内容。

12.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <graphics.h>

int main(void)
{
int gdriver = EGA, gmode = EGAHI;
int x, y, ht;

initgraph(&gdriver, &gmode, "");

x = getmaxx() / 2;
y = getmaxy() / 2;
ht = textheight("W");

setactivepage(1);

line(0, 0, getmaxx(), getmaxy());

settextjustify(CENTER_TEXT, CENTER_TEXT);
outtextxy(x, y, "This is page #1:");
outtextxy(x, y+ht, "Press any key to halt:");

setactivepage(0);

outtextxy(x, y, "This is page #0.");
outtextxy(x, y+ht, "Press any key to view page #1:");
getch();

setvisualpage(1);

getch();
closegraph();
return 0;
}

上述示例将在屏幕上绘制两个页面,并允许用户通过按任意键查看第二个页面。

注意: setvisualpage() 函数只能用于已经创建的图形窗口,且参数 pagenum 必须在 0getmaxpages() 函数返回值之间。

12.3 运行结果

13. setwritemode

13.1 函数说明

函数声明 函数功能
void setwritemode(int mode); 用于设置绘画操作的写入模式

参数:

  • mode: 要设置的写入模式,整数类型。常用的写入模式有以下三种:
    • COPY_PUT:0,复制模式(默认),新绘制的图形将完全覆盖旧图形
    • XOR_PUT:1,异或模式,新绘制的图形将与旧图形进行异或运算后显示。在这种模式下,如果一个像素既在新图形中出现过,也在旧图形中出现过,则它最终不会被显示出来;如果一个像素只在新图形中出现过,或者只在旧图形中出现过,则它将会被显示出来。
    • OR_PUT:2,或模式,新绘制的图形将与旧图形进行或运算后显示。在这种模式下,如果一个像素既在新图形中出现过,也在旧图形中出现过,则它最终会被显示出来;如果一个像素只在新图形中出现过,或者只在旧图形中出现过,则它将会被显示出来。

13.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <graphics.h>

int main()
{
int gdriver = DETECT, gmode;
int xmax, ymax;

initgraph(&gdriver, &gmode, "");

xmax = getmaxx();
ymax = getmaxy();

setwritemode(XOR_PUT);

line(0, 0, xmax, ymax);
getch();

line(0, 0, xmax, ymax);
getch();

setwritemode(COPY_PUT);

line(0, 0, xmax, ymax);

getch();
closegraph();
return 0;
}

注意: setwritemode() 函数只对紧随其后的绘画操作生效,它不会影响之前已经绘制的图形。因此,在更改写入模式之前,必须先完成之前的绘画操作。

13.3 运行结果

14. signal

14.1 函数说明

函数声明 函数功能
void (*signal(int signum, void (*handler)(int)))(int); 用于设置指定信号的处理方式。当系统接收到某个信号时,会调用相应的信号处理函数来处理该信号。在调用 signal 函数时,需要指定要处理的信号以及相应的信号处理函数。

参数:

  • signum : 要设置的信号编号,整数类型。常见的信号有很多种,如:
    • SIGINT(中断信号):通常由用户按下 “Ctrl + C“ 产生,用于中断正在运行的程序。
    • SIGALRM(闹钟信号):用于在指定的时间后向进程发送信号,可以用于实现定时器等功能。
    • SIGFPE(浮点异常信号):在发生浮点运算异常时发送该信号。
    • SIGSEGV(段错误信号):在访问非法的内存地址时发送该信号。
  • handler : 要设置的信号处理函数,是一个指向函数的指针,其形式为 void handler(int)

返回值:

  • 如果调用成功,返回之前对信号的处理方式(通常是一个函数指针)。如果之前没有设置过该信号的处理方式,返回默认的处理方式(通常是 SIG_DFLSIG_IGN)。
  • 如果调用失败,返回 SIG_ERR

14.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

void sigint_handler(int sig) {
printf("Caught signal %d\n", sig);
exit(0);
}

int main() {
signal(SIGINT, sigint_handler);

while (1) {
printf("Doing something...\n");
getchar();
// check for interrupt signal
raise(SIGINT);
}

return 0;
}

在上面的示例中,

  • 我们首先使用 signal() 函数设置了一个处理 SIGINT 信号的处理程序 sigint_handler()
  • 然后,在主循环中,我们随意输入一个字符后,就使用 raise() 函数向当前正在运行的进程发送 SIGINT 信号。当收到 SIGINT 信号时,程序将打印一条消息并退出。

14.3 运行结果

15. significand,significandf

15.1 函数说明

函数声明 函数功能
double significand(double x); 用于分离浮点数 x 的尾数部分(double)
float significandf(float x); 用于分离浮点数 x 的尾数部分(float)

参数:

  • x : 要求尾数的浮点数。

15.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
#include <math.h>

int main()
{
double x = 123.456789;
float y = -2.5;

printf("The significand of %lf is %lf\n", x, significand(x));
printf("The significand of %f is %f\n", y, significandf(y));

return 0;
}

注意: 在某些旧版本的编译器中,可能没有实现 significand 函数。这个时候可以考虑使用其他类似的函数来替代,如 frexpmodf 等。

16. sin,sinf,sinl

16.1 函数说明

函数声明 函数功能
double sin(double x); 用于计算一个角度(以弧度为单位)的正弦值(double)
float sinf(float x); 用于计算一个角度(以弧度为单位)的正弦值(float)
long double sinl(long double x); 用于计算一个角度(以弧度为单位)的正弦值(long double)

参数:

  • x : 要求正弦值的角度,以弧度为单位

16.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
#include <math.h>

int main()
{
double x = M_PI / 6.0; // M_PI 圆周率
float y = M_PI / 4.0L;
long double z = M_PI / 3.0L;

printf("sin(%lf) = %lf\n", x, sin(x));
printf("sinf(%f) = %f\n", y, sinf(y));
printf("sinl(%Lf) = %Lf\n", z, sinl(z));

return 0;
}

16.3 运行结果

17. sincos,sincosf,sincosl

17.1 函数说明

函数声明 函数功能
void sincos(double x, double* sinVal, double* cosVal); 用于同时计算一个角度(以弧度为单位)的正弦值和余弦值
void sincosf(float x, float* sinVal, float* cosVal); 用于同时计算一个角度(以弧度为单位)的正弦值和余弦值
void sincosl(long double x, long double* sinVal, long double* cosVal); 用于同时计算一个角度(以弧度为单位)的正弦值和余弦值

参数:

  • x : 要求正弦值和余弦值的角度,以弧度为单位
  • sinVal : 存放计算得到的正弦值的指针
  • cosVal : 存放计算得到的余弦值的指针

17.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
#include <math.h>

int main()
{
double x = M_PI / 6.0;
float y = M_PI / 4.0L;
long double z = M_PI / 3.0L;

double sinVal, cosVal;
float sinfVal, cosfVal;
long double sinlVal, coslVal;

sincos(x, &sinVal, &cosVal);
sincosf(y, &sinfVal, &cosfVal);
sincosl(z, &sinlVal, &coslVal);

printf("sincos(%lf) = (%lf, %lf)\n", x, sinVal, cosVal);
printf("sincosf(%f) = (%f, %f)\n", y, sinfVal, cosfVal);
printf("sincosl(%Lf) = (%Lf, %Lf)\n", z, sinlVal, coslVal);

return 0;
}

17.3 运行结果

18. sinh,sinhf,sinhl

18.1 函数说明

函数声明 函数功能
double sinh(double x); 用于计算一个数的双曲正弦值
float sinhf(float x); 用于计算一个数的双曲正弦值
long double sinhl(long double x); 用于计算一个数的双曲正弦值

参数:

  • x : 要求双曲正弦值的数,以弧度为单位

18.2 演示示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
#include <math.h>

int main()
{
double x = 1.0;
float y = 2.0;
long double z = 3.0;

printf("sinh(%lf) = %lf\n", x, sinh(x));
printf("sinhf(%f) = %f\n", y, sinhf(y));
printf("sinhl(%Lf) = %Lf\n", z, sinhl(z));

return 0;
}

18.3 运行结果

0%