字符串与内存

字符串

malloc

void *malloc(size_t size);

realloc

void* realloc(void *ptr, size_t size);

将ptr的内存空间大小调整为size,原地址后不够则重新开辟

strcpy

char *strcpy(char * dest, char * src);

返回值是dest, strcpy在复制字符串时会自动在末尾加上\0,

length(destsrc)1length(dest - src) \ge 1if(length(deststc)<1)perror("SegmentationFault")if(length(dest - stc) \lt 1) \\perror("Segmentation Fault")

strlen

size_t strlen(const char * str); from <string.h>

返回从第一个字符到第一个\0的长度(exclude \0)

example : strlen(“hello”) == 5;

strcat

char * strcat(char * dest, char * src);

返回值是dest,将src例存储的字符串接到dest后面,

strcmp

int strcmp(char * str1, char * str2);

if(returnval==0)表示str1str2完全相同;elseif(returnval>0)表示第一个分歧位置str1[i]>str2[i]elsestr1[i]<str2[i]if (returnval == 0) 表示str1和str2完全相同;\\ elseif(returnval > 0)表示第一个分歧位置str1[i] > str2[i]\\ else str1[i] < str2[i]

strtok

char *strtok(char *str, const char *delim);

常用于在处理输入值时, 将不同的参数分隔开。

这个函数将输入的字符串str用输入的分隔符分为更短的字符串。

delim是一个含有多个字符的字符串,每一个字符都是一个独立的分隔符,\n\t就是两个独立的分隔符,特别要注意的是,strtok会修改原有字符串,如果需要留原字符串,需要先strcpy拷贝一份再使用

image-20210313160659251

返回值:第一次调用返回第一个由非分隔符字符的指针的分隔片段,之后每一次调用,都使用NULL作为第一个参数,调用成功返回下一个分隔片段,当到达str末尾时返回NULL。

image-20210313160747517

理论上来说,上述函数可以实现linux里的wc,cut等对字符串分隔统计词频的功能。具体需要自己实践。

example 统计信中字符串中某一单词出现的次数,(蒜头君的情书)

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 <string.h>

const int MAX_LENGTH = 256;
//处理带换行符的字符串输入
char* get_letter(void) {
static char letter[1000000];
letter[999999] = ' ';
char *p = letter;
int size = MAX_LENGTH;
while (feof(stdin) == 0) {
if (size == 0) {
break;
}
fgets(p, size + 1, stdin);
while (*p != '\0') {
p++;
size--;
}
}
return letter;
}

int main() {
char *str = get_letter();
int strsize = strlen(str);
char *bakstr = malloc(sizeof(char) * strsize + 5);
strcpy(bakstr, str);
char *token = strtok(bakstr, "\n\t\r\n\"\',. ");
int ans = 0;
while (token != NULL) {
printf("%s\n", token);
if (strcmp(token, "love") == 0) ans++;
token = strtok(NULL, "\n\t\r\n\"\',. ");
}
free(bakstr);
printf("%d\n", ans);
puts(str);
return 0;

}

#undef MAX_LENGTH

[^在处理\n时由于windows和linux系统的差别,为了程序的鲁棒性,同时需要处理\r\n。]: windows下的点一下回车,效果是:回车换行,就是\r\n unix系统下的回车一下就是一个\n

具体看这里\r\n和\n的区别

内存

以下两个函数在string.h中。可以对指定任何位置的内存进行修改。

memset

void *memset(void *ptr, int value, size_t num);

从ptr开始,每一个字节都会被设置成value,通常设置0或-1。对在栈区申请的内存空间进行初始化。(全局变量申请是在堆中,无8Mb限制,切自动初始化)

memcpy

void *memcpy(void *dest, const void * source, size_t num);

将从source开始的长度为num字节的内存复制到dest中。

==在使用上述两个函数时,通常num需要配合sizeof使用。==

把6个整数从内存复制到另一个位置。

size_t num = 6 * sizeof(int)

mmap

void *mamp(void *addr, size_t length, int prot, int flags);

此函数用作文件到内存的映射。相比从用户空间和内核空间互相拷贝数据效率更高。