一.结构体、枚举与联合(Structure,Enumeration & Union)

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
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <stdbool.h>

// 枚举Enumeration
// 可替代多个#define

// 联合Union
// 它允许在相同的内存位置存储不同的数据类型。
// 联合体的所有成员共享一块内存空间,大小等于其最大成员的大小。
// 这就意味着在任一时刻,联合体只能存储一个成员的值

// 一个变量可能存储多种类型的数据,但是在一个给定时刻里,只是用其中一种的数据类型,这样可以节省内存。

typedef union
{
int int_value;
float float_value;
char* string_value;
} Data;

typedef enum
{
INT,
FLOAT,
STRING
} DataType;

typedef struct
{
DataType type;
Data data;
} TypedData;

void print_data(TypedData* typed_data)
{
switch(typed_data->type)
{
case INT:
printf("Integer: %d\n",typed_data->data.int_value);;
break;
case FLOAT:
printf("Float: %f\n",typed_data->data.float_value);
break;
case STRING:
printf("String: %s\n",typed_data->data.string_value);
break;
}
}
// 实现了三者的联用。自己定义一个类型,并按照不同类型去输出;也就是说我想要什么类型就可以做出什么类型,十分灵活。
// Union可以存储不同的数据类型,那我们可以通过这种方式来去控制它什么时候是什么类型
int main(void)
{
TypedData data1 = {INT,{.int_value = 10}}; //我们.这样的写法意思就是它自己data.···

TypedData data2 = {FLOAT,{.float_value = 3.14}};

TypedData data3 = {INT,{.string_value = "Hello,Chaos!"}};

print_data(&data1);
print_data(&data2);
print_data(&data3);

return 0;
}

二.VS编译器捕获字符串异常的简单方法

Release方式运行

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
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <crtdbg.h>

void my_invalid_pram_handler(const wchar_t* expression,const wchar_t* function,const wchar_t* file,unsigned int line,uimtptr_t p_reserved)
{
wprintf(L"Invalid parameter detected in function %s. File: %s Line %d\n",function,file,line);
wprintf(L"Expression: %s\n",expression);
}

int main()
{
_set_invalid_parameter_handler(my_invalid_parm_handler);

const char src[] = "Hello";

char dest[2];

erron_t err = strcpy_s(dest,sizeof(dest),src); // strcpy_s有一个返回值叫作errno_t,实际上是个int整形

if(err != 0)
{
printf("Error copying string. Error code: %d\n",err);
}
else
{
printf("%s\n",dest);
}

return 0;
}

三.字符串函数

非法字符匹配

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 验证一个字符串是否有非法的那些字符(重命名)
#include <string.h>
#include <stdio.h>

int main(void)
{
char input[] = "filename.txt";

char invalid_chars[] = "/\\:*?\"<>|";

if(strcspn(input,invalid_chars) < strlen(input))
{
printf("Input contains invalid characters.\n");
}
else
{
printf("Input is valid.");
}
return 0;
}

常用函数案例

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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define TEXT_SIZE 100
#define WORD_SIZE 50
#define DELIMS ",.!?\n "

void replaceWord(const char* text, const char* oldWord, const char* newWord, char* result);
int countChar(const char* text, char ch);
int countWords(const char* text);
void extractUniqueWords(const char* text, char uniqueWords[][WORD_SIZE], int* uniqueCount);


int main(void)
{
char text[TEXT_SIZE] = "This is a simple text.This text is for texting.";

char replacedText[TEXT_SIZE] = { 0 };
char oldWord[] = "text";
char newWord[] = "example";
char countCharTarget = 's';

char uniqueWords[TEXT_SIZE][WORD_SIZE] = { 0 };
int uniqueCount = 0;

replaceWord(text, oldWord, newWord, replacedText);
printf("Repaced Text : %s\n", replacedText);

int charCount = countChar(replacedText, countCharTarget);
printf("Character '%c' appears %d times.\n", countCharTarget, charCount);

int wordCount = countWords(replacedText);
printf("Total number of words: %d\n", wordCount);

extractUniqueWords(replacedText, uniqueWords, &uniqueCount);
puts("Unique words:");

for (int i = 0; i < uniqueCount; i++)
{
printf("%s\n", uniqueWords[i]);
}

return 0;
}

void replaceWord(const char* text, const char* oldWord, const char* newWord, char* result)
{
char buffer[TEXT_SIZE] = { 0 };
const char* pos = text;
const char* temp = text;
size_t oldlen = strlen(oldWord);

while ((temp = strstr(pos, oldWord)) != NULL)
{
strncat_s(buffer, sizeof(buffer), pos, temp - pos);
strcat_s(buffer, sizeof(buffer), newWord);

pos = temp + oldlen;
}

strcat_s(buffer, sizeof(buffer), pos);
strcpy_s(result, TEXT_SIZE, buffer);
}

int countChar(const char* text, char ch)
{
int count = 0;
while (*text)
{
if (*text == ch)
{
count++;
}
text++;
}
return count;
}

int countWords(const char* text)
{
int count = 0;
char buffer[TEXT_SIZE] = { 0 };

strcpy_s(buffer, TEXT_SIZE, text);

char* context = NULL;

char* token = strtok_s(buffer, DELIMS, &context);

while (token != NULL)
{
count++;
token = strtok_s(NULL, DELIMS, &context);
}
return count;
}

void extractUniqueWords(const char* text, char uniqueWords[][WORD_SIZE], int* uniqueCount)
{
char tempText[TEXT_SIZE] = { 0 };
strcpy_s(tempText, TEXT_SIZE, text);

char* context = NULL;
char* token = strtok_s(tempText, DELIMS, &context);

while (token != NULL)
{
int found = 0;

for (int j = 0; j < *uniqueCount; ++j)
{
if (strcmp(token, uniqueWords[j]) == 0)
{
found = 1;
break;
}
}

if (!found)
{
strcpy_s(uniqueWords[*uniqueCount], WORD_SIZE, token);
(*uniqueCount)++;
}
token = strtok_s(NULL, DELIMS, &context);
}
}

四.文件

安全读取配置文件

game_config.txt

1
2
3
4
5
6
7
8
# Game Configuration File

GraphicsQuality=High
FullScreen=true
Resolution=1920x1080
AudioShadows-true
MaxNPCs=50
Language=English

run_app.c

1