Converter char em int

1. Converter char em int

tmp
tmp

(usa Ubuntu)

Enviado em 18/07/2019 - 12:51h

Como converto um char em int?
Tentei assim:
x = y - '0'; 

Mas nunca da valor certo!


  


2. Re: Converter char em int

Paulo
paulo1205

(usa Ubuntu)

Enviado em 18/07/2019 - 13:29h

Prezado, boa tarde.

O que você escreveu não traz informações suficientes para que possamos ajudar de modo muito efetivo. Seria melhor se você pudesse transcrever todo o bloco de código em que você declara e atribui valores a x e a y, ou então, que respondesse, no mínimo, às seguintes perguntas:

  • Qual o tipo de y?
  • Que valor(es) tal variável contém?
  • O que você esperaria encontrar como resposta, atribuída a x?


... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)


3. Re: Converter char em int

tmp
tmp

(usa Ubuntu)

Enviado em 18/07/2019 - 14:10h

paulo1205 escreveu:

Prezado, boa tarde.

O que você escreveu não traz informações suficientes para que possamos ajudar de modo muito efetivo. Seria melhor se você pudesse transcrever todo o bloco de código em que você declara e atribui valores a x e a y, ou então, que respondesse, no mínimo, às seguintes perguntas:

  • Qual o tipo de y?
  • Que valor(es) tal variável contém?
  • O que você esperaria encontrar como resposta, atribuída a x?


... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)


Tenho esse exemplo:

char a, b;
int x;
x = (int) a + b;

Vamos supor que variáveis a e b valem 10 cada
Mesmo tentando somar com Casting não funciona como esperado, pois não da valor correto, a e b precisa ser tipo char, pois estou pegando valor por parâmetros


4. Re: Converter char em int

Paulo
paulo1205

(usa Ubuntu)

Enviado em 18/07/2019 - 18:59h

Se a e b valem 10 cada, então a resposta é 20. Você está obtendo o quê?

Lembre-se que, em C, o tipo char é um tipo inteiro, só que possivelmente com menos bits do que int, o que limita mais quais números podem ser representados.


... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)


5. Re: Converter char em int

tmp
tmp

(usa Ubuntu)

Enviado em 18/07/2019 - 19:18h

paulo1205 escreveu:

Se a e b valem 10 cada, então a resposta é 20. Você está obtendo o quê?


... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)


-1063704456


6. Re: Converter char em int

Paulo
paulo1205

(usa Ubuntu)

Enviado em 18/07/2019 - 23:20h

tmp escreveu:

-1063704456


Isso geralmente acontece quando você trabalha com variáveis cujo valor não foi devidamente definido, ou quando alguma outra variável (especialmente ponteiros e arrays) é usada de modo inadequado, e acaba invadindo a área de memória da primeira variável.

Para um diagnóstico mais preciso, você teria de mostrar todo o código.


... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)


7. Re: Converter char em int

tmp
tmp

(usa Ubuntu)

Enviado em 19/07/2019 - 15:50h

paulo1205 escreveu:

tmp escreveu:

-1063704456


Isso geralmente acontece quando você trabalha com variáveis cujo valor não foi devidamente definido, ou quando alguma outra variável (especialmente ponteiros e arrays) é usada de modo inadequado, e acaba invadindo a área de memória da primeira variável.

Para um diagnóstico mais preciso, você teria de mostrar todo o código.


... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]){
FILE *r, *w;
char buffer[999999];
int it;
float ft;
if(strcmp(argv[1],"--help")==0){
printf("xcal é uma calculadora por parâmetros\n");
printf("um exemplo de cálculo seria:\n");
printf("./xcal * 2 5\n");
printf("nesse exemplo você estaria calculado 2 x 5\n");
printf("outros parâmetros seriam:\n");
printf("+ faz soma, exemplo: ./xcal + 1 1\n");
printf("- diminui um valor, exemplo de uso: ./xcal - 2 1\n");
printf("x faz conta de vezes, exemplo de uso: ./xcal x 2 5\n");
printf("/ divide, exemplo de uso: ./xcal / 5 2\n");
}
else if(strcmp(argv[1], "+")==0){
it = (int) argv[2] + argv[3];
printf("Result: %d\n", it);
}
else{
printf("Digite ./xcal --help para obter ajuda\n");
}


return 0;
}





