yeti>> I have tested your minimal testprogram with the whole test-file. Unfortunately the program doesn't print anything to stdout. It doesn't seem to be any data stored in the GSList or in the datastructure, Data *data. (I tried to print a field every time a new line was about to be read in the while-loop). Furthermore, I wonder if the test, if(end == start) failfield = "Latitude";, can conclude that the string was converted correctly with g_ascii_strtod(). If g_ascii_strtod() converts only a fraction of the string, it will result in (end != start) and failfield won't be set which results in no output to stderr.
Magnus On Thu, 6 Sep 2007 21:13:44 +0200 David Nečas (Yeti) <[EMAIL PROTECTED]> wrote: > 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 _______________________________________________ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list