制作未知长度的 char 数组的工作副本
Making a working copy of char array of unkown length
将 MPLABX 5.35 与 XC16 v1.36 用于 PIC24FJ128GB204。 c背景有限,学习中。
我正在尝试编写一个函数,它在一个 char 数组(大小未知)中接受一个(指向一个)字符串并就地编辑它以右对齐它并用字符填充它直到它有要求的长度。
由于我也想为其他项目保留此功能,源数组的大小将是未知的,但用户(我)应该使 targetLength 小于数组的大小。
想象一下数组:
char example[20] = "test";
我希望能够将它传递给具有所需长度(例如,10 个字符,包括空终止符)和填充字符“#”的函数,它应该就地编辑数组为“### ##测试
我想出的代码(只适用于一些场合,所以不可用):
uint16_t fillStringRight(char * source,
uint16_t targetLength,
char filler)
{
uint16_t sourceLength = strlen(source) + 1;
if (sourceLength > targetLength){
// source length is already longer than requested
return 0;
}
uint16_t reqFiller = targetLength - sourceLength;
strcpy(&source[reqFiller], source);
memset(source, filler, reqFiller -1);
return 1;
}
但是,在这种情况下:
char source[20] = "test";
fillStringRight(source, 6, ' ');
这不起作用。如果我理解正确,源和结果重叠,所以 strcpy 将覆盖空终止符,从而继续写入内存,直到看门狗重新启动 PIC。
第一个问题:我的理解正确吗?
我想我应该复制源字符串而不是就地编辑它。但是,我不知道字符串的长度,所以我无法调整将用于副本的 char 数组的大小(除非我把它做得大得离谱)。我阅读了有关 malloc 的内容,以在堆中创建一个大小在运行时确定的变量,但也阅读了反对在微控制器上使用 malloc 的内容。我还不明白为什么,所以我宁愿避开它,直到我更好地理解它。
第二个问题:正确的做法是什么?我可以编写一个向后运行的函数(从最后一个位置的空终止符开始,然后向后运行),但这看起来开销很大。有没有更好的办法?
The memory areas may overlap: copying takes place as though the bytes in src are first copied into a temporary array that does not overlap src or dest, and the bytes are then copied from the temporary array to dest.
换句话说,有你想要的功能:)
尝试 memmove(&source[reqFiller], source, sourceLength);
等效伪代码:
char *tmp = duplicate_string(source);
copy tmp to &source[reqFiller];
无关,但仅供参考:
1)strlen()
returnssize_t
,不是uint16_t
2) &a[b] == &*(a +b) == (a + b)
所以 &source[reqFiller] == source + reqFiller
将 MPLABX 5.35 与 XC16 v1.36 用于 PIC24FJ128GB204。 c背景有限,学习中。
我正在尝试编写一个函数,它在一个 char 数组(大小未知)中接受一个(指向一个)字符串并就地编辑它以右对齐它并用字符填充它直到它有要求的长度。 由于我也想为其他项目保留此功能,源数组的大小将是未知的,但用户(我)应该使 targetLength 小于数组的大小。
想象一下数组:
char example[20] = "test";
我希望能够将它传递给具有所需长度(例如,10 个字符,包括空终止符)和填充字符“#”的函数,它应该就地编辑数组为“### ##测试
我想出的代码(只适用于一些场合,所以不可用):
uint16_t fillStringRight(char * source,
uint16_t targetLength,
char filler)
{
uint16_t sourceLength = strlen(source) + 1;
if (sourceLength > targetLength){
// source length is already longer than requested
return 0;
}
uint16_t reqFiller = targetLength - sourceLength;
strcpy(&source[reqFiller], source);
memset(source, filler, reqFiller -1);
return 1;
}
但是,在这种情况下:
char source[20] = "test";
fillStringRight(source, 6, ' ');
这不起作用。如果我理解正确,源和结果重叠,所以 strcpy 将覆盖空终止符,从而继续写入内存,直到看门狗重新启动 PIC。
第一个问题:我的理解正确吗?
我想我应该复制源字符串而不是就地编辑它。但是,我不知道字符串的长度,所以我无法调整将用于副本的 char 数组的大小(除非我把它做得大得离谱)。我阅读了有关 malloc 的内容,以在堆中创建一个大小在运行时确定的变量,但也阅读了反对在微控制器上使用 malloc 的内容。我还不明白为什么,所以我宁愿避开它,直到我更好地理解它。
第二个问题:正确的做法是什么?我可以编写一个向后运行的函数(从最后一个位置的空终止符开始,然后向后运行),但这看起来开销很大。有没有更好的办法?
The memory areas may overlap: copying takes place as though the bytes in src are first copied into a temporary array that does not overlap src or dest, and the bytes are then copied from the temporary array to dest.
换句话说,有你想要的功能:)
尝试 memmove(&source[reqFiller], source, sourceLength);
等效伪代码:
char *tmp = duplicate_string(source);
copy tmp to &source[reqFiller];
无关,但仅供参考:
1)strlen()
returnssize_t
,不是uint16_t
2) &a[b] == &*(a +b) == (a + b)
所以 &source[reqFiller] == source + reqFiller