8. Re: Converter char em int

Paulo
paulo1205

(usa Ubuntu)

Enviado em 20/07/2019 - 15:35h

tmp escreveu:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]){
FILE *r, *w;
char buffer[999999];
int it;
float ft;
if(strcmp(argv[1],"--help")==0){
printf("xcal é uma calculadora por parâmetros\n");
printf("um exemplo de cálculo seria:\n");
printf("./xcal * 2 5\n");
printf("nesse exemplo você estaria calculado 2 x 5\n");
printf("outros parâmetros seriam:\n");
printf("+ faz soma, exemplo: ./xcal + 1 1\n");
printf("- diminui um valor, exemplo de uso: ./xcal - 2 1\n");
printf("x faz conta de vezes, exemplo de uso: ./xcal x 2 5\n");
printf("/ divide, exemplo de uso: ./xcal / 5 2\n");
}
else if(strcmp(argv[1], "+")==0){
it = (int) argv[2] + argv[3];
printf("Result: %d\n", it);
}
else{
printf("Digite ./xcal --help para obter ajuda\n");
}


return 0;
}


Qual sistema operacional e qual compilador você está usando? Quando você compila o programa acima, o compilador não lhe mostra nenhuma mensagem de diagnóstico, indicando ou erro ou código perigoso?

Aqui, usando o GCC 7.4 no Linux, se eu compilar o código acima sem nenhuma opção de diagnóstico, mesmo assim o compilador mostra duas mensagens de alerta.
gcc x.c
x.c: In function ‘main’:
x.c:21:12: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
it = (int) argv[2] + argv[3];
^
x.c:21:10: warning: assignment makes integer from pointer without a cast [-Wint-conversion]
it = (int) argv[2] + argv[3];
^


Se eu ativar as opções de código que eu sempre recomendo (“-O2 -Wall -Werror -pedantic-errors”), aí a coisa fica ainda mais séria.
gcc -O2 -Werror -Wall -pedantic-errors x.c
x.c: In function ‘main’:
x.c:21:12: error: cast from pointer to integer of different size [-Werror=pointer-to-int-cast]
it = (int) argv[2] + argv[3];
^
x.c:21:10: error: assignment makes integer from pointer without a cast [-Wint-conversion]
it = (int) argv[2] + argv[3];
^
x.c:8:11: error: unused variable ‘ft’ [-Werror=unused-variable]
float ft;
^~
x.c:6:10: error: unused variable ‘buffer’ [-Werror=unused-variable]
char buffer[999999];
^~~~~~
x.c:5:15: error: unused variable ‘w’ [-Werror=unused-variable]
FILE *r, *w;
^
x.c:5:11: error: unused variable ‘r’ [-Werror=unused-variable]
FILE *r, *w;
^
cc1: all warnings being treated as errors


Algumas das mensagens se referem a variáveis que você declarou mas não usou (ft, buffer, r e w). Mesmo que o compilador seja esperto o bastante para evitar o eventual desperdício de espaço, é bom, para facilitar a manutenção do código do programa, nunca declarar coisas que não serão usadas.

Mas o seu problema mesmo está indicado nas outras duas mensagens.

Observe que o tipo de argv é “char **”†. Isso significa que argv tem o tipo “ponteiro para dado do tipo ponteiro para dado do tipo char”‡. Se argv tem esse tipo, então o tipo de “argv[n]”, sendo n um inteiro qualquer, tem o tipo “ponteiro para dado do tipo char”.

E aí vem uma pegadinha para alguns iniciantes em C (e mesmo para — ou especialmente para — quem já programou com outras linguagens de programação): o C não tem um tipo nativo para representar strings de texto. Em lugar disso, strings são consideradas como meros arrays de caracteres contíguos, e cada string é indicada pelo ponteiro para o primeiro dos caracteres que a compõem. Essa convenção de representação é seguida por várias funções da biblioteca padrão do C que trabalham com strings (todas as funções de <string.h>, e outras de outras partes, tais como printf(), scanf(), fopen() etc.), mas não no nível da linguagem de programação em si††.

