Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

NASG

[Resolvido] strtol com letras para "digitos"

Mensagens Recomendadas

NASG

Bom dia a todos. Estou a implementar um programa que recebe na linha de comandos dois valores e deve dividir um pelo outro. Para isso tenho de usar a instrução STRTOL. O programa está a funcionar correctamente com valores numericos, mas quando coloco caracteres como a, ou b, ou c, o programa retorna sempre a mensagem não pode dividir por 0. Não é suposto a instrução strtol pegar no caracter e o traduzir para um numero inteiro longo e fazer a divisão na mesma. Alguem pode ajudar ?

Desde já obrigado

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

void minha_divisao(long int a, long int n,long int *quoc, long int *resto)
{

 *quoc =a/n;
 *resto=a%n;   

}

int main (int argc, char *argv[ ]) /* Estes parametros são usados quando queremos que o nosso programa aceite parametros através da linda de comandos */
{

    long int a,n;
    long int quoc, resto;

    if(argc<3||argc>3)
    {
    printf("Argumentos invalidos !!! Tem de digitar apenas dois valores.\n ");
   return 0;

    }

a=strtol(argv[1],NULL,0);                   
n=strtol(argv[2],NULL,0);

    if(n==0)
    {
               printf("Nao pode fazer a divisao por 0. Digite novo valor para Divisor :\n ");
       printf("Deve digitar na forma ./my_divisao num1, num2 e num2 nao pode ser=0 !!\n ");
       return 0;

    }

  minha_divisao(a,n,&quoc,&resto);


      printf("Resultado do quociente e: ""%ld\n",quoc);
   printf("Resultado do resto e: ""%ld\n",resto);

  return 0;         

}

Editado por pmg
GeSHi

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pmg

Não é suposto a instrução strtol pegar no caracter e o traduzir para um numero inteiro longo e fazer a divisão na mesma?

Nem por isso. Ve a descricao da funcao no site do POSIX, por exemplo

If the value of base is 0, the expected form of the subject sequence is that of a decimal constant, octal constant, or hexadecimal constant, any of which may be preceded by a '+' or '-' sign. A decimal constant begins with a non-zero digit, and consists of a sequence of decimal digits. An octal constant consists of the prefix '0' optionally followed by a sequence of the digits '0' to '7' only. A hexadecimal constant consists of the prefix 0x or 0X followed by a sequence of the decimal digits and letters 'a' (or 'A' ) to 'f' (or 'F' ) with values 10 to 15 respectively.

Ou seja: o input 42 é interpretado como 42; o input 042 é interpretado como 34; o input 0x42 é interpretado como 66.


What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
NASG

Obrigado pela tua resposta. eu estive a ler o que disseste e lá tem...

"...Se o valor de base é entre 2 e 36, a forma esperada da seqüência assunto é uma sequência de letras e números que representam um inteiro com o radix especificado pela base, opcionalmente precedido por um '+' ou '-' sinal. As letras de 'A' (ou 'A') a 'z' (ou 'Z'), inclusive, é atribuída os valores 10 a 35; apenas letras cujos valores atribuídos são menos do que o de base são permitidos. Se o valor de base é 16, o 0x caracteres ou 0X pode opcionalmente preceder a sequência de letras e dígitos, após o sinal, se presente..."

Isto não quer dizer que eu possa colocar letras e a instruçõa STRTOL a converte para um inteiro ?

Obrigado

Qual poderia ser a alternativa para que pudesse tambem converter letras para inteiros e os dividir ?

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pmg

Para leres letras com o strtol() tens que usar uma base diferente de 0. E usando essa base "ficas limitado" a essa base: se meteres base 16, por exemplo, é sempre base 16

strtol("42", NULL, 0);    // 42
strtol("042", NULL, 0);   // 34
strtol("0x42", NULL, 0);  // 66
strtol("42", NULL, 16);   // sempre 66
strtol("042", NULL, 16);  // sempre 66
strtol("0x42", NULL, 16); // sempre 66

strtol("42", NULL, 8);    // 34
strtol("042", NULL, 8);   // 34
strtol("0x42", NULL, 8);  // erro (x nao pode ser usado com base 8)
strtol("42", NULL, 10);   // 42
strtol("042", NULL, 10);  // 42
strtol("0x42", NULL, 10); // erro (x nao pode ser usado com base 10)

Se quiseres ler tanto com base 10 como com base 16, dependendo da existencia de letras no input, a minha sugestão é que experimentes primeiro com base 10. Se funcionar aceita o valor; se não funcionar experimenta com base 16.

/* NAO TESTADO */
char input[] = "4a";
char *err;
errno = 0;

a = strtol(input, &err, 10);
if ((errno == 0) && (*err == '\0')) {
   /* usa a */
} else {
   errno = 0;
   b = strtol(input, &err, 16);
   if ((errno == 0) && (*err == '\0')) {
       /* usa b */
   } else {
       /* input invalido */
   }
}

Editado por pmg
codigo para base 10 e 16

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

so uma nota :

printf("Deve digitar na forma ./my_divisao num1, num2 e num2 nao pode ser=0 !!\n ");

andas a colocar uma virgula como separador dos parâmetros da chamada da aplicação ?


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
NASG

Bom dia,

esta a funcionar para caracteres de letras com a escala no strtol selecionada para 36, ou seja aceita caracteres de a a z.

Cumprimentos e Obrigado pela ajuda

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.