精华内容
下载资源
问答
  • c语言 拼接字符串
    2021-05-19 11:46:40

    C语言拼接字符串以及进制转换

    #include #include #include char *join1(char *, char*) ...

    C语言拼接字符串 -- 使用strcat()函数

    [头文件]#include [原型] char *strcat(char *dest, const char *src); [参数]: dest 为目标字符串指针,s ...

    C语言实现字符串拼接

    #include #include #include char* str_contact(const c ...

    iOS开发-OC语言 (三)字符串

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; text-align: center; font: 24.0px "PingFang SC" } p ...

    python拼接字符串方法汇总

    python拼接字符串一般有以下几种方法: 1.直接通过(+)操作符拼接 s = 'Hello'+' '+'World'+'!' print(s) 输出结果:Hello World! 这种方式最常用. ...

    Python拼接字符串的七种方式

    忘了在哪看到一位编程大牛调侃,他说程序员每天就做两件事,其中之一就是处理字符串.相信不少同学会有同感. 几乎任何一种编程语言,都把字符串列为最基础和不可或缺的数据类型.而拼接字符串是必备的一种技能.今 ...

    go语言之字符串、指针、数组、切片、结构struct、面向对象

    一: 字符串 概述: Go 语言将字符串作为 种原生的基本数据类型,字 符串的初始化可以使用字符串字面量. (1)字符串是常量,可以通过类 数组 索引访问其字节单元,但是不能修改某个字节的值 (2)宇 ...

    C函数 printf 拼接字符串

    C函数 printf 拼接字符串 从前学C语言,最常用的函数可能就是 printf 了,但是往往是这样: printf(年龄是:"%d",a); 由于不懂得怎么拼接字符串,有时候只 ...

    为什么 Java 8 中不再需要 StringBuilder 拼接字符串

    为什么 Java 8 中不再需要 StringBuilder 拼接字符串 来源:codeceo 发布时间:2016-12-27 阅读次数:427 0   在Java开发者中,字符串的拼接占用资源高往往 ...

    更多相关内容
  • C语言拼接字符串

    千次阅读 2021-05-19 08:03:57
    字符串拼接涉及两个字符串的合并。strcat函数经常用来执行这种操作,这个函数接受两个字符串指针作为参数,然后把两者拼接起来并返回拼接结果的指针。这个函数的原型如下:此函数把第二个字符串拼接到第一个的结尾,...

    字符串拼接涉及两个字符串的合并。strcat函数经常用来执行这种操作,这个函数接受两个字符串指针作为参数,然后把两者拼接起来并返回拼接结果的指针。这个函数的原型如下:

    此函数把第二个字符串拼接到第一个的结尾,第二个字符串是以常量char指针的形式传递的。函数不会分配内存,这意味着第一个字符串必须足够长,能容纳拼接后的结果,否则函数可能会越界写入,导致不可预期的行为。函数的返回值的地址跟第一个参数的地址一样。这在某些情况下比较方便,比如这个函数作为printf函数的参数时。

    为了说明这个函数的用法,我们会组合两个错误消息字符串。第一个是前缀,第二个是具体的错误消息。如下所示,我们首先在缓冲区中为两个字符串分配足够的内存,然后把第一个字符串复制到缓冲区,最后将第二个字符串和缓冲区拼接:

    我们给malloc函数的参数加1是为了容纳NUL字符。假设第一个字面量在内存中的位置就在第二个字面量前面,这段代码的输出会像下面这样。下图说明了内存分配情况。

    3a3147eaf33b3d011b31c9e79e51f61b.png

    如果我们没有为拼接后的字符串分配独立的内存,就可能会覆写第二个字符串,下面这个没有用到缓冲区的例子会说明这一点。我们仍然假设第一个字面量在内存中的位置就在第二个字面量前面:

    这段代码的输出如下:

    errorMessage字符串会左移一个字符,原因是拼接后的结果覆写了errorMessage。字面量"Not enough memory"紧跟在第一个字面量之后,因此覆写了第二个字面量。下图解释了这一点,字面量池的状态显示在左边,右边是复制操作后的状态。

    2b3b2ac2e29d18625257cf00da6ff8bf.png

    如果我们像下面这样用char数组而不是用指针来存储字符串,就不一定能工作了:

    如果用下面这个strcpy调用会得到一个语法错误,这是因为我们试图把函数返回的指针赋给数组名字,这类操作不合法:

    如果像下面这样去掉赋值,就可能会有内存访问的漏洞,因为复制操作会覆写栈帧的一部分。这里假设在函数内部声明数组,如图5-11所示。无论源字符串是存储在字符串字面量池中还是栈帧中,都不应该用来直接存放拼接后的结果,一定要专门为拼接结果分配内存:

    e5acdde78f6e7998e8bdcfd5d0a2d621.png

    拼接字符串时容易犯错的另一个地方是使用字符字面量而不是字符串字面量。在下例中,我们将一个字符串拼接到一个路径字符串后,这样是能如期工作的:

    因为额外的字符和NUL字符需要空间,我们在malloc调用中给字符串长度加了2。因为在字符串字面量中用了转义序列,所以这里拼接的是一个反斜杠字符。

    不过,如果使用字符字面量,如下所示,那么就会得到一个运行时错误,原因是第二个参数被错误地解释为char类型变量的地址1:

    展开全文
  • C语言拼接字符串的三种操作

    万次阅读 2018-12-28 20:10:09
    //注意,此时指针c已经指向拼接之后的字符串的结尾'\0' ! return tempc; //返回值是局部malloc申请的指针变量,需在函数调用结束后free。 } 方法二,直接改掉字符串a void join2(char *a, char *b) { //注意,...

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>

    char *join1(char *, char*);
    void join2(char *, char );
    char *join3(char *, char
    );

    int main(void) {
    char a[4] = "abc"; // char *a = "abc"
    char b[4] = "def"; // char *b = "def"
    
    char *c = join3(a, b);
    printf("Concatenated String is %s\n", c);
    
    free(c);
    c = NULL;
    
    return 0;
    }
    

    方法一,不改变字符串a,b, 通过malloc,生成第三个字符串c, 返回局部指针变量

    char *join1(char *a, char *b) {
    char *c = (char *) malloc(strlen(a) + strlen(b) + 1); 
    //局部变量,用malloc申请内存,strlen不算'\0',所以需要+1
    if (c == NULL) exit (1);
    char *tempc = c; //把首地址存下来
    while (*a != '\0') {
        *c++ = *a++;
    }
    while ((*c++ = *b++) != '\0') {
        ;
    }
    //注意,此时指针c已经指向拼接之后的字符串的结尾'\0' !
    return tempc;
    //返回值是局部malloc申请的指针变量,需在函数调用结束后free。
    }
    

    方法二,直接改掉字符串a

    void join2(char *a, char *b) {
    //注意,如果在main函数里a,b定义的是字符串常量(如下):
    //char *a = "abc";
    //char *b = "def";
    //那么join2是行不通的。
    //必须这样定义:
    //char a[4] = "abc";
    //char b[4] = "def";
    while (*a != '\0') {
        a++;
    }
    while ((*a++ = *b++) != '\0') ;
    }
    

    方法三,调用C库函数,

    char* join3(char *s1, char *s2)
    {
    char *result = malloc(strlen(s1)+strlen(s2)+1);
    if (result == NULL) exit (1);
    
    strcpy(result, s1);
    strcat(result, s2);
    
    return result;
    }
    
    展开全文
  • 今天小编就为大家分享一篇C语言实现将字符和数字到一起,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • 网络数据是以流的形式进行传输的(我们在构造客户端/服务端待发送数据时,肯定有特定的格式)。 关于发送一次,一个包的完整性可靠接收(tcp的...===》1:实现不同类型的数据拼接字符串的方案 (3.1) ===》2:char**通

    网络数据是以流的形式进行传输的(我们在构造客户端/服务端待发送数据时,肯定有特定的格式)。

    关于发送一次,一个包的完整性可靠接收(tcp的可靠传输,以及取数据的半包粘包问题)这里不关注,可以参考上文。

    这里的目的是

    ===》备份c语言字符处理相关方案

    ===》备份自己在业务实现时,对字符串切割实现的一个接口(strstr,strcasestr,strsep,strtok,strdup相关接口)

    有如下几个细节可以关注

    ===》1:实现不同类型的数据拼接字符串的方案 (3.1)

    ===》2:char**通过传参的方式再函数内部进行构造 (3.2.4.2)

    ===》3:对字符串进行解析处理的几种方案,尤其是分割字符串的实现(strsep实现了demo)(3.2.4)

    1:背景描述

    网络传输过程中,如tcp的客户端可服务端进行通信时,send函数实际发送的数据是用字符数组+长度表示的,即流的形式。

    有关一次发送,一个包的完整接收,依赖于tcp底层的可靠流式传输,需要进行半包和粘包处理,可以参考上文。

    但是,这里针对一个包的结构,我们其实也会需要根据我们的业务场景进行设计,按照特定的结构进行构造,与解析。

    这里关注一次发送一个包的构造与解析方案,以及代码实现做备份

    2:逻辑描述

    2.1:大概描述

    网络传输中,对字符流的处理非常重要,建立在我们制定的特定的规范上

    ===》除了关注一个包的完整接收(粘包半包问题),还需要关注数据本身

    ===》1:类似tcp/ip协议栈那样,用特定的协议栈,特定的字节表示特定的含义进行解析(固定字节大小表示含义)

    ===》2:我们可以自定义规范,如用特定的字符/字符串进行识别,分割不同字符所表示的含义(如 msg_type|other_type|msg_len|msg_data).

    这里针对以上所描述的两种方案的数据的构造与解析,进行梳理及代码测试。。。

    2.2:数据的构造(目的构造特定格式待发送的char*及获取长度)

    一般发送端和接收端对数据的处理都是协商好的,按照特定的格式构造,必然会按照特定的格式进行解析。

    数据的构造本质:其实就是按照特定的格式给char指针中塞入协商的格式的数据,以及获取到实际发送的数据的长度

    ===》1:类似tcp/ip协议头,可以通过结构体指针强转,以及获取实际长度进行发送

    ===》2:构造要发送的char*指针及获取长度方案:使用 memcpy

    ===》3:构造要发送的char*指针及获取长度方案:c库函数,strcpy, strcat

    ===》4:构造要发送的char*指针及获取长度方案:使用sprintf、sprintf_s觉得最好用

    2.3:数据的解析(目的对接收到的char*按协商的格式进行解析)

    以流的形式,接收到对待的数据(实际是char*指针和数据长度),对其按照协商进行解析。

    解析的本质:按照特定的字节,或者对整个流进行处理依次取特定位置数据

    ===》1:指针强转,类似tcp/ip协议栈处理,可以把接收到的报文,直接转为结构体指针进行操作

    ===》2:先取特定长度,再按这个长度取实际数据。 (发送先发送长度+data(可以自己定义解析格式))

    ===》3:解析接收到的流,进行解析(如按照“|”进行分割

    本文的目的之一也是为了备份按照“|”进行分割的一个实践代码

    3:代码梳理

    3.1:待发送数据构造的demo

    3.1.1:结构体指针转为char*实现/解析逻辑

    构造结构体,计算实际长度,send时直接转为char*传参进行发送。。。

    再linux环境上使用gcc进行编译测试过,代码执行ok

    //1:类似tcp/ip协议栈,其实都是按照特定的结构体进行类型强转数据解析
    void parse_struct_format_data()
    {
    printf("parse_struct_format_data test: \n");
    	//假设定义了柔性数组,构造数据并解析数据的流程如下
    	struct my_data_t
    	{
    		int msg_type;
    		int data_len;
    		char data[0];
    	};
    	//假设要发送的数据为client send data example. \n, 类型为1
    	const char* data = "client send data example. \n";
    	//发送端构造最终的数据如下
    	struct my_data_t *send_data = NULL;
    	send_data = (struct my_data_t*)malloc(sizeof(struct my_data_t)+strlen(data)+1);
    	if(send_data == NULL)
    	{
    		return ;
    	}
    	memset(send_data, '\0', sizeof(struct my_data_t)+strlen(data)+1);//只是预留了一个位而已
    	send_data->msg_type = 1;
    	send_data->data_len = strlen(data);
    	memcpy(send_data->data, data, strlen(data));
    	//这里其实 send_data就是我们最终构造的一个网络数据格式包,可以进行发送
    	//使用send进行发送时,只是传参char*以及待发送的数据长度
    	char *send_para_data = (char *)send_data; //结构体类型强转  tcp识别到的是这个结构里的流数据
    	int send_para_data_len = sizeof(struct my_data_t)+strlen(data);
    	//如果客户端使用send_para_data 及长度send_para_data_len 进行发送及校验 。。。
    	//我们收到的流,以recv进行接收,就是一个字符流,内容其实就是send_para_data 长度为send_para_data_len 
    	//这里要完整的接收到一个包(半包粘包问题,可参考上文)
    	//进行逆向解析就好
    	struct my_data_t *recv_data = (struct my_data_t*)send_para_data;
    	//可以按照柔性数组的逻辑 按照长度对实际数据进行解析打印
    	printf("\trecv_data type is [%d] \n",recv_data->msg_type);
    	printf("\trecv_data len is [%d] \n",recv_data->data_len);
    	//这里只是测试  注意如果这个data中有特殊的字符如\0等,不能这样打印,要按照十六进制按照长度打印
    	printf("\trecv_data len is [%s] \n", recv_data->data);
    	printf("recv_data ASSII is [");
    	for(int i=0; i<recv_data->data_len; i++)
    	{
    		printf("%02x ", recv_data->data[i]);
    	}
    	printf("]\n");
    	if(send_data!= NULL)
    	{
    		free(send_data);
    		send_data = NULL;
    	}
    }
    

    3.1.2:使用memcpy实现字符串的拼接,构造char*

    目的是获得最终的char*指针位置以及实际发送的数据长度。

    这里因为懒,使用了to_string把int转为string进行测试,所以编译的时候用c++11,可以修改用itoa…

    //1:使用memcpy实现字符串的拼接 splicing test of string1 and string2
    int use_memcpy_splic_string()
    {
    printf("use_memcpy_splic_string test:\n");
    	const char* str1 = "splicing test of ";
    	const char* str2 = "string";
    	const char* and1 = " and ";
    	int one = 1;
    	int two = 2;
    	//这里用到了C++中的to_string函数  c语言可以用itoa,这里主要是理解字符串拼接,,, 有int类型的字符串转换拼接常用sprintf
    	int size = strlen(str1) + strlen(str2) * 2 + (strlen(to_string(one).c_str())) + strlen(and1) + (strlen(to_string(two).c_str())) + 1;
    	printf("\tget the len is : %d %lu\n", size, strlen("splicing test of string1 and string2"));
    
    	int pos = 0;
    	char* result = (char*)malloc(size);
    	if (result == NULL)
    	{
    		return -1;
    	}
    	memset(result, '\0', size);
    	memcpy(result, str1, strlen(str1));
    	pos += strlen(str1);
    	memcpy(result + pos, str2, strlen(str2));
    	pos += strlen(str2);
    	memcpy(result + pos, to_string(one).c_str(), strlen(to_string(one).c_str()));
    	pos += strlen(to_string(one).c_str());
    	memcpy(result + pos, and1, strlen(and1));
    	pos += strlen(and1);
    	memcpy(result + pos, str2, strlen(str2));
    	pos += strlen(str2);
    	memcpy(result + pos, to_string(two).c_str(), strlen(to_string(two).c_str()));
    	pos += strlen(to_string(two).c_str());
    	printf("\tthe result is [%lu][%s]  \n", strlen(result), result);
    	printf("\tpos is [%d] \n", pos);
    	if (result != NULL)
    	{
    		free(result);
    		result = NULL;
    	}
    	return 0;
    }
    

    3.1.3:使用c库函数(strcpy, strcat)

    偷懒用了to_string(),编译测试用c++11

    //2:使用c库函数实现字符串的拼接 splicing test of string1 and string2
    //写代码的时候要注意目标字符串的长度一定要够用 
    int use_clibrary_strcat_splic_string()
    {
    printf("use_clibrary_strcat test: \n");
    	const char* str1 = "splicing test of ";
    	const char* str2 = "string";
    	const char* and1 = " and ";
    	int one = 1;
    	int two = 2;
    	//这里用到了C++中的to_string函数  c语言可以用itoa,这里主要是理解字符串拼接,,, 有int类型的字符串转换拼接常用sprintf
    	int size = strlen(str1) + strlen(str2) * 2 + (strlen(to_string(one).c_str())) + strlen(and1) + (strlen(to_string(two).c_str())) + 1;
    	printf("\tget the len is : %d %lu\n", size, strlen("splicing test of string1 and string2"));
    	char* result = (char*)malloc(size);
    	if (result == NULL)
    	{
    		return -1;
    	}
    	memset(result, '\0', size); 
        //vs上测试时要用strcpy_s
    	// strcpy_s(result, size, str1);
    	// strcat_s(result, size, str2);
    	// strcat_s(result, size, to_string(one).c_str());
    	// strcat_s(result, size, and1);
    	// strcat_s(result, size, str2);
    	// strcat_s(result, size, to_string(two).c_str());
    	//注意字符串处理时的不安全性!!!
    	strcpy(result,  str1);
    	strcat(result,  str2);
    	strcat(result,  to_string(one).c_str());
    	strcat(result,  and1);
    	strcat(result,  str2);
    	strcat(result,  to_string(two).c_str());
    	printf("\tthe result is [%lu][%s]  \n", strlen(result), result);
    	if (result != NULL)
    	{
    		free(result);
    		result = NULL;
    	}
    	return 0;
    }
    

    3.1.4:使用sprintf(sprintf_s):最实用和方便

    vs上测试时需要使用sprintf_s

    int use_sprintf_splic_string()
    {
    	printf("use_sprintf_splic_string test: \n");
    	const char* str1 = "splicing test of ";
    	const char* str2 = "string";
    	const char* and1 = " and ";
    	int one = 1;
    	int two = 2;
    	//定义目标字符串,为其申请内存都是必须的
    	int size = strlen(str1) + strlen(str2) * 2 + (strlen(to_string(one).c_str())) + strlen(and1) + (strlen(to_string(two).c_str())) + 1;
    	printf("\tget the len is : %d %lu\n", size, strlen("splicing test of string1 and string2"));
    	char* result = (char*)malloc(size);
    	if (result == NULL)
    	{
    		return -1;
    	}
    	memset(result, '\0', size);
    	//使用sprintf一步到位
    	sprintf(result, "%s%s%d%s%s%d", str1, str2, one, and1, str2, two);
    	//sprintf_s(result, size, "%s%s%d%s%s%d", str1, str2, one, and1, str2, two);
    	printf("\tthe result is [%lu][%s]  \n", strlen(result), result);
    	if (result != NULL)
    	{
    		free(result);
    		result = NULL;
    	}
    	return 0;
    }
    

    3.2:接收数据进行解析的demo

    3.2.1:直接把char*转为结构体(类似tcp/ip协议栈处理)

    参考3.1.1

    3.2.2:按照协商的自己含义,使用memcpy按字节处理

    参考3.1.2

    3.2.3:先接收长度,再接收数据的解析

    网络数据有个场景,可以先发送实际数据的长度,recv时先接收特定字节长度,再接收实际数据,保证报的完整.

    //2:特定字节表示长度,对后面的数据进行处理==》其实和结构体格式差不多,柔性数组
    void parse_len_and_data_networkdata()
    {
    printf("parse_len_and_data_networkdata test: \n");
    	//在网络传输中,可以用特定字节表示长度+实际数据的格式
    	const char *send_data = "msg_type | msg_len |msg_data ...\n"; //实际数据有特殊字符的话,长度要传进来或者结构体其他方案
    	//在网络发送中,如果想简单实现不想用结构那么麻烦,可以这样用 
    	int send_len = strlen(send_data);
    	printf("\tsend_len [%d][%s] \n",send_len, send_data);
    	//可以类似上个函数用结构体  struct data_t{int len; char data[0];};构造
    	//我试试这种:
    	char * real_send_data = (char *)malloc(send_len +4+1);
    	memset(real_send_data, 0, send_len +4+1);
    	memcpy(real_send_data, (char*)&send_len, sizeof(int)); //前四个字节拷贝长度,也可以以字符串形式直接存进去 to_string(send_len).c_str()
    	memcpy(real_send_data +sizeof(int), send_data, send_len);
    	//real_send_data 就是我们实际send的流   我们可以先接收取前四个字节获取数据长度,再接收后面的字段
    	//先定义一个int,从recv取四个字节,转为int表示的长度
    	int recv_len = *(int *)real_send_data; //先recv取四个字节  解析成真正的数据
    	char* recv_data = real_send_data+4;  //这里应该是recv读出来的 长度为recv_len 
    	printf("\trecv_len[%d] [%s] \n",recv_len, recv_data);
    	if(real_send_data != NULL)
    	{
    		free(real_send_data);
    		real_send_data = NULL;
    	}
    }
    

    3.2.4:如果是按字符串进行分割的设计,对其进行解析

    这里只是实现了切割字符串的其中一种方案。

    3.2.4.1:数据的构造(符合”|“切割的字符串:”msg_type|other_type|msg_len|msg_data“):

    //模拟一个完整的包,返回一个符合特定格式的拼接起来的包数据
    //假设 msg_type|other_type|msg_len|msg_data 格式
    int get_concatenate_strings(char ** result_data, int* len)
    {
    	// 假设格式msg_type|other_type|msg_len|msg_data 格式
    	const char * data = "mytest of spilt of send data ... \n\t test";//注意网络数据这里的复杂,用memcpy处理
    	int msg_type = 1;
    	int other_type = 2;
    	int msg_len = strlen(data); //实际后面的数据长度
    	//这里估算一下最终最大长度 用20+strlen(data)肯定够用
    	char *send_data = NULL;
    	send_data = (char*)malloc(20+msg_len);
    	memset(send_data, 0, 20+msg_len);
    	sprintf(send_data, "%d|%d|%d|", msg_type, other_type, msg_len);
    	
    	//通过传参的方式传递出去
    	*len = strlen(send_data) +msg_len;
    	memcpy(send_data+strlen(send_data), data, msg_len);
    	*result_data = send_data;
    	printf("\t result_data is [%d][%s] \n",*len, send_data);
    }
    

    3.2.4.2:按特定字符对字符串实现切割解析(解析提取”msg_type|other_type|msg_len|msg_data“各字段含义)

    这里可以关注一下这几个库函数实现字符串切割的方案,测试只是其中一种

    char * strstr(const char *haystack, const char *needle); 函数定位子串的位置,然后实现字符串的切割
    char * strcasestr(const char *haystack, const char *needle); 和strstr同样的功能,只是忽略两个参数的大小写
    char *strtok(char *str, const char *delim); 分解字符串 str 为一组字符串,delim 为分隔符
    char *strsep(char **stringp, const char *delim); strtok的升级,

    //这里使用"|"对长度为len目标数据data进行切割,通过参数result返回解析后的数据
    int check_recv_data_by_spilit(const char * data, int len, char **result, const char* delim)
    {
    	//直接根据'|'对字符串进行切割 根据切割后的个数进行校验
    	char *src = strdup(data); //复制了一份数据 strsep会修改原字符串
    	char * src_free = src; 
    
    	//msg_type|other_type|msg_len|msg_data  按照协商的格式 定义了暂存的指针
    	char * delim_buff[4] = {0};
    	char* token = NULL;  //切割后返回的字符指针
    	int i = 0;			 //切割的个数
    	//返回的是符合的分割的字符   同时原字符从分割后的位置开始
    	for(token = strsep(&src, delim); token!=NULL && i<4; token=strsep(&src, delim))
    	{
    		delim_buff[i++] = token;
    		printf("\tspilt data [%d:%lu:%s] \n", i, strlen(token), token);
    		printf("\t\t src:[%s] \n",src);
    	}
    
    	if(i != 4) //必然是协商的格式 
    	{
    		printf("\tvps spilit data error \n");
    		free(src_free);
    		return -1;
    	}
    
    	int msg_type = (int)atoi(delim_buff[0]);
    	int dev_type = (int)atoi(delim_buff[1]);
    	int data_len = (int)atoi(delim_buff[2]);
    	char * cli_data = delim_buff[3];
    	printf("\nmsg_type:%d, dev_type:%d, data_len:%d:%lu:[%s] \n", msg_type, dev_type, data_len, strlen(cli_data), cli_data);
    
    	//把解析后的数据进行处理 使用传参传出去
    	int ret = 0;
    	struct client_recv_t *result_t = NULL;
    	result_t = (struct client_recv_t *)malloc(sizeof(struct client_recv_t) + data_len+1);
    	if(result_t == NULL)
    	{
    		printf("malloc error \n");
    		*result = NULL;
    		ret = -1;
    	}else
    	{
    		memset(result_t, sizeof(struct client_recv_t) + data_len+1, 0);
    		result_t->msg_type = msg_type;
    		result_t->dev_type = dev_type;
    		result_t->data_len = data_len;
    		memcpy(result_t->data, cli_data, data_len);
    		
    		*result = (char *)result_t;
    	}
    	memset(src_free, 0, len);
    	free(src_free);
    	src_free = NULL;
    	return ret;
    }
    

    3.2.4.2:测试代码:

    再linux环境直接用gcc进行编译测试,代码ok。。。

    //定义一个保存解析后数据的结构
    struct client_recv_t
    {
    	int msg_type;
    	int dev_type;
    	int data_len;
    	char data[0];
    };
    
    int parse_spilt_string_and_getdata(const char * data, int len)
    {
    	printf("\tneed parse data is [%d][%s] \n", len, data);
    	//使用特定字符串对字符串进行切割,这里举例是"|",可以是其他的字符串。。。
    	//协商的协议是:msg_type|other_type|msg_len|msg_data 
    	//实际数据是:[47][1|2|40|mytest of spilt of send data ... \n\t test
    
    	char * result_data_t = NULL; //存储解析后的数据,也可以是其他方案,这里只是举例
    	//这里使用"|"对长度为len目标数据data进行切割,通过传参获取 result_data_t
    	if(check_recv_data_by_spilit(data, len, &result_data_t, "|") != 0)
    	{
    		printf("vps parse spilit error \n");
    		return -1;
    	}
    	//对解析后的数据进行打印
    	struct client_recv_t *result_data = (struct client_recv_t *)result_data_t;
    	printf("\t parse test data is [%d][%d][%d][%s] \n", result_data->msg_type, result_data->dev_type, result_data->data_len, result_data->data);
    	// memset(result_data, sizeof(struct client_recv_t)+ (result_data->data_len+1), 0);
    	if(result_data != NULL)
    	{
    		free(result_data);
    		result_data = NULL;
    		printf("free success \n");
    	}
    	return 0;
    }
    
    //真正的入口
    void parse_string_spilt_data()
    {
    printf("parse_string_spilt_data test: \n");
    	//假设协商的协议是msg_type|other_type|msg_len|msg_data 
    	//构造一个数据,获取到最终发送的数据和数据长度
    	char * send_data = NULL;
    	int send_len = 0;
    	if(get_concatenate_strings(&send_data, &send_len) < 0)
    	{
    		printf("\t make send_data error \n");
    		return;
    	}
    	printf("\t last_result_data is [%d][%s] \n",send_len, send_data);
    	//假设对这个数据进行发送了,报的完整性参考上文
    	//接收其实就是这样格式的数据,解析一下这个 这里recv接收时要关注包的完整性
    	parse_spilt_string_and_getdata(send_data, send_len);
    	if(send_data != NULL)
    	{
    		free(send_data);
    		send_data = NULL;
    	}
    }
    

    我开始试着积累一些常用代码:自己代码库中备用

    我的知识储备更多来自这里,推荐你了解:Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等技术内容,立即学习

    展开全文
  • 1.字符串拼接 使用c的函数char *strcat(char *str_des, char *str_sou); 将字符串str_sou接在字符串str_des后面(放在str_des的最后字符和“\0”之间)。 注意不要越界,可用strlen(input)函数求字符串长度之后再...
  • C语言实现字符串拼接

    千次阅读 2020-12-04 18:06:48
    /*实现字符串拼接*/ //头文件 #include <stdio.h> #include <stdlib.h> //主程序 int main() { //声明连个字符串 char str[] = "hello"; char str1[] = "word"; //声明一个空的数组用于接收两个...
  • C语言拼接字符串和整型

    千次阅读 2015-11-10 14:22:23
    用sprintf合拼char name[10] = "hello"; int age = 123; char buffer[80]; sprintf(buffer, "%s%d xx", name, age);...buffer就是合并后的字符串。 相关函数:sscanf(),相当于拆分。 #include int main(void) {
  • C语言字符串拼接

    2021-05-26 20:52:24
    包含头文件: #include <stdio.h> 函数体 int sprintf(char *str, const char *format, ...); 例子: int gpio_num = 99;...sprintf(PATH,"/sys/class/gpio/gpio%d/value",gpio_num);...sprintf(PATH,"welcom
  • } //注意,此时指针c已经指向拼接之后的字符串的结尾'\0' ! return tempc;//返回值是局部malloc申请的指针变量,需在函数调用结束后free之 } /*方法二,直接改掉字符串a,*/ void join2(char *a, char *b) { //注意...
  • printf("请输入字符串1:\n"); gets(str1); printf("请输入字符串2:\n"); gets(str2); while (str1[i] != '\0') { i++;//找到str1的最后一个字符 } while (str2[j] != '\0') { str1[i++] = .
  • c语言字符串拼接函数

    千次阅读 2021-02-11 12:50:37
    //关于字符串的操作要包含头文件sting.h #include<string.h> int main() { //strcat char c1[32] = { 0 }; char c2[32] = { 0 }; strcat(c1, "hello"); printf("%s", c1); strcat(c2, " world"); ...
  • c语言函数strncat()c语言如何拼接字符串(取前n个字符)。实例源码介绍函数的使用。相关函数:bcopy, memccpy, memecpy, strcpy, strncpy需引入的头文件:#inclue 定义strncat()函数:char * strncat(char *dest, ...
  • C语言字符串拼接的两种方法

    千次阅读 2021-09-29 15:22:44
    strcat #include <stdio.h> #include<stdlib.h> #include<string.h> int main() { char *firstName = "Hello";... char *name = (char *) malloc(strlen(firstName)+strlen(lastName));... strcat(n
  • #include <stdlib.h> #include <stdio.h> #include <string.h> main) { char string1[10] = , string2[10] = ,string3[10]=,string4[100]=;版权文档请勿用做商业用途 int r,i=0,j=0; while ( string1[0] !...
  • C语言实现合并字符串

    2020-12-23 04:47:34
    使用C语言进行字符串拼接应该怎么做呢?在先前,我肯定是要定义一个新的“字符串”,然后进行内存的拷贝。其实,有一个printf函数的孪生兄弟可以实现这个功能,那就是sprintf。 其实,在接触操作系统的时候我对这...
  • 简单的字符串拼接实现
  • C语言字符串数组拼接

    2021-03-26 22:13:15
    代码目标是为了实现将速度值读取后实现语音拼接 include <stdio.h> #define AC_TdSpeed_SET_REPLY "F" #define AC_TdSpeed_M_REPLY "End" unsigned char *TD_Metric_Inch_Speed; unsigned char Number[12][4]...
  • 显然没法放到栈上,如果非要和errstr拼接起来的话,errstr必须在堆上,即要动态的malloc,由此可见,对于脚本语言来讲,一个非常简单的逻辑,在C中却如此的麻烦 解决办法: 为了既不需要free,又能拼接字符串,可以...
  • C语言拼接字符串 -- 使用strcat()函数

    万次阅读 2018-08-09 09:33:02
    【头文件】#include &lt;... 【参数】: dest 为目标字符串指针,src 为源字符串指针。 strcat() 会将参数 src 字符串复制到参数 dest 所指的字符串尾部;dest 最后的结束字符 NULL 会被覆...
  • 本文实例为大家分享了C语言实现字符串拼接和拷贝的具体代码,供大家参考,具体内容如下 字符串拼接: #include #include #include char *str_contact(const char *,const char *); char *str_contact(const char *...
  • C语言实现字符串中任意地方插入其他字符实现拼接 #include <stdio.h> #include <strings.h> #include <stdlib.h> char *Custom_Insetr_String(char *string_str1,char *string_str2,const ...
  • c语言字符数组拼接

    千次阅读 2020-04-23 09:50:28
    //这地方比较繁琐,可不写,直接i=strlen(a)-1 //进行拼接 for(j=0; j(b); j++) a[i+j]=b[j]; a[i+j] = '\0'; } int main() { char a[100],b[20]; gets(a); gets(b); mystrcat(a,b); puts(a); }
  • c语言中的字符串拼接

    千次阅读 2019-04-27 23:51:05
    先判断两个字符串的末尾,然后将两个字符串拼接到一起,并将字符串最末尾设置为0。 3 为什么要将位置0和位置2都置为0? protocols[0] = ‘\0’; protocols[2] = ‘\0’; 将位置0置为0表示这是一个空字符串。 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 23,399
精华内容 9,359
关键字:

c语言如何拼接字符串