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

Reply via email to