csv文字列をCのfloatの配列に変換する簡単な方法について誰かアドバイスできますか?
例えば
char my_string[] = "1.0,2.0,3.0";
に:
my_array = [1.0, 2.0, 3.0]
my_array のタイプはfloat[]
迅速かつ簡単な解決策として使用sscanf
しますが、事前に文字列に含まれる値の数がわかりません
char
「、」を探すたびにループする必要なく、これを実行できる既存のライブラリ関数はありますか?
csv文字列をCのfloatの配列に変換する簡単な方法について誰かアドバイスできますか?
例えば
char my_string[] = "1.0,2.0,3.0";
に:
my_array = [1.0, 2.0, 3.0]
my_array のタイプはfloat[]
迅速かつ簡単な解決策として使用sscanf
しますが、事前に文字列に含まれる値の数がわかりません
char
「、」を探すたびにループする必要なく、これを実行できる既存のライブラリ関数はありますか?
使用できます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, ",");
}
使用できるライブラリがあります-LibCSV
彼らの説明から:
libcsv は、純粋な ANSI C89 で書かれた小さくてシンプルで高速な CSV ライブラリで、CSV データの読み書きが可能です。コールバック関数を使用して解析されたフィールドと行を処理する簡単なインターフェイスを提供し、不適切にフォーマットされた CSV ファイルを解析できます
while()
で一度に 1 つの float のみを読み取るループを使用しますsscanf()
。0 が返されるとすぐsscanf()
に、リストの最後にいることがわかります。
#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;
}
#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;
}
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)