同时替换多个字符
Replacing multiple chars at the same time
所以在我的代码中,我有一系列的字符,我想用随机数据替换它们。由于 rand 可以替换 int,我想我可以通过一次替换四个字符而不是一次替换一个来节省一些时间。所以基本上不是这个:
unsigned char TXT[] = { data1,data2,data3,data4,data4,data5....
for (i = 34; i < flenght; i++) // generating the data to send.
TXT[i] = rand() % 255;
我想做这样的事情:
unsigned char TXT[] = { data1,data2,data3,data4,data4,data5....
for (i = 34; i < flenght; i+4) // generating the data to send.
TXT[i] = rand() % 4294967295;
效果很好,但我不确定后半部分该怎么做。非常感谢您能给我的任何帮助,谢谢!
那行不通。编译器将从rand() % big_number
中获取结果,并切掉多余的数据以使其适合unsigned char
。
在速度方面,您最初的方法很好。您考虑的优化是有效的,但很可能不需要。这可能不会产生明显的差异。
当然,你想做的事情是可能的,但考虑到你的错误,我想说的是,理解现在的努力远远超过了好处。继续学习,下次你遇到这样的代码时,你会知道该怎么做(并判断是否有必要(,回顾这一刻并:)微笑。
您必须直接访问内存,并对数据进行一些转换。你可能想要这样的东西:
unsigned char TXT[] = { data1,data2,data3,data4,data4,data5....
for (i = 34; i < flenght/sizeof(int); i+=sizeof(int)) // generating the data to send.
{
int *temp = (int*)&TXT[i]; // very ugly
*temp = rand() % 4294967295;
}
由于对齐问题,这可能会有问题,所以要小心。对齐问题可能会导致程序意外崩溃,并且难以调试。如果我是你,我不会这样做,你的初始代码很好。
TXT[i] = rand() % 4294967295;
不会按预期方式工作。也许您期望rand()%4294967295
将生成一个 4 字节整数(您可能会将其解释为 4 个不同的字符(。rand()%4294967295
产生的值将被类型转换为单个字符,并且将仅分配给TXT[i]
索引之一。
虽然不清楚为什么需要同时进行 4 个赋值,但一种方法是使用位运算符来获取生成的数字的 4 个不同的有效字节,然后可以将这些字节分配给四个不同的索引。
这么多有效的答案 C 不太关心它存储在哪个地址的类型。因此,您可以侥幸逃脱以下情况:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
char *arr;
int *iArr;
int main (void){
int i;
arr = malloc(100);
/* Error handling ommitted, yes that's evil */
iArr = (int*) arr;
for (i = 0; i < 25; i++) {
iArr[i] = rand() % INT_MAX;
}
for (i = 0; i < 25; i++) {
printf("iArr[%d] = %dn", i, iArr[i]);
}
for (i = 0; i < 100; i++) {
printf("arr[%d] = %cn", i, arr[i]);
}
free(arr);
return 0;
}
最后,数组只是内存中的某个连续块。您可以随心所欲地解释它(如果您愿意(。如果你知道 sizeof(int( = 4 * sizeof(char(,那么上面的代码就可以工作了。
我不是说我推荐它。其他人指出,无论发生什么,通过 TXT 中所有字符的第一个循环都会产生相同的结果。例如,人们可以考虑展开一个循环,但实际上我不会在乎这一点。
(int*(本身就足够警告了。这意味着对编译器来说,不要考虑你认为的类型只是"相信"他程序员他知道得更多。
好吧,这种"知道得更好"可能是C编程中万恶之源。
unsigned char TXT[] = { data1,data2,data3,data4,data4,data5....
for (i = 34; i < flenght; i+4)
// generating the data to send.
TXT[i] = rand() % 4294967295;
这有几个问题:
- TXT 不能保证 CPU 写入
int
数据所需的内存对齐(它是否工作 - 也许相对较慢 - 或不工作 - 例如 Solaris 上的 SIGBUS - 特定于硬件( - 最后 1-3 个字符可能会丢失(即使您将
i + 4
更改为i += 4
;-P( - 无论如何,
rand()
都会返回一个int
- 你不需要用任何东西修改它 - 您需要通过
int*
写入随机数据,以便一次访问 4 个字节,而不是简单地从随机数据的末尾切出一个字节并覆盖每四个字符 - 对于像这样依赖于
int
大小的东西,你真的应该用sizeof(int)
来写它,这样即使int不是32位也可以工作,或者使用(目前可悲的(非标准但常见的typedef,例如int32_t
(或者在Windows上我认为它是__int32
,或者你可以使用boost
或其他库头来获取int32_t
, 或编写自己的typedef
(。
对齐文本数据实际上非常棘手:您的代码建议您想要从第 35 个字符开始int
大小的切片......即使整体字符数组与整数正确对齐,第 35 个字符也不会对齐。
如果它确实始终是第 35 个,那么您可以使用前导字符填充数据,以便访问第 36 个(可能是 32 位int
大小的倍数(,然后将文本对齐到 32 位地址(使用特定于编译器的#pragma
或使用与 int32_t
的并集(。 如果实际代码改变了您开始覆盖的字符,以至于您无法简单地对齐一次数据,那么您将陷入困境:
- 您的原始字符一次覆盖
- 非可移植的未对齐覆盖(如果可能且在您的系统上更好(,或 实现最多覆盖三个
- 前导未对齐字符的代码,然后切换到对齐地址的 32 位整数覆盖模式,然后返回到最多三个尾随字符的逐字符覆盖。
这不起作用,因为生成的值被转换为数组元素的类型 - char
在这种特殊情况下。但是,您可以按照自己喜欢的方式自由解释分配的内存。例如,您可以将其转换为数组int
:
unsigned char TXT[] = { data1,data2,data3,data4,data4,data5....
for (i = 34; i < flenght-sizeof(int); i+=sizeof(int)) // generating the data to send.
*(int*)(TXT+i) = rand(); // There is no need in modulo operator
for (; i < flenght; ++i) // generating the data to send.
TXT[i] = rand(); // There is no need in modulo operator either
我只想用关于模运算符和数组处理而不是sizeof(int)
倍数的评论来完成解决方案。
1( %
的意思是"除以时的余数",所以你想要rand() % 256
字符,否则你永远不会得到值为 255 的字符。与 int 情况类似,尽管在这里无论如何都没有必要进行模运算,因为您想要整个输出值范围。
2(rand
通常一次只生成两个字节;检查 RAND_MAX 的值。
3(反正34不能被4整除,所以你必须专门处理最终情况。
4(您将需要投射指针,如果它尚未对齐,它将不起作用。但是,一旦有了强制转换,就不需要考虑迭代中的sizeof(int)
:指针算术会自动处理元素大小。
5(很有可能它不会产生明显的差异。如果将随机数据写入数组确实是程序中的瓶颈,那么无论如何它都没有真正做任何有意义的事情。
- 生成随机.txt文件,10行,10列。充满随机:"*"、"#"、"@"。然后将随机字符替换为'P'
- 我想仅使用递归将字符"a"替换为字符"z"
- 将一个字符替换为字符串中更多数量的字符,而不删除C++中的其他字母
- 如何将像'A'这样的单个字符替换为类似"10"?
- Qt:文件名中的非 ASCII 字符替换为"?"
- 我无法用字符替换重复的数字"a"
- QtLineEdit 占位符:如何让用户在插入模式下将字符 1 替换为 1
- 将一个特定字符替换为正则表达式匹配中的另一个字符
- 如何将所有出现的字符替换为给定的字符串
- 将一个数组到另一个数组的字符替换为字符串
- C++ 字符串,用于删除字符'b'并将字符'a'替换为两个'd'的构建函数
- 将字符串中的所有非 ASCII 字符替换为其等效的 ASCII
- 将utf8编码的字符串转换为本地8位编码的字符串,并将无法确定的字符替换为空白
- C++-用非ascii字符替换文件中的特殊字符
- 将字符串中的 č,š,ć 等字符替换为其 html 代码C++
- 用连字符替换字符串中的文本
- 用不同字符替换单词的代码
- 将空白字符替换为 %20 的字符串,忽略所有尾随空格
- 将部分字符*替换为较小的字符*
- 将字符串中的字符替换为某个字符串