Я хотел бы сканировать переменные, которые образуют векторы из текстового файла с разделителями в виде пробела, а камень преткновения (все для меня часто) - это отсутствие элегантности.Сканирование номера переменной «полей» из текстового файла
В настоящее время мой код сканирования требует обозначающая размер вектора в качестве первого элемента в файле:
7 : 1 3 6 8 -9 .123 1.1
Что беспокоит меня, потому что «7» может быть определена путем проверки белого пространства.
Я пробовал различные формы fscanf(), strtok() и т. Д., Но все они кажутся грубыми forcish. Не прибегая к 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() */
Если у вас есть контроль над форматированием входных данных, вы можете попытаться обойтись без длины вектора. Это удаляет специальный корпус для длины вектора и перемещает вас прямо в токенизацию. Если вы можете надежно узнать свою длинную векторную строку, вы можете проанализировать ее в массиве и затем распределить вектор vector.value на основе количества значений, обозначенных как токенизация. Sscanf заставляет меня съеживаться, но каждый из них. – Erik