空白で区切られたテキスト ファイルからベクトルを形成する変数をスキャンしたいのですが、つまずきは (私にとってはよくあることですが) エレガンスの欠如です。
現在、私のスキャン コードでは、ファイルの最初の要素としてベクトルのサイズを示す必要があります。
7 : 1 3 6 8 -9 .123 1.1
「7」は空白を調べることで判断できるため、これは気になります。
fscanf()、strtok() などのさまざまな形式を試してみましたが、すべて総当たりのようです。lex/yacc (利用できません) に頼ることなく、誰かが次のものよりもエレガントなものを提案できますか?
typedef struct vector_tag
{
int Length;
double * value;
} vector;
vector v;
char buf[BIG_ENOUGH], key[BIG_ENOUGH], val[BIG_ENOUGH];
void scan_vector(FILE * fh)
{
int i, length;
double * data;
char * tok;
do {
if (feof(fh)) return;
fgets(buf, sizeof buf, fh);
} while (2 != sscanf(buf,"%[^:]:%[^\n\r]",key,val));
length =
v.Length = strtol(key,NULL,10);
data =
v.value = malloc(length * sizeof(double));
tok = strtok(val, " "); /* I'd prefer tokenizing on whitespace */
for (i = 0; i++ < v.Length; ) {
* data++ = strtod(tok,NULL);;
tok = strtok(NULL, " "); /* Again, tokenize on whitespace */
}
}
解決策:チェックされた回答のおかげで、実装しました:
static int scan_vector(FILE * fh, vector * v)
{
if (1 == fscanf(fh,"%d:",& v->length))
{
int i;
v->value = malloc(v->Length * sizeof(double));
assert (NULL != v->value);
for (i = 0; i < v->Length; i++)
{
if (fscanf(fh,"%lf",v->value + i) != 1) return(0);
}
return(1);
}
return(0);
} /* scan_vector() */