2012-06-29 47 views
4

任何人都可以建议一个简单的方法将csv字符串转换为C中的浮点数组?将csv字符串转换为浮点数组

例如

char my_string[] = "1.0,2.0,3.0"; 

到:

my_array = [1.0, 2.0, 3.0] 

其中my_array类型为float[]

我会用sscanf作为一个快速简便的解决方案,但我不知道有多少值都包含在字符串中提前

是否有一些现有的库函数可以做到这一点,而我不得不求助于循环遍历每个char寻找一个“,”?

回答

6

你可以使用strtok()

float my_array[N]; // if you don't know how many there are, use the heap 
int i = 0; 

char *tok = strtok(my_string, ","); 
while (tok != NULL) { 
    my_array[i++] = atof(tok); 
    tok = strtok(NULL, ","); 
} 
+3

...如果你不介意'strtok()'在你的字符串中间散发空值...... –

2

使用一个while()循环,每次只读取一个浮点数与sscanf()。只要sscanf()返回0,就知道你已经在列表的最后。

+0

你怎么sscanf会沿着字符串推进,即通过每一个CSV前进? – bph

+0

对不起,没有想到那个。只有按照预期的方式使用scanf,fscanf .. – ypnos

+1

您可以使用'%n'转换说明符查找读取的字符数。你必须小心一点;逗号的哪一边呢?或者你在'sscanf()'之外处理逗号?可能是后者。所以:'size_t offset = 0; int position; while(sscanf(buffer + offset,“%lf%n”,&my_array [i],&position)== 1){offset + = position; if(buffer [offset] ==',')position ++; }'将近似于需要的东西。 –

3

有,你可以使用库 - LibCSV

从他们的描述:

libcs​​v是一个小的,简单而快速的CSV库用纯ANSI C89,可以读取和写入CSV数据。它使用回调函数来处理解析的领域和行 提供了一个直接的 接口,可解析格式不正确的CSV文件

0

你可能要考虑使用strchr功能家族。

STRCHR(3)   Linux Programmer's Manual   STRCHR(3) 

NAME 
     strchr, strrchr - locate character in string 

SYNOPSIS 
     #include <string.h> 

     char *strchr(const char *s, int c); 

     char *strrchr(const char *s, int c); 

DESCRIPTION 
     The strchr() function returns a pointer to the first 
     occurrence of the character c in the string s. 

     The strrchr() function returns a pointer to the last 
     occurrence of the character c in the string s. 

RETURN VALUE 
     The strchr() and strrchr() functions return a pointer to 
     the matched character or NULL if the character is not 
     found. 

CONFORMING TO 
     SVID 3, POSIX, BSD 4.3, ISO 9899 

SEE ALSO 
     index(3), memchr(3), rindex(3), strpbrk(3), strsep(3), 
     strspn(3), strstr(3), strtok(3) 
1
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

char** split(const char *str, const char *delimiter, size_t *len){ 
    char *text, *p, *first, **array; 
    int c; 
    char** ret; 

    *len = 0; 
    text=strdup(str); 
    if(text==NULL) return NULL; 
    for(c=0,p=text;NULL!=(p=strtok(p, delimiter));p=NULL, c++)//count item 
     if(c==0) first=p; //first token top 

    ret=(char**)malloc(sizeof(char*)*c+1);//+1 for NULL 
    if(ret==NULL){ 
     free(text); 
     return NULL; 
    } 
    strcpy(text, str+(first-text));//skip until top token 
    array=ret; 

    for(p=text;NULL!=(p=strtok(p, delimiter));p=NULL){ 
     *array++=strdup(p); 
    } 
    *array=NULL; 
    *len=c; 
    free(text); 
    return ret; 
} 

void free4split(char** sa){ 
    char **array=sa; 

    if(sa!=NULL){ 
     while(*sa) 
      free(*sa++);//for string 
     free(array); //for array 
    } 
} 

int main(){ 
    char my_string[] = "1.0,2.0,3.0"; 
    float *my_array; 
    char **strs; 
    size_t count; 

    strs=split(my_string, ", \t", &count); 
    my_array=(float*)malloc(sizeof(float)*count); 
    { //convert 
     int i; 
     for(i=0;i<count;++i) 
      my_array[i]=(float)atof(strs[i]); 
     free4split(strs); 

    } 
    { //test print 
     int i; 
     for(i=0;i<count;++i) 
      printf("%f\n", my_array[i]); 
    } 
    return 0; 
} 
+0

感谢你的回复,但这是我试图避免的那种C疯狂 - 是希望会有一个简单的一个或两个班轮,有人知道 – bph

+1

@Hiett - 像你寻求的一行内功能不存在于C语言的标准库中。 – BLUEPIXY

+0

拆分应该使用strtok_r – BLUEPIXY

1
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

char* getToken(char **p, const char delimiter){ 
    char *word, *top=*p; 
    int len; 

    if(*p == NULL || **p == '\0') return NULL; 
    while(**p && **p != delimiter) 
     ++(*p); 
    if(**p != delimiter) return strdup(top); 
    len = *p - top; 
    ++(*p); 
    word=(char*)malloc(sizeof(char)*(len+1)); 
    strncpy(word, top, len); 
    word[len]='\0'; 
    return word; 
} 

int main(){ 
    char my_string[] = "1.0,2.0,3.0"; 
    float *my_array=NULL; 
    char *word, *p=my_string; 
    int count=0; 

    while(NULL!=(word=getToken(&p, ','))){ 
     my_array=(float*)realloc(my_array, sizeof(float)*(++count)); 
     my_array[count-1]=(float)atof(word); 
     free(word); 
    } 
    { //test print 
     int i; 
     for(i=0;i<count;++i) 
      printf("%f\n", my_array[i]); 
    } 
    return 0; 
} 
相关问题