如何在C中将逗号分隔的char*转换为uint32_t[]数组



我想在C中将逗号分隔的char*转换为uint32_array[]。有简单的方法/例程可以做到这一点吗?

我已经在SO上花了很多时间,并在C++上找到了许多解决方案,但不是这样的C:分析逗号分隔的std::字符串但我认为从char*到string再到string再从stream到vector并使用vector并不是一个好的解决方案。

char input[] = "1 , 2 , 34, 12, 46, 100";

uint32_t output[] = { 1 , 2 , 34, 12, 46, 100 };

如果有任何帮助,我都将不胜感激。非常感谢。

这里有一个递归算法,只进行一次遍历。它在最深层进行分配,并在退出时填充:

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;
}

一种(多种(方法:

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]超出界限的方法——您可能也需要考虑这一点。

这里有一种方法:

#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("%dn",output.values[i]);
    free(output.values);
}

我会全力以赴,完成一次数据传递。我估计所需的数组大小是最坏的情况,其中每个数据的形式都是"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

通读字符串一次,找出如何调整数组大小:

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] = '';
    sscanf(entry, "%u", &output[entry_idx++]);
    start = end + 1;
} while (!finished);

CCD_ 6是13,因为CCD_。对于2100年制造的计算机,您可以将其制作得更长,以防将来发生故障。

完成后一定要释放阵列:

free(output); 
output = NULL;
#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] = %dn", i, t[i]);
    i++;
  }
  free(t);
  return 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;
}

最新更新