我一直在互联网上寻找这个,到目前为止,我只是找到了很多具体答案的问题,而不是一般的问题。
我对 C 有点生疏。我想创建一个将返回字符数组的函数。
这就是我得到的并且不起作用。 基本上是一种将字节数组转换为字符数组以稍后执行 atoi 的方法。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char *get_char(int my_byte[], int packetsize)
{
char *array_char=(char *) malloc(sizeof(char)*10); //trying this but didnt work
// char array_char[10]; //i had it like this before(was told to do it)
for(int i=0;i<10;i++)
{
array_char[i]=my_byte[i]+0;
}
return array_char;
}
int main()
{
int byte_array[]={1,2,3,4,5,6,7,8,9,0};
char *temp;
char data;
temp=get_char(byte_array,10);
data=*temp;
printf("String point %s ",data);
}
两个修复:
- 当您要转换为字符时,则
array_char[i]=my_byte[i]+0;
应该是array_char[i]=my_byte[i]+'0';
注意'0'
是字符(将转换为 int)而不是数字 0(不执行任何操作)。
- 此外,您必须释放
temp
main
指针,因为该内存get_char()
函数中动态分配。
编辑:只需注意get_char()
中的另一个问题
char *array_char=(char *) malloc(sizeof(char)*10);
应该是
char *array_char= malloc(sizeof(char)*(packetsize+1));
for
循环后,确保缓冲区以 NUL 终止:
array_char[packetsize] = ' ';
请注意,您的packetsize
从未被使用 - 您应该会收到一些编译器警告。在malloc
中硬编码10
是不好的 - 这实际上是将packetsize
解析为参数的整个想法 - 因此请正确使用它。
您需要注意以下事项:
- 您需要在
*array_char
末尾添加一个以 null 结尾的字符,否则使用从堆中分配的此指针将导致未定义的行为。 -
您可以像这样简单地分配
*array_char
:char *array_char = malloc(packetsize+1);
因为
sizeof(char)
是1
,+1
尾随空字节。 -
你也不需要强制返回 malloc()。
- 与其将
10
作为packetsize
传递给get_char()
,不如将此大小作为sizeof(arr) / sizeof(arr[0]
传递,这是数组的计算大小。这可以是在某处声明的size_t
变量,甚至可以是宏。 - 需要检查
malloc()
,因为如果不成功,它可以返回NULL
。 - 您需要在程序的某个时刻
free()
temp
。 -
array_char[i]=my_byte[i]+0;
需要改为array_char[i]=my_byte[i]+'0';
,因为'0'
是零字符的 ASCII 代码。 -
char data
需要char *data
,因为temp
是一个指针。如果使用
-Wall -Wextra
进行编译,您将看到以下行:data=*temp;
很危险,并且会触发从没有强制转换的整数创建指针的警告。这很可能导致分段错误。如果
temp
和data
都是指针,那么您可以简单地使用:data=temp;
将
data
设置为temp
的地址。有时写成data = &(*temp);
,但这更难阅读。虽然不需要data
,单独使用temp
应该没问题。
然后,您的代码可能如下所示:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define ARRAYSIZE(arr) (sizeof(arr) / sizeof(arr[0]))
char *get_char(int my_byte[], size_t packetsize) {
char *array_char = malloc(packetsize+1);
const char ascii = '0';
size_t i;
if (!array_char) {
printf("Cannot allocate %zu bytesn", packetsize+1);
exit(EXIT_FAILURE);
}
for(i = 0; i < packetsize; i++) {
array_char[i] = my_byte[i] + ascii;
}
array_char[i] = ' '; /* or array_char[packetsize] = ' ' */
return array_char;
}
int main(void) {
int byte_array[]={1,2,3,4,5,6,7,8,9,0};
char *temp, *data;
temp = get_char(byte_array, ARRAYSIZE(byte_array));
data = temp;
printf("String point %sn", data);
printf("String converted into number = %dn", atoi(data));
free(temp);
temp = NULL;
return 0;
}
您还可以查看strtol
,这在错误检查方面比使用atoi()
更好。
从函数返回数组是不明智的主意。那么如何返回字符串呢?由于大多数libc函数都使用,我们可以使用类似的东西(即)将缓冲区与我们的输入一起传递,并期望函数使用输出缓冲区为我们提供结果。
编码时要注意的一些问题
- 先写你的逻辑。
- 尝试使用 libc 中的可用函数。
- 在处理字节数据/二进制数据时,请注意缓冲区溢出。 不要在一个函数中分配
- 并在另一个函数中取消分配。
下面是经过修改的代码示例。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include <stdint.h>
int get_char(uint8_t my_byte[], int packetsize, char *buffer, int max_buffer)
{
int byte_itr, buf_itr;
char temp_buf[16]={0x00};
for(byte_itr=0, buf_itr=0; byte_itr<packetsize && max_buffer > buf_itr; byte_itr++)
{
memset(temp_buf, 0x00, sizeof(temp_buf));
char temp_ch = my_byte[byte_itr];
snprintf(temp_buf, sizeof(temp_buf), "%d", temp_ch);
if( buf_itr+strlen(temp_buf) >=max_buffer){
break;
}else{
buf_itr += strlen(temp_buf);
strcat(buffer, temp_buf);
if(byte_itr+1 < packetsize){
strcat(buffer, ",");
buf_itr += 1;
}
}
}
return buf_itr;
}
int main()
{
uint8_t byte_array[]={1,2,3,4,5,6,7,8,9,0};
char char_array[32]={0x00};
int len = get_char(byte_array, 10, char_array, sizeof(char_array));
printf("String point %s : len %dn", char_array, len);
}
注意: 当长度返回和输出缓冲区大小相同时,则发生缓冲区已满情况。