我想将逗号分隔的char *转换为C中的uint32_array []。有一个简单的方法/例程吗?
我已经花了很多时间在SO上并在C ++上找到了很多解决方案,但不是那样的C: Parsing a comma-delimited std::string 但我认为从char *转换为字符串流到字符串流并使用向量并不是一个很好的解决方案。
char input[] = "1 , 2 , 34, 12, 46, 100";
到
uint32_t output[] = { 1 , 2 , 34, 12, 46, 100 };
我会感激任何帮助。非常感谢。
答案 0 :(得分:1)
一种方法(很多):
int converted = 0 ;
char* tok = input ;
int i = 0 ;
do
{
converted = sscanf( tok, "%d", &output[i] ) ;
tok = strchr( tok, ',' ) + 1 ;
i++ ;
} while( tok != NULL && converted != 0 ) ;
您可以使用strtok()
代替sscanf()
和strchr()
,但修改 input
,这可能是不受欢迎的。
如果输入是流而不是字符串,则更简单:
int converted = 0 ;
int i = 0 ;
do
{
converted = fscanf( fd, "%d,", &output[i] ) ;
i++ ;
} while( !feof( fd ) && converted != 0 ) ;
我没有提供任何方法来阻止output[i]
超出界限 - 您可能也需要考虑这一点。
答案 1 :(得分:1)
这是一种方法:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
int* values;
int count;
}
output_t;
output_t Read(char input[])
{
int* values = NULL;
int count = 0;
char* pch = strtok(input,", ");
while (pch != NULL)
{
values = realloc(values,(count+1)*sizeof(*values));
values[count++] = atoi(pch);
pch = strtok(NULL,", ");
}
return (output_t){values,count};
}
这是一个用法示例:
void Example()
{
char input[] = "1 , 2 , 34, 12, 46, 100";
output_t output = Read(input);
for (int i=0; i<output.count; i++)
printf("%d\n",output.values[i]);
free(output.values);
}
答案 2 :(得分:1)
这是一个只进行一次传递的递归算法。它分配在最深层次并填写出路:
int *cvt(char *input, int *level)
{
char *cp = strtok(input, ", ");
if (cp == NULL) {
/* No more separators */
return (int *) malloc(sizeof(int) * *level);
}
int my_index = -1;
int n;
if (sscanf(cp, "%d", &n) == 1) {
my_index = *level;
*level += 1;
} else {
printf("Invalid integer token '%s'\n", cp);
}
int *array = cvt(NULL, level);
if (my_index >= 0) {
array[my_index] = n;
}
return array;
}
致电:
int main(int ac, char **av)
{
char input[] = "1, 2, bogus, 4, 8, 22, 33, 55";
int n_array = 0;
int *array = cvt(input, &n_array);
int i;
printf("Got %d members:\n", n_array);
for (i = 0; i < n_array; ++i)
printf("%d ", array[i]);
printf("\n");
return 0;
}
答案 3 :(得分:1)
我会将我的帽子扔进戒指并进行一次数据传递。我估计所需的数组大小是最糟糕的情况,其中每个数据都是“n”形式,所以每个数字两个字节,然后调整大小。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef unsigned int uint32_t;
int main (void) {
char input[] = "1 , 2 , 34, 12, 46, 100";
uint32_t *output, *temp;
char *tok;
int elements = 0;
int len = 1 + strlen(input) / 2; // estimate max num of elements
output = malloc(len * sizeof(*output));
if (output == NULL)
exit(-1); // memory alloc error
tok = strtok(input, ", "); // parse the string
while (tok != NULL) {
if (elements >= len)
exit(-2); // error in length assumption
if (1 != sscanf(tok, "%u", output + elements))
exit(-3); // error in string format
elements++;
tok = strtok(NULL, ", ");
}
temp = realloc(output, elements * sizeof(*output)); // resize the array
if (temp == NULL)
exit(-4); // error in reallocating memory
output = temp;
for (len=0; len<elements; len++)
printf("%u ", output[len]);
printf("\n");
free(output);
return 0;
}
节目输出:
1 2 34 12 46 100
答案 4 :(得分:0)
通读字符串一次以弄清楚如何调整数组的大小:
uint32_t n = 1;
for (uint32_t idx = 0; idx < strlen(input); idx++) {
if (input[idx] == ',') {
n++;
}
}
执行此操作的另一种方法并不需要读取字符串,但它需要在新元素进入时调整目标数组的大小,这会使代码更复杂。对于小字符串来说,读取字符串很容易。
制作目标阵列:
uint32_t* output = NULL;
output = malloc(sizeof(*output) * n);
if (!output) {
fprintf(stderr, "Error: Could not allocate space for output array!\n");
exit(EXIT_FAILURE);
}
填充数组。在不破坏字符串的情况下执行此操作的一种方法是保留指向包含逗号分隔字符串中所需数字元素的子字符串的开头和结尾的几个指针,并且只是循环遍历字符串中的所有字符:
#define MAX_LEN 13
char* start = &input[0];
char* end = &input[0];
char entry[MAX_LEN];
uint32_t entry_idx = 0;
int finished = 0; // false
do {
end = strchr(start, ',');
if (!end) {
end = input + strlen(input);
finished = 1;
}
memcpy(entry, start, end - start);
entry[end - start] = '\0';
sscanf(entry, "%u", &output[entry_idx++]);
start = end + 1;
} while (!finished);
MAX_LEN
为13,因为uint32_t
不太可能超过13位数。对于2100年制造的计算机,您可以将此更长时间地证明这一点。
请务必在完成后释放阵列:
free(output);
output = NULL;
答案 5 :(得分:0)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
int getsize(char* str, char* delimiters) //give the size of the final uint32_t array[]
{
int count = 0;
char* st = strdup(str), *t = strtok(st, delimiters);
while(t)
{
count++;
t = strtok(NULL, delimiters);
}
free(st);
return count;
}
uint32_t* Char_to_Array(char *data, char* delimiters, int *siz) //siz is a pointer to get the size of the array
{
char* st = strdup(data), *t = NULL; //dup string, strtok mage change on the passed string
*siz = getsize(data, delimiters);
uint32_t* buf=(uint32_t *)malloc((*siz)*4);
t = strtok(st, delimiters); //split string by " "
int i = 0;
while(t)
{
buf[i] = atoi(t);
t = strtok(NULL, delimiters);
i++;
}
free(st);
return buf;
}
这里是一个带有主要功能的测试
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
int main()
{
int getsize(char* str, char* delimiters), siz = 0, i = 0;
uint32_t* Char_to_Array(char *data, char* delimiters, int *x);
uint32_t* t = Char_to_Array("123, 156, 4658,7878", " ,", &siz);
while(i<siz)
{
printf("array[%d] = %d\n", i, t[i]);
i++;
}
free(t);
return 0;
}
答案 6 :(得分:0)
2通过方法:
1)计算逗号数并分配一个数组。
2)解析字符串 - 查找错误。
[uint32逗号晚会]
#include <errno.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include <inttypes.h>
typedef struct {
uint32_t *u32;
size_t count;
bool error;
} CSV_32_T;
CSV_32_T CSV_to_int32_list(const char *csv) {
CSV_32_T list = { NULL, 1, false };
// 1st pass: Quickly go through list counting commas
const char *p = csv;
for (p = csv; *p; p++) {
if (*p == ',') {
list.count++;
}
}
size_t i = 0;
list.u32 = malloc(list.count * sizeof *list.u32);
if (list.u32) {
// 2nd pass: scan
p = csv;
for (i = 0; i < list.count; i++) {
if (i > 0 && *p++ != ',') {
break;
}
int n = 0;
if (1 != sscanf(p, "%" SCNu32 " %n", &list.u32[i], &n)) {
break;
}
p += n;
}
}
if (i != list.count || *p) {
free(list.u32);
return (CSV_32_T ) { NULL, 0, true } ;
}
return list;
}
void testCSV(const char *csv) {
CSV_32_T y = CSV_to_int32_list(csv);
printf("%d %zu \"%s\"\n", y.error, y.count, csv);
}
int main(void) {
testCSV("1 , 2 , 34, 12, 46, 100");
testCSV("1 2 , 34, 12, 46, 100");
return 0;
}