[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]
Re: Conversion functions.
- From: Magnus Myrefors <myrefors magnus telia com>
- To: gtk-app-devel-list gnome org
- Subject: Re: Conversion functions.
- Date: Fri, 7 Sep 2007 01:45:09 +0200
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) <yeti physics muni cz> 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
[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]