Desse modo, quando você faz, no código acima, “it = (int) argv[2] + argv[3];”, eis o que você efetivamente tem:

  • A primeira parcela da soma é “(int)argv[2]”, que é entendida pelo compilador, por partes, da seguinte maneira:
      • você obtém o valor de argv[2], que é do tipo “ponteiro para dado do tipo char” (e é, portanto, um valor que representa um endereço da memória);
      • você força a conversão desse valor para um valor do tipo int (a primeira mensagem de erro que apareceu quando eu tentei compilar seu programa se deu porque, num compilador de 64 bits, como o que eu usei, ponteiros têm 64 bits de largura, mas inteiros têm apenas 32, de modo que o dado resultante da conversão necessariamente desprezou parte das informações contidas no dado original, e tal situação normalmente indica erro lógico no programa).

  • A segunda parcela da soma usa o valor de argv[3], que é um dado do tipo “ponteiro para dado do tipo char”.

  • A soma tem, portanto, uma parcela inteira (obtida por conversão) e uma parcela que é um ponteiro. Isso indica para o compilador que você tem uma operação de aritmética de ponteiros, que funciona da seguinte maneira:
      • o ponteiro é entendido como apontando para múltiplos elementos (como um vetor), e o resultado da soma corresponde ao endereço do elemento desse vetor que teria o valor inteiro como índice (em outras palavras, se p é um ponteiro para um tipo qualquer (exceto void) e n é um inteiro, então (p+n == n+p) && (p+n == &p[n]));
      • o resultado da soma é, portanto, também um dado de um tipo ponteiro: o mesmo tipo que o da parcela da soma que é um ponteiro (no seu caso, como essa parcela tinha o tipo “char *”, o ponteiro produzido pela soma também é um “char *”).

  • Finalmente, o valor da soma é atribuído à variável it. Contudo, como it não é do mesmo tipo que a soma, o compilador lhe avisa sobre a conversão de tipos implícita que terá (ou teria, no caso da compilação que é abortada, quando eu usei a opção “-Werror”) de ocorrer para que a atribuição do valor a uma variável com tipo diferente possa (ou pudesse) ser feita.

A moral da história toda é que o seu programa não produziu o valor que você queria porque você não expressou o que queria corretamente. Você provavelmente gostaria de transformar os numerais em forma de strings apontadas pelos argumentos argv[2] e argv[3] em dados numéricos, e então obter a soma dos valores desses dados numéricos.

Como o C não oferece suporte a strings em nível de linguagem de programação, você terá de recorrer a uma das funções da biblioteca que permitem fazer tal conversão, ou escrever seu próprio algoritmo para fazer tal conversão. Caso opte por usar uma das funções da biblioteca, pode usar strtol(), sscanf() com a conversão "%d" ou atoi(), entre outras. Dessas, atoi() é a mais simples, mas tem a grave desvantagem de não permitir diagnóstico de erro (por exemplo, se o usuário passar como argumento uma string que não seja um numeral válido para a conversão), ao passo que strtol() e sscanf() podem facilitar tal diagnóstico.

Se você quiser usar dados em ponto flutuante (trocando it pelo ft que você declarou mas não usou), pode usar atof(), strtod() ou a conversão "%f" de sscanf().

---------
† Aquela notação usando colchetes vazios é uma forma obsoleta, herdada da antiga linguagem B, de declarar ponteiros (B não tinha a notação usando asterisco). Ela ainda é relativamente bem aceita em C quando, na declaração de parâmetro de funções, se quer dar o sentido que que aquele ponteiro, em particular, vai apontar para um vetor de elementos, em vez de apontar para um elemento só. Assim, “char *argv[]” é um sinônimo absoluto de “char **argv”.

‡ Ou, se você considerar que esse ponteiro necessariamente indica um vetor, pode entender como “vetor de elementos do tipo ponteiro para dado do tipo char”.

†† O único suporte que a linguagem dá é transformar constantes literais na forma de texto entre aspas (e.g. "Isto é um texto" ou "Hello, World!\n") automaticamente num array de caracteres compatível com essa notação.


... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)


9. Re: Converter char em int

tmp
tmp

(usa Ubuntu)

Enviado em 22/07/2019 - 16:28h

paulo1205 escreveu:

tmp escreveu:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]){
FILE *r, *w;
char buffer[999999];
int it;
float ft;
if(strcmp(argv[1],"--help")==0){
printf("xcal é uma calculadora por parâmetros\n");
printf("um exemplo de cálculo seria:\n");
printf("./xcal * 2 5\n");
printf("nesse exemplo você estaria calculado 2 x 5\n");
printf("outros parâmetros seriam:\n");
printf("+ faz soma, exemplo: ./xcal + 1 1\n");
printf("- diminui um valor, exemplo de uso: ./xcal - 2 1\n");
printf("x faz conta de vezes, exemplo de uso: ./xcal x 2 5\n");
printf("/ divide, exemplo de uso: ./xcal / 5 2\n");
}
else if(strcmp(argv[1], "+")==0){
it = (int) argv[2] + argv[3];
printf("Result: %d\n", it);
}
else{
printf("Digite ./xcal --help para obter ajuda\n");
}


return 0;
}


Qual sistema operacional e qual compilador você está usando? Quando você compila o programa acima, o compilador não lhe mostra nenhuma mensagem de diagnóstico, indicando ou erro ou código perigoso?

Aqui, usando o GCC 7.4 no Linux, se eu compilar o código acima sem nenhuma opção de diagnóstico, mesmo assim o compilador mostra duas mensagens de alerta.
gcc x.c
x.c: In function ‘main’:
x.c:21:12: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
it = (int) argv[2] + argv[3];
^
x.c:21:10: warning: assignment makes integer from pointer without a cast [-Wint-conversion]
it = (int) argv[2] + argv[3];
^


Se eu ativar as opções de código que eu sempre recomendo (“-O2 -Wall -Werror -pedantic-errors”), aí a coisa fica ainda mais séria.
gcc -O2 -Werror -Wall -pedantic-errors x.c
x.c: In function ‘main’:
x.c:21:12: error: cast from pointer to integer of different size [-Werror=pointer-to-int-cast]
it = (int) argv[2] + argv[3];
^
x.c:21:10: error: assignment makes integer from pointer without a cast [-Wint-conversion]
it = (int) argv[2] + argv[3];
^
x.c:8:11: error: unused variable ‘ft’ [-Werror=unused-variable]
float ft;
^~
x.c:6:10: error: unused variable ‘buffer’ [-Werror=unused-variable]
char buffer[999999];
^~~~~~
x.c:5:15: error: unused variable ‘w’ [-Werror=unused-variable]
FILE *r, *w;
^
x.c:5:11: error: unused variable ‘r’ [-Werror=unused-variable]
FILE *r, *w;
^
cc1: all warnings being treated as errors


Algumas das mensagens se referem a variáveis que você declarou mas não usou (ft, buffer, r e w). Mesmo que o compilador seja esperto o bastante para evitar o eventual desperdício de espaço, é bom, para facilitar a manutenção do código do programa, nunca declarar coisas que não serão usadas.

Mas o seu problema mesmo está indicado nas outras duas mensagens.

Observe que o tipo de argv é “char **”†. Isso significa que argv tem o tipo “ponteiro para dado do tipo ponteiro para dado do tipo char”‡. Se argv tem esse tipo, então o tipo de “argv[n]”, sendo n um inteiro qualquer, tem o tipo “ponteiro para dado do tipo char”.

E aí vem uma pegadinha para alguns iniciantes em C (e mesmo para — ou especialmente para — quem já programou com outras linguagens de programação): o C não tem um tipo nativo para representar strings de texto. Em lugar disso, strings são consideradas como meros arrays de caracteres contíguos, e cada string é indicada pelo ponteiro para o primeiro dos caracteres que a compõem. Essa convenção de representação é seguida por várias funções da biblioteca padrão do C que trabalham com strings (todas as funções de <string.h>, e outras de outras partes, tais como printf(), scanf(), fopen() etc.), mas não no nível da linguagem de programação em si††.

Desse modo, quando você faz, no código acima, “it = (int) argv[2] + argv[3];”, eis o que você efetivamente tem:

  • A primeira parcela da soma é “(int)argv[2]”, que é entendida pelo compilador, por partes, da seguinte maneira:
      • você obtém o valor de argv[2], que é do tipo “ponteiro para dado do tipo char” (e é, portanto, um valor que representa um endereço da memória);
      • você força a conversão desse valor para um valor do tipo int (a primeira mensagem de erro que apareceu quando eu tentei compilar seu programa se deu porque, num compilador de 64 bits, como o que eu usei, ponteiros têm 64 bits de largura, mas inteiros têm apenas 32, de modo que o dado resultante da conversão necessariamente desprezou parte das informações contidas no dado original, e tal situação normalmente indica erro lógico no programa).

  • A segunda parcela da soma usa o valor de argv[3], que é um dado do tipo “ponteiro para dado do tipo char”.

  • A soma tem, portanto, uma parcela inteira (obtida por conversão) e uma parcela que é um ponteiro. Isso indica para o compilador que você tem uma operação de aritmética de ponteiros, que funciona da seguinte maneira:
      • o ponteiro é entendido como apontando para múltiplos elementos (como um vetor), e o resultado da soma corresponde ao endereço do elemento desse vetor que teria o valor inteiro como índice (em outras palavras, se p é um ponteiro para um tipo qualquer (exceto void) e n é um inteiro, então (p+n == n+p) && (p+n == &p[n]));
      • o resultado da soma é, portanto, também um dado de um tipo ponteiro: o mesmo tipo que o da parcela da soma que é um ponteiro (no seu caso, como essa parcela tinha o tipo “char *”, o ponteiro produzido pela soma também é um “char *”).

  • Finalmente, o valor da soma é atribuído à variável it. Contudo, como it não é do mesmo tipo que a soma, o compilador lhe avisa sobre a conversão de tipos implícita que terá (ou teria, no caso da compilação que é abortada, quando eu usei a opção “-Werror”) de ocorrer para que a atribuição do valor a uma variável com tipo diferente possa (ou pudesse) ser feita.

A moral da história toda é que o seu programa não produziu o valor que você queria porque você não expressou o que queria corretamente. Você provavelmente gostaria de transformar os numerais em forma de strings apontadas pelos argumentos argv[2] e argv[3] em dados numéricos, e então obter a soma dos valores desses dados numéricos.

Como o C não oferece suporte a strings em nível de linguagem de programação, você terá de recorrer a uma das funções da biblioteca que permitem fazer tal conversão, ou escrever seu próprio algoritmo para fazer tal conversão. Caso opte por usar uma das funções da biblioteca, pode usar strtol(), sscanf() com a conversão "%d" ou atoi(), entre outras. Dessas, atoi() é a mais simples, mas tem a grave desvantagem de não permitir diagnóstico de erro (por exemplo, se o usuário passar como argumento uma string que não seja um numeral válido para a conversão), ao passo que strtol() e sscanf() podem facilitar tal diagnóstico.

Se você quiser usar dados em ponto flutuante (trocando it pelo ft que você declarou mas não usou), pode usar atof(), strtod() ou a conversão "%f" de sscanf().

---------
† Aquela notação usando colchetes vazios é uma forma obsoleta, herdada da antiga linguagem B, de declarar ponteiros (B não tinha a notação usando asterisco). Ela ainda é relativamente bem aceita em C quando, na declaração de parâmetro de funções, se quer dar o sentido que que aquele ponteiro, em particular, vai apontar para um vetor de elementos, em vez de apontar para um elemento só. Assim, “char *argv[]” é um sinônimo absoluto de “char **argv”.

‡ Ou, se você considerar que esse ponteiro necessariamente indica um vetor, pode entender como “vetor de elementos do tipo ponteiro para dado do tipo char”.

†† O único suporte que a linguagem dá é transformar constantes literais na forma de texto entre aspas (e.g. "Isto é um texto" ou "Hello, World!\n") automaticamente num array de caracteres compatível com essa notação.


... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)


criei essas variaveis para usar mais a frente, estou usando gcc 8.3.0 no ubuntu 18.10
vou aplicar suas dicas e volto, obrigado pela ajuda!






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts