在 C 中提高速度的字符串拆分建议
String splitting advice for speed in C
我有一个大小为 3060 的字符数组 (uint8_t)。这是通过读取一个 CSV 文件得到的,该文件的每一行都有 51 个字节的数据。我希望将其拆分,以便一次获取 51 个字节的数据。所以我想要的是 0-51 然后 52-102 等等
我打算用这个做的是通过我正在工作的蓝牙 gatt 连接发送这些数据。
是否可以 memcpy 这个数组的一部分,例如:
memcpy(my3060_data[0-50],data_to_send_1,sizeof(data_to_send_1));
然后将值循环到 3060?
因此,我希望这个过程快点,有什么建议吗?
使用循环可以简化流程。例如:
#include <stdint.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
uint8_t buffer[52], chunkSize, data[3060];
uint16_t processed = 0;
while(processed < sizeof(data))
{
if((processed + sizeof(buffer)) < sizeof(data))
chunkSize = sizeof(buffer);
else
chunkSize = sizeof(data) - processed;
printf("%u, ", chunkSize);
memcpy(buffer, data + processed, chunkSize);
processed += chunkSize;
}
printf("\n");
return 0;
}
这会产生以下结果:
$ gcc main.c -o main.exe; ./main.exe
52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 44,
注意最后一个块是 44 字节。
你如何处理缓冲区由你决定。
如果您可以逐行读取 CSV 文件,那么您可以执行以下操作:
char buffer[100];
FILE *fptr;
if ((fptr = fopen("file_to_open.csv", "r")) = NULL)
{
printf("Error! opening file");
// Program exits if file pointer returns NULL.
exit(1);
}
while(fscanf(fptr, "%[^\n]", buffer)!=EOF)
{
//process buffer
}
fclose(fptr);
I want this process to be quick any advice?
用1读取文件fread()
。最节省时间的地方是高效的 I/O 操作。
这是在 OP "I have an array of chars(uint8_t)
that has a size of 3060" 之前,但它比后续代码中的小代码调整更有用。
#define DATA_SIZE 3060
uint8_t data[DATA_SIZE+1]; // One more to detect too large a file.
if (DATA_SIZE == fread(data, 1, sizeof data, CSV_file)) {
// Success
} else {
// Oops
}
OP 的 memcpy()
肯定有问题。
// Bad
// memcpy(my3060_data[0-50],data_to_send_1,sizeof(data_to_send_1));
// More like
#define LINE_SIZE 51
for (int index = 0; index < DATA_SIZE; index += LINE_SIZE) {
uint8_t data_to_send_1[LINE_SIZE];
memcpy(data_to_send_1, &my3060_data[index], LINE_SIZE);
send_it(data_to_send_1, LINE_SIZE);
// OR skip the copy
send_it(&my3060_data[index], LINE_SIZE);
}
我有一个大小为 3060 的字符数组 (uint8_t)。这是通过读取一个 CSV 文件得到的,该文件的每一行都有 51 个字节的数据。我希望将其拆分,以便一次获取 51 个字节的数据。所以我想要的是 0-51 然后 52-102 等等
我打算用这个做的是通过我正在工作的蓝牙 gatt 连接发送这些数据。 是否可以 memcpy 这个数组的一部分,例如:
memcpy(my3060_data[0-50],data_to_send_1,sizeof(data_to_send_1));
然后将值循环到 3060?
因此,我希望这个过程快点,有什么建议吗?
使用循环可以简化流程。例如:
#include <stdint.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
uint8_t buffer[52], chunkSize, data[3060];
uint16_t processed = 0;
while(processed < sizeof(data))
{
if((processed + sizeof(buffer)) < sizeof(data))
chunkSize = sizeof(buffer);
else
chunkSize = sizeof(data) - processed;
printf("%u, ", chunkSize);
memcpy(buffer, data + processed, chunkSize);
processed += chunkSize;
}
printf("\n");
return 0;
}
这会产生以下结果:
$ gcc main.c -o main.exe; ./main.exe
52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 44,
注意最后一个块是 44 字节。
你如何处理缓冲区由你决定。
如果您可以逐行读取 CSV 文件,那么您可以执行以下操作:
char buffer[100];
FILE *fptr;
if ((fptr = fopen("file_to_open.csv", "r")) = NULL)
{
printf("Error! opening file");
// Program exits if file pointer returns NULL.
exit(1);
}
while(fscanf(fptr, "%[^\n]", buffer)!=EOF)
{
//process buffer
}
fclose(fptr);
I want this process to be quick any advice?
用1读取文件fread()
。最节省时间的地方是高效的 I/O 操作。
这是在 OP "I have an array of chars(uint8_t)
that has a size of 3060" 之前,但它比后续代码中的小代码调整更有用。
#define DATA_SIZE 3060
uint8_t data[DATA_SIZE+1]; // One more to detect too large a file.
if (DATA_SIZE == fread(data, 1, sizeof data, CSV_file)) {
// Success
} else {
// Oops
}
OP 的 memcpy()
肯定有问题。
// Bad
// memcpy(my3060_data[0-50],data_to_send_1,sizeof(data_to_send_1));
// More like
#define LINE_SIZE 51
for (int index = 0; index < DATA_SIZE; index += LINE_SIZE) {
uint8_t data_to_send_1[LINE_SIZE];
memcpy(data_to_send_1, &my3060_data[index], LINE_SIZE);
send_it(data_to_send_1, LINE_SIZE);
// OR skip the copy
send_it(&my3060_data[index], LINE_SIZE);
}