2012-06-29 49 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; 
} 
相關問題