Автор Гілка: Кляті бібліотеки! не можу більше  (Прочитано 6247 раз)

Відсутній raven

  • Новачок
  • *
  • дописів: 0
  • Карма: +0/-0
  • linux kettle
Re: Кляті бібліотеки! не можу більше
« Відповідей #15 : 2008-06-20 15:19:52 »
Прикол в тому, що в мене strtod взагалі не працює.  :o
Гм, і то правда...

Насправді, я все життя використовував sprintf. Чого можу побажати і топікстартеру=)

Відсутній Сергій Лисовенко

  • Літератор
  • ******
  • дописів: 1489
  • Карма: +0/-0
Re: Кляті бібліотеки! не можу більше
« Відповідей #16 : 2008-06-20 15:57:14 »
Насправді, я все життя використовував sprintf. Чого можу побажати і топікстартеру=)
А можна приклад коду з використанням sprintf для перетворення строки в раціональне число?
 ;D ;D ;D
« Змінено: 2008-06-20 15:57:39 від serg_ik »
Якщо Лінукс написали студенти - нехай вони під ним і навчаються.

Відсутній raven

  • Новачок
  • *
  • дописів: 0
  • Карма: +0/-0
  • linux kettle
Re: Кляті бібліотеки! не можу більше
« Відповідей #17 : 2008-06-20 17:10:27 »
А можна приклад коду з використанням sprintf для перетворення строки в раціональне число?
Пардон, помилився напрямком.

Btw, atof?

Відсутній DalekiyObriy

  • Літератор
  • ******
  • дописів: 1929
  • Карма: +5/-0
Re: Кляті бібліотеки! не можу більше
« Відповідей #18 : 2008-06-20 17:19:47 »
#include <stdio.h>

...
$ ./test
1.200000
1072902963.000000
1072693248.000000

1) компілювати треба з -Wall, а краще з -pedantic
2) включати треба всі файли заголовків:

#include <stdlib.h>

тоді все гаразд:
1.200000
1.200000
1.000000

P.S. мушу зазначити, що С без -Wall та -pedantic взагалі СТРАШНА МОВА!! :))
« Змінено: 2008-06-20 17:20:50 від DalekiyObriy »
Fedora 35 (x86-64)

Відсутній Сергій Лисовенко

  • Літератор
  • ******
  • дописів: 1489
  • Карма: +0/-0
Re: Кляті бібліотеки! не можу більше
« Відповідей #19 : 2008-06-20 20:57:07 »
.2 - it's a float with value -1,71799e+09
дійсно отткровення
Якщо Лінукс написали студенти - нехай вони під ним і навчаються.

Відсутній Володимир Лісівка

  • Адміністратор ЩОДО
  • Видавець
  • *****
  • дописів: 3820
  • Карма: +11/-0
  • Програміст
Re: Кляті бібліотеки! не можу більше
« Відповідей #20 : 2008-06-21 16:59:16 »
Дякую за підказку з -Wall -pedantic (мав би й сам здогадатися  :-[ ). Виправлений варіант:
#include <stdio.h>

#define __USE_GNU 1
#include <stdlib.h>
#include <locale.h>

char *def = "12.3456";

int
main (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-strtod
String: 12.3456
12.3456 - it's a float with value 12,345600
[Fedora Linux]

Відсутній Сергій Лисовенко

  • Літератор
  • ******
  • дописів: 1489
  • Карма: +0/-0
Re: Кляті бібліотеки! не можу більше
« Відповідей #21 : 2008-06-22 18:26:11 »
Так і бути розкрию повністю
#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;
}
Воно працює. Принаймні в мене :)
Тут зашито 2 варіанти парсера - один з них XML


P.S.
щоб не дивувались чого я код не розкриваю: я його путньо писати не вмію  ;D
(камінчик в бік майкрософта)
« Змінено: 2008-06-22 18:30:28 від serg_ik »
Якщо Лінукс написали студенти - нехай вони під ним і навчаються.

Відсутній Володимир Лісівка

  • Адміністратор ЩОДО
  • Видавець
  • *****
  • дописів: 3820
  • Карма: +11/-0
  • Програміст
Re: Кляті бібліотеки! не можу більше
« Відповідей #22 : 2008-06-23 15:32:20 »
Ну так поміняй всі strtod на strtod_l(..., ..., c_locale), і замість setlocale(LC_NUMERIC,"C"); постав c_locale = newlocale(LC_ALL_MASK, "C", NULL);

[Fedora Linux]

Відсутній Володимир Лісівка

  • Адміністратор ЩОДО
  • Видавець
  • *****
  • дописів: 3820
  • Карма: +11/-0
  • Програміст
Re: Кляті бібліотеки! не можу більше
« Відповідей #23 : 2008-06-23 15:43:17 »
І не забудь перед першим #include написати
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif

 або компілюй з -D_GNU_SOURCE . Мій варіант з #define __USE_GNU - не зовсім коректний, так як це внутрішня макрозмінна glibc.
[Fedora Linux]

Відсутній Сергій Лисовенко

  • Літератор
  • ******
  • дописів: 1489
  • Карма: +0/-0
Re: Кляті бібліотеки! не можу більше
« Відповідей #24 : 2008-06-23 19:00:50 »
А як тоді що до фсіляких fprintf , fscanf?
Якщо Лінукс написали студенти - нехай вони під ним і навчаються.

Відсутній Володимир Лісівка

  • Адміністратор ЩОДО
  • Видавець
  • *****
  • дописів: 3820
  • Карма: +11/-0
  • Програміст
Re: Кляті бібліотеки! не можу більше
« Відповідей #25 : 2008-06-24 14:51:00 »
Наскільки я бачу, стандартних методів нема. Можна використовувати g_ascii_formatd з glib. Треба напевно накопати Дрепера, щоб додали _l версії для функцій *printf/*scanf, як це зроблено в BSD.
[Fedora Linux]

Відсутній Сергій Лисовенко

  • Літератор
  • ******
  • дописів: 1489
  • Карма: +0/-0
Повернути чудодійність sizeof
« Відповідей #26 : 2008-07-02 16:31:28 »
Та сам розробка, але інша тема: під час розвитку проекту (якщо так можна назвати моє кодіння, в результаті якого виникають текстові файли для галереї) в деяких структурах позмінював типи членів (були пойнтери на одні структури - стали на інші). На одній машині наче нормально працювала, а на іншій - гуп... аж скалки скла полетіли ;)
Беру бубна, танцюю... Нічого - гупається і гупається, навіть gdb дає надто прозорі натяки (зазвичай, він при гупі вказує стрічку, а тут і цього не захотів, не дивлячись, що програма зібрана з відлагоджувальним кодом). Почаклував вставлянням відлагоджувальних стрічок типу fprintf(stderr,...); аж раптом надибав, що при виділенні пам'яті зазначена sizeof старої структури...
От мене і цікавить як проти таких граблів боротись. Чи можна якось примусити sizeof говорити розмір типу, пойнтером на який є елемент структури, явно цей тип не задаючи?
Якщо Лінукс написали студенти - нехай вони під ним і навчаються.

Михайло Даниленко

  • Гість
Re: Кляті бібліотеки! не можу більше
« Відповідей #27 : 2008-07-02 16:53:35 »
ви маєте на увазі
struct aa {
        struct bb * c;
} a;
sizeof(*(a.c))

? тоді працює.
а якщо
struct aa {
        void *c;
} a;
a.c = &b;
sizeof (*(a.c))

тоді не працює.

Відсутній raven

  • Новачок
  • *
  • дописів: 0
  • Карма: +0/-0
  • linux kettle
Re: Повернути чудодійність sizeof
« Відповідей #28 : 2008-07-02 16:57:14 »
(...) ... (...). ;) (...) fprintf(stderr,...);
Сергій, та забий ти на цей Сі, в тебе явна тяга до ліспа=)

Чи можна якось примусити sizeof говорити розмір типу, пойнтером на який є елемент структури, явно цей тип не задаючи?
Точніше. В мене асоціації з вінегретом із typedef-ів і #define-ів.