[C] Převod čísel

Diskuze a poradna o programátorech a programování různých obvodů

Moderátor: Moderátoři

Odpovědět
Zpráva
Autor
Uživatelský avatar
Velous
Příspěvky: 99
Registrován: 12 bře 2010, 01:00

[C] Převod čísel

#1 Příspěvek od Velous »

Zdravím, dělám program pro převod čísel mezi soustavami. Mám tam použít funkci strtol. Nějak jsem se zasekl a nevím jak dál. Díky za pomoc.

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
Naposledy upravil(a) Velous dne 05 pro 2012, 19:28, celkem upraveno 1 x.

Uživatelský avatar
mtajovsky
Příspěvky: 3694
Registrován: 19 zář 2007, 02:00
Bydliště: Praha

#2 Příspěvek od mtajovsky »

Máte nějaký zmatek v proměnných.
- x musí být long int
- c je int, ale první parametr strtol() musí být typu const char *
- c není inicializované
- b je dle promptu převáděné číslo, ale používáte to v převodu do cílové soustavy jako její základ
- jako převáděné číslo máte v strtol() c, které není načteno
- Prevod se nikde nepoužívá

p32
Příspěvky: 15069
Registrován: 13 led 2007, 01:00
Bydliště: Olomouc

#3 Příspěvek od p32 »

Načteš první hodnotu a pokud je mimo rozsah tak pokračuješ dál ? U dalšího to samé, to je fakt na palici. Potom něco převedeš a nemáš tam ani výstup toho převodu.
Začni logicky používat podmínky a zruš psaní dlouhých keců na obrazovku, když stačí napsat jen "špatně" a opakovat zápis nebo při dobrém vstupu až potom pokračovat v dalším zápisu. Jako první bys měl dát vědět, kterou klávesou se dá vyskočit z programu.

Uživatelský avatar
mtajovsky
Příspěvky: 3694
Registrován: 19 zář 2007, 02:00
Bydliště: Praha

#4 Příspěvek od mtajovsky »

Tak třeba nějak takto:

Kód: Vybrat vše

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char **argv)
{
int baseFrom, baseTo;
long tmp; 
char from[256], to[256];
char* stop;

   printf("Program pro prevod cisel mezi soustavami\n\
-------------------------------------------\n\
ukonceni na CTRL-C\n\n");

   while(1)
   {
      printf("Zadejte soustavu, ze ktere chcete prevest cislo: ");
      scanf("%d", &baseFrom);
      if(baseFrom >= 2 && baseFrom <= 20)
         break;
      printf("Ciselna soustava musi byt v rozsahu 2-20.\n");
   }

   while(1)
   {
      printf("Zadejte soustavu, do ktere chcete prevest cislo: ");
      scanf("%d", &baseTo);
      if(baseTo >= 2 && baseTo <= 20)
         break;
      printf("Ciselna soustava musi byt v rozsahu 2-20.\n");
   }

   while(1)
   {
      printf("Zadejte cislo, ktere chcete prevest: ");
      scanf("%s", from);
      tmp = strtol(from, &stop, baseFrom);
      if(stop == from + strlen(from))
         break;
      printf("Cislo neodpovida zadane soustave.\n");
   }

   ltoa(tmp, to, baseTo);

   printf("Cislo %s v soustave %u je %s v soustave %u.\n", from, baseFrom, to, baseTo);

   return 0;
}
Kontrola čísla versus zadaná soustava bude fungovat jen v adresním modelu flat, ale to je dnes už snad všechno. Zkontrolujte si to.

Uživatelský avatar
Velous
Příspěvky: 99
Registrován: 12 bře 2010, 01:00

#5 Příspěvek od Velous »

Díky. Jen jsem teď zjistil, že by to mělo být udělané pomocí operace modulo. :-/

Uživatelský avatar
mtajovsky
Příspěvky: 3694
Registrován: 19 zář 2007, 02:00
Bydliště: Praha

#6 Příspěvek od mtajovsky »

A co, ten první převod na long, nebo zpětný převod do cílové soustavy?

Uživatelský avatar
Velous
Příspěvky: 99
Registrován: 12 bře 2010, 01:00

#7 Příspěvek od Velous »

Ano, funkce strtol tam má bý také použita.

Uživatelský avatar
mtajovsky
Příspěvky: 3694
Registrován: 19 zář 2007, 02:00
Bydliště: Praha

#8 Příspěvek od mtajovsky »

Kód: Vybrat vše

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char **argv)
{
int baseFrom, baseTo, i=0;
long numero;
char from[256], to[256]="";
char* stop;

   printf("Program pro prevod cisel mezi soustavami\n\
-------------------------------------------\n\
ukonceni na CTRL-C\n\n");

   while(1)
   {
      printf("Zadejte soustavu, ze ktere chcete prevest cislo: ");
      scanf("%d", &baseFrom);
      if(baseFrom >= 2 && baseFrom <= 20)
         break;
      printf("Ciselna soustava musi byt v rozsahu 2-20.\n");
   }

   while(1)
   {
      printf("Zadejte soustavu, do ktere chcete prevest cislo: ");
      scanf("%d", &baseTo);
      if(baseTo >= 2 && baseTo <= 20)
         break;
      printf("Ciselna soustava musi byt v rozsahu 2-20.\n");
   }

   while(1)
   {
      printf("Zadejte cislo, ktere chcete prevest: ");
      scanf("%s", from);
      numero = strtol(from, &stop, baseFrom);
      if(stop == from + strlen(from))
         break;
      printf("Cislo neodpovida zadane soustave.\n");
   }

   do
   {
      int cifra = numero % baseTo;
      to[i++] = (cifra<=9)?'0'+cifra:'a'+cifra-10;
      numero /= baseTo;
   }
   while(numero);
   strrev(to);

   printf("Cislo %s v soustave %u je %s v soustave %u.\n", from, baseFrom, to, baseTo);

   return 0;
}
Výsledek na obrázku níže.
Přílohy
prevod.JPG
(45.5 KiB) Staženo 42 x

Uživatelský avatar
piitr
Příspěvky: 1003
Registrován: 19 říj 2007, 02:00
Kontaktovat uživatele:

#9 Příspěvek od piitr »

Možná bych před to "strrev(to)" dal ještě "to=0;".
Ony sice, myslím, jsou ty automatické proměnné nulované, ale já na to nerad spoléhám.

Uživatelský avatar
rnbw
Příspěvky: 32312
Registrován: 21 bře 2006, 01:00
Bydliště: Bratislava

#10 Příspěvek od rnbw »

Premena "to" je inicializovana na prazdny retazec, je to vporiadku.

Uživatelský avatar
piitr
Příspěvky: 1003
Registrován: 19 říj 2007, 02:00
Kontaktovat uživatele:

#11 Příspěvek od piitr »

rnbw píše:Premena "to" je inicializovana na prazdny retazec, je to vporiadku.
To ne. To by nestačilo. Pro prázdný řetězec stačí, aby byla nula na prvním bajtu, ale tady je třeba mít vynulované celé pole. Tu první nulu přece přepíšu hned prvním průchodem cyklu. Ony ty nuly budou všude, takže je to v pořádku, ale teď z hlavy nevím, jak moc se na to dá spoléhat, a už jen pro přehlednost na to spoléhám nerad.

Uživatelský avatar
rnbw
Příspěvky: 32312
Registrován: 21 bře 2006, 01:00
Bydliště: Bratislava

#12 Příspěvek od rnbw »

Aha, uz vidim, ze do "to" sa zapisuje priamo po znakoch.

Uživatelský avatar
Velous
Příspěvky: 99
Registrován: 12 bře 2010, 01:00

#13 Příspěvek od Velous »

Díky moc všem! :wink:

Uživatelský avatar
mtajovsky
Příspěvky: 3694
Registrován: 19 zář 2007, 02:00
Bydliště: Praha

#14 Příspěvek od mtajovsky »

Jj, nakonec řetězce by se měla zapsat nula. V debug módu to nezlobilo, protože se před spuštěním nejprve vynuluje paměť zásobníku. To jsou nejhorší chyby, protože při prvním průchodu to nezlobí a při dalších, kdy už je zásobník popsán, to začne zlobit a z aplikace lezou špatná data. Jednou jsem takovou chybu hledal celý den. Omluvou budiž, že ne ve vlastním kódu :)

Odpovědět

Zpět na „Programování PIC, ATMEL, EEPROM a dalších obvodů“