Прикол в тому, що в мене strtod взагалі не працює.
Насправді, я все життя використовував sprintf. Чого можу побажати і топікстартеру=)
А можна приклад коду з використанням sprintf для перетворення строки в раціональне число?
Код: [Вибрати]#include <stdio.h>...$ ./test1.2000001072902963.0000001072693248.000000
#include <stdio.h>...$ ./test1.2000001072902963.0000001072693248.000000
#include <stdio.h>#define __USE_GNU 1#include <stdlib.h>#include <locale.h>char *def = "12.3456";intmain (int argc, char **argv){ char *s; char *endp; double d=0.0; locale_t c_locale; // Set default locale setlocale (LC_ALL, ""); if ( argc > 1) s=argv[1]; else s=def; endp=s; printf("String: %s\n", s); // Create "C" locale c_locale = newlocale(LC_ALL_MASK, "C", NULL); if (c_locale == NULL) { puts("Cannot get C locale.\n"); return 1; } // Convert string to double using "C" locale d = strtod_l (s, &endp, c_locale); if (s != endp && *endp == '\0') printf("%s - it's a float with value %f\n", s, d); else { printf("%s - it's not a number.", s); } // Free unused locale freelocale(c_locale); return 0;}$ ./test-strtodString: 12.345612.3456 - it's a float with value 12,345600
#include <stdio.h>#include <string.h>#include <ctype.h>#include <stdlib.h>#include <math.h>#include <locale.h>#include <libxml/xmlmemory.h>#include <libxml/parser.h>#include "prj.h"int numword (char *str){ char *keys = "sphere\0intersphcyl\0"; int sl, siz, i = 0; siz = 0; do { if (!strcmp (keys + siz, str)) return i; sl = strlen (keys + siz); siz += sl + 1; i++; } while (sl); return -1;}int getword (char *from, char *to){ int i, dsp; for (dsp = 0; isspace (from[dsp]); dsp++); for (i = dsp; !isspace (from[i]); i++) to[i - dsp] = from[i]; to[i - dsp] = 0; return i;}CYLINDER interspher_cyl (SPHERE * sph1, SPHERE * sph2, double r){ double r1, r2, l; vector nap; CYLINDER res; r1 = sqrt (sph1->r * sph1->r - r * r); r2 = sqrt (sph2->r * sph2->r - r * r); nap = VecIneq (sph1->o, sph2->o); l = sqrt (VecAbs2 (nap)); res.r = r; res.n = ProdScal (1. / l, nap); res.o = VecIneq (sph1->o, ProdScal (r1, res.n)); res.l = l - r1 - r2; // ADDING holes to spheres sph2->holes = realloc (sph2->holes, (sph2->nh + 1) * sizeof (HOLE)); sph2->holes[sph2->nh].n = res.n; sph2->holes[sph2->nh].o = VecSum (sph2->o, ProdScal (r2, res.n)); sph2->holes[sph2->nh].r = r; sph2->holes[sph2->nh].figure = 1; sph2->nh++; sph1->holes = realloc (sph1->holes, (sph1->nh + 1) * sizeof (HOLE)); sph1->holes[sph1->nh].n = ProdScal (-1., res.n); sph1->holes[sph1->nh].o = res.o; // VecSum(sph1->o,ProdScal(-r1 // ,res.n)); sph1->holes[sph1->nh].r = r; sph1->holes[sph1->nh].figure = 1; sph1->nh++; res.figure1 = 1; res.figure0 = 1; return res;}KUPA3D interpret_3dvl (FILE * fp){ KUPA3D res; char buff[100]; memset (&res, 0, sizeof (KUPA3D)); res.cyls = 0; res.sphers = 0; res.ncyls = 0; res.nsphers = 0; while (fgets (buff, 100, fp)) { char word[15]; int pos; pos = getword (buff, word); switch (numword (word)) { double r, x, y, z; int n1, n2; case 0: sscanf (buff + pos, "%lf %lf %lf %lf", &x, &y, &z, &r); res.sphers = realloc (res.sphers, sizeof (SPHERE) * (res.nsphers + 1)); res.sphers[res.nsphers].r = r; res.sphers[res.nsphers].o.x = x; res.sphers[res.nsphers].o.y = y; res.sphers[res.nsphers].o.z = z; res.sphers[res.nsphers].holes = NULL; res.sphers[res.nsphers].nh = 0; res.nsphers++; break; case 1: sscanf (buff + pos, "%d %d %lf", &n1, &n2, &r); if (n1 >= res.nsphers || n2 >= res.nsphers) { fprintf (stderr, "Spheres Overflow\n"); break; } res.cyls = realloc (res.cyls, sizeof (CYLINDER) * (res.ncyls + 1)); res.cyls[res.ncyls] = interspher_cyl (res.sphers + n1, res.sphers + n2, r); res.ncyls++; break; } } return res;}typedef struct { int n1, n2; double r;} INTERSPHERCYL;INTERSPHERCYL parse_intersphcyl (xmlDocPtr doc, xmlNodePtr cur){ INTERSPHERCYL res; xmlChar *key; int neibours = 0; cur = cur->xmlChildrenNode; while (cur != NULL) { if ((!xmlStrcmp (cur->name, (const xmlChar *) "radius"))) { key = xmlNodeListGetString (doc, cur->xmlChildrenNode, 1); res.r = atof (key); // printf("keyword: %s\n", key); xmlFree (key); } if ((!xmlStrcmp (cur->name, (const xmlChar *) "neibour"))) { key = xmlNodeListGetString (doc, cur->xmlChildrenNode, 1); if (neibours == 0) { res.n1 = atoi (key); neibours++; } else res.n2 = atoi (key); // printf("keyword: %s\n", key); xmlFree (key); } if ((!xmlStrcmp (cur->name, (const xmlChar *) "neibours"))) { char *endptr, *sptr; long int val; key = xmlNodeListGetString (doc, cur->xmlChildrenNode, 1); sptr = key; val = strtol (sptr, &endptr,10); if (sptr != endptr && *sptr != 0) { res.n1 = val; sptr = endptr; } else fprintf (stderr, "error reading neibours numbers\n"); val = strtol (sptr, &endptr,10); if (sptr != endptr && *sptr != 0) { res.n2 = val; // sptr = endptr; } else fprintf (stderr, "error reading neibours numbers\n"); // printf("keyword: %s\n", key); xmlFree (key); } cur = cur->next; } return res;}SPHERE parse_sphere (xmlDocPtr doc, xmlNodePtr cur){ xmlChar *key; cur = cur->xmlChildrenNode; SPHERE res; while (cur != NULL) { if ((!xmlStrcmp (cur->name, (const xmlChar *) "center"))) { char *endptr, *sptr; double val; // fprintf(stderr,"pos 1\n");fprintf(stderr,"pos 2\n"); key = xmlNodeListGetString (doc, cur->xmlChildrenNode, 1); // printf("keyword: %s\n", key); sptr = key; val = strtod (sptr, &endptr); if (sptr != endptr && *sptr != 0) { res.o.x = val; sptr = endptr; } else fprintf (stderr, "error reading atom coordinates\n"); val = strtod (sptr, &endptr); if (sptr != endptr && *sptr != 0) { res.o.y = val; sptr = endptr; } else fprintf (stderr, "error reading atom coordinates\n"); val = strtod (sptr, &endptr); if (sptr != endptr && *sptr != 0) { res.o.z = val; sptr = endptr; } else fprintf (stderr, "error reading atom coordinates\n"); // res.r=atof(key); xmlFree (key); } if ((!xmlStrcmp (cur->name, (const xmlChar *) "radius"))) { key = xmlNodeListGetString (doc, cur->xmlChildrenNode, 1); // printf("keyword: %s\n", key); res.r = atof (key); xmlFree (key); } cur = cur->next; } res.holes = NULL; res.nh = 0; return res;}KUPA3D interpret_3d_xml (char *docname){ xmlDocPtr doc; xmlNodePtr cur;KUPA3D res;setlocale(LC_NUMERIC,"C"); doc = xmlParseFile (docname); memset (&res, 0, sizeof (KUPA3D)); if (doc == NULL) { fprintf (stderr, "Document not parsed successfully. \n"); return res; } cur = xmlDocGetRootElement (doc); if (cur == NULL) { fprintf (stderr, "empty document\n"); xmlFreeDoc (doc); return res; } // printf ("rootname is %s\n", cur->name); if (xmlStrcmp (cur->name, (const xmlChar *) "box")) { fprintf (stderr, "document of the wrong type, root node != box"); xmlFreeDoc (doc); return res; } cur = cur->xmlChildrenNode; // printf ("current name xmlChildrenNode: %s\n", (cur != NULL) ? cur->name : 0); while (cur != NULL) { if ((!xmlStrcmp (cur->name, (const xmlChar *) "sphere"))) { SPHERE sph = parse_sphere (doc, cur);res.sphers = realloc (res.sphers, sizeof (SPHERE) * (res.nsphers + 1)); res.sphers[res.nsphers] = sph; res.nsphers++;///// printf ("x=%g,y=%g,z=%g,r=%g\n", sph.o.x, sph.o.y, sph.o.z, sph.r); // // } if ((!xmlStrcmp (cur->name, (const xmlChar *) "intersphcyl"))) { INTERSPHERCYL isph = parse_intersphcyl (doc, cur); if (isph.n1 >= res.nsphers || isph.n2 >= res.nsphers) { fprintf (stderr, "Spheres Overflow\n"); continue; } res.cyls = realloc (res.cyls, sizeof (CYLINDER) * (res.ncyls + 1)); res.cyls[res.ncyls] = interspher_cyl (res.sphers + isph.n1, res.sphers + isph.n2, isph.r); res.ncyls++;//// printf ("n1=%d,n2=%d, r=%g\n", isph.n1, isph.n2, isph.r); // // } cur = cur->next; // printf("current name cur->next: %s\n",(cur // != NULL)?cur->name:0); } xmlFreeDoc (doc); setlocale(LC_NUMERIC,""); return res;}
#ifndef _GNU_SOURCE#define _GNU_SOURCE#endif
(...) ... (...). (...) fprintf(stderr,...);
Чи можна якось примусити sizeof говорити розмір типу, пойнтером на який є елемент структури, явно цей тип не задаючи?