Ich möchte eine Variablen, die Vektoren aus weißem Raum abgegrenzten Textdatei und der Stolperstein scannen (alles zu oft für mich) ist Mangel an Eleganz.Scannen Variable Anzahl von 'Feldern' aus einer Textdatei
Derzeit mein Scancode die Größe des Vektors als erstes Element in der Datei erfordert abgrenzt:
7 : 1 3 6 8 -9 .123 1.1
Was ich stört, weil die ‚7‘ durch Überprüfen des Leerraumes ermittelt werden kann.
Ich habe verschiedene Formen von fscanf(), strtok() usw. ausprobiert, aber alle scheinen rohe Gewalt zu sein. Ohne auf Lex/Yacc (nicht verfügbar) zurückgreifen zu können, könnte jemand etwas eleganteres vorschlagen als das Folgende?
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 */
}
}
Lösung: Dank der überprüften Antwort, ich implementiert:
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() */
Wenn Sie steuern können, wie die Eingabedaten formatiert werden, können Sie versuchen, auf die Vektorlänge zu verzichten. Dadurch wird die spezielle Hülle für die Vektorlänge entfernt und Sie gelangen direkt in das Tokenizing. Wenn Sie Ihre längste Vektorzeichenfolge zuverlässig kennen, können Sie sie in ein Array zerlegen und dann Ihren Vektorwert basierend auf der Anzahl der in Token angegebenen Werte zuweisen. Der Sscanf lässt mich zusammenzucken, aber jeder für sich. – Erik