On Thu, Sep 06, 2007 at 11:00:11AM -0300, Matías Alejandro Torres wrote: > Here's the minimal program to read that. The reading part is kind of > crappy but it works with that example.
The trouble with the reading part is not that it's kind of crappy (well, it is IMO, reading by character makes no sense when g_ascii_strtod() and strtol() can perfectly iterate themselves *and* have error-reporting, g_slist_append() is O(N) making the reading O(N^2), it is a waste of time to construct a big GSList just to fill a GtkListStore from it instead of filling the store directly -- and if Data is a data structure used elsewhere in the program it makes little sense to break it into columns instead of storing it directly in a G_TYPE_BOXED/G_TYPE_POINTER column), but that: - it assigns the fgetc() return value to a gchar, breaking EOF testing - it uses a fixed unchecked buffer of size 50 we do now know whether overflows or not on your data - it takes any sequence of non-[ \t] as a field and reads it without checking so we do not know what actually happens on your data - it uses g_strtod() (NOT g_ascii_strtod() you've been talking about) which tries to accept both C and your current locale formats and therefore is not predictable (and won't help reading data that someone with a *different* local wrote in the locale-specific manner anyway) If the attached program reads the complete file and prints back its contents correctly, then I dare to say your problem is not broken g_ascii_strtod(). As a bonus, the attached program prints a detailed error to stderr if there are malformed data rows in the file. Yeti -- http://gwyddion.net/ ========================================================================= #define _GNU_SOURCE 1 #include <stdlib.h> #include <stdio.h> #include <string.h> #include <errno.h> #include <glib.h> typedef struct _Data { gchar *log; gdouble latitude; gint altitude; gint interval; gint heartbeat; gdouble speed; } Data; int main(int argc, char *argv[]) { const gchar *filename, *failfield; gchar *buf = NULL; size_t buf_size = 0, lineno; ssize_t line_len; FILE *fh; GSList *l, *stuff = NULL; Data *data; if (argc != 2) { g_printerr("readstuff FILE\n"); return 1; } filename = argv[1]; if (!(fh = fopen(filename, "r"))) { g_printerr("Cannot open %s: %s\n", filename, g_strerror(errno)); return 1; } lineno = 0; failfield = NULL; while ((line_len = getline(&buf, &buf_size, fh)) != -1) { gchar *start, *end; guint len; lineno++; start = g_strstrip(buf); /* Skip non-data lines */ if (!buf[0] || !g_ascii_isdigit(buf[0])) continue; data = g_new(Data, 1); len = strcspn(start, " \t"); data->log = g_strndup(start, len); start += len; data->latitude = g_ascii_strtod(start, &end); if (end == start) { failfield = "Latitude"; break; } start = end; data->altitude = strtol(start, &end, 10); if (end == start) { failfield = "Altitude"; break; } start = end; data->interval = strtol(start, &end, 10); if (end == start) { failfield = "IntervalTime"; break; } start = end; data->heartbeat = strtol(start, &end, 10); if (end == start) { failfield = "HeartRate"; break; } start = end; data->speed = g_ascii_strtod(start, &end); if (end == start) { failfield = "Speed"; break; } stuff = g_slist_prepend(stuff, data); if (*end) fprintf(stderr, "Warning: trailing garbage at line %lu of %s: %s\n", (unsigned long int)lineno, filename, buf); } fclose(fh); free(buf); if (failfield) { fprintf(stderr, "Cannot parse %s at line %lu of %s: %s\n", failfield, (unsigned long int)lineno, filename, buf); g_free(data->log); g_free(data); } else { stuff = g_slist_reverse(stuff); for (l = stuff; l; l = l->next) { data = (Data*)l->data; printf("%s %.5f %d %d %d %.2f\n", data->log, data->latitude, data->altitude, data->interval, data->heartbeat, data->speed); } } for (l = stuff; l; l = l->next) { data = (Data*)l->data; g_free(data->log); g_free(data); } g_slist_free(stuff); return !!failfield; } _______________________________________________ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list