Stránka 1 z 1

[C] Převod čísel

Napsal: 30 lis 2012, 10:22
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)
{

Napsal: 30 lis 2012, 11:36
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á

Napsal: 30 lis 2012, 13:56
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.

Napsal: 01 pro 2012, 14:57
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.

Napsal: 02 pro 2012, 13:09
od Velous
Díky. Jen jsem teď zjistil, že by to mělo být udělané pomocí operace modulo. :-/

Napsal: 02 pro 2012, 13:42
od mtajovsky
A co, ten první převod na long, nebo zpětný převod do cílové soustavy?

Napsal: 02 pro 2012, 13:58
od Velous
Ano, funkce strtol tam má bý také použita.

Napsal: 02 pro 2012, 19:10
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.

Napsal: 03 pro 2012, 08:43
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.

Napsal: 03 pro 2012, 08:57
od rnbw
Premena "to" je inicializovana na prazdny retazec, je to vporiadku.

Napsal: 03 pro 2012, 13:05
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.

Napsal: 03 pro 2012, 13:56
od rnbw
Aha, uz vidim, ze do "to" sa zapisuje priamo po znakoch.

Napsal: 03 pro 2012, 18:05
od Velous
Díky moc všem! :wink:

Napsal: 04 pro 2012, 17:32
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 :)