strcmp no terminal vs Dev-c++ [RESOLVIDO]

1. strcmp no terminal vs Dev-c++ [RESOLVIDO]

Golbery Santos
golbery

(usa Ubuntu)

Enviado em 05/06/2016 - 21:50h

Ola!!
Alguém sabe me dizer por quê nao compila o código abaixo no terminal? Compilei no Dev-C++ e funcionou normalmente!!

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
/*
A ideia é ler o sexo de várias pessoas e imprimir quantas pessoas são do sexo masculino e são do
sexo feminino. ( considerar “M” ou “m” e também “F” ou “f” ):
*/
int main(){
char sexo[2];
int conteM=0, conteF=0;
do
{
scanf("%s",&sexo);
if (!stricmp(sexo,"m")) conteM++;
else if (!stricmp(sexo,"f")) conteF++;
}while(stricmp(sexo,"s"));

printf("\nTOTAL HOMENS: %d, TOTAL MULHERES: %d\n",conteM, conteF);
system("PAUSE");
}

Para compilar no terminal usei a linha de comando:
gcc le3_q02.c -lm -o compiler.bin;
depois:
./compiler.bin


  


2. MELHOR RESPOSTA

Paulo
paulo1205

(usa Ubuntu)

Enviado em 06/06/2016 - 05:02h

No título você fala em strcmp(), mas no programa você usa stricmp(). Esse i no meio do nome da função faz toda a diferença: strcmp() faz parte da biblioteca padronizada do C, ao passo que stricmp() é uma função não-padronizada, provida como extensão somente por alguns compiladores, sobretudo no ambiente Windows.

No mundo POSIX (UNIX em geral, além de Linux e MacOS/X), a função equivalente a essa que você usou se chama strcasecmp(). Infelizmente, ela padece do problema reverso: a maioria dos compiladores para Windows não a implementa com esse nome.

Entretanto, o melhor para o seu programa é não usar nenhuma delas. O que você quer de informação é só um caráter -- então que tal ler só um caráter? Eis como você pode fazer:

unsigned char sexo;  /* <-- Tem de ser unsigned por causa de toupper() (ver abaixo). */
int rc;
while(1){
printf("Digite 'M' para masculino, 'F' para feminino, ou 'S' para sair: ");
rc=scanf(" %c", &sexo); /* <-- Note o espaço após as aspas e antes do %c. */
if(rc==EOF || rc==0){
fprintf(stderr, "Erro de leitura ou final inesperado da entrada.\n");
break;
}
sexo=toupper(sexo); /* <-- toupper() é declarada em <ctype.h>. */
if(sexo=='M')
conteM++;
else if(sexo=='F')
conteF++;
else if(sexo=='S')
break;
else
fprintf(stderr, "Você digitou um caráter inválido.\n");
}


-----

EM TEMPO: No seu programa original, você cometeu outro erro: em vez de dizer “scanf("%s", &sexo)”, sendo sexo, naquele caso, um array de caracteres, você deveria ter dito simplesmente “scanf("%s", sexo)”.

Para entender o motivo, considere os seguintes aspectos:

1) O especificador de formato "%s" de scanf() indica que o argumento correspondente é do tipo “ponteiro para char”.

2) O padrão do C, ao tratar de expressões, e mais particularmente dos tipos de dados usados em tais expressões, diz que quando o nome de um array aparece em qualquer expressão que não envolva a aplicação dos operadores & (obtenção de endereço) ou sizeof (cálculo da quantidade de bytes ocupados) diretamente sobre o array então o tipo do array deve ser interpretado como se fosse um ponteiro para o tipo do seu elemento (por exemplo: se eu tiver um array de caracteres, ele será entendido como um ponteiro para caracteres; se eu tiver um array de inteiros, ele será entendido como um ponteiro para inteiros etc.).

    2.1) Note que eu disse “caracteres” e “inteiros”, no plural, e não “caráter” e “inteiro”. Em C, um ponteiro pode ser usado para apontar para um único objeto ou para uma sucessão de objetos do mesmo tipo. Cabe ao programador saber se está se referindo a um único objeto ou a uma coleção.

3) Se a expressão envolver os operadores & ou sizeof aplicados diretamente sobre o array, então o array inteiro é entendido como um único dado, em vez de um agregado de dados do mesmo tipo.

4) No caso do operador & aplicado a um array com N elementos do tipo X, ele devolverá um dado do tipo “ponteiro para (uma possível sucessão de) arrays com N elementos do tipo X” (note como isso é diferente de “ponteiro para (uma possível sucessão de) elementos do tipo X”).


Erros como esse são relativamente comuns, especialmente entre iniciantes (mas não só!). Até por ser algo que ocorre por envolver apenas um caráter no código fonte (o “&”), esse erro pode acontecer até por acidente. Mas algo que atrapalha o diagnóstico de problemas desse tipo é que, em muitos casos, o endereço do array como um todo (e.g. &array) e o endereço do seu primeiro elemento (e.g. apenas array) serem numericamente equivalentes, mesmo que os tipos de cada expressão sejam diferentes e incompatíveis entre si. Se o compilador não for instruído a verificar ou a obrigar a correspondência entre tipos, ou se ele não puder fazer isso (por exemplo, em funções que usem listas de parâmetros variáveis, como é o caso de printf() e scanf()), erros desse tipo podem passar batidos durante a compilação e seguir sem identificação por um longo tempo. O programa está matematicamente errado, mas uma coincidência numérica permite que ele não manifeste esse erro... até o dia em que você estiver num computador em que essa coincidência não vale, ou quando você fizer uma ligeira alteração na forma do programa, e tal alteração inocente for suficiente para revelar a diferença de sentido.

Sempre que possível, instrua seu compilador a lhe dar o máximo possível de mensagens de diagnóstico, e até a tratar mensagens de alerta como se fossem erros (porque geralmente são mesmo, ainda que acidentais!). Alguns compiladores, quando instruídos a trabalhar assim, conseguem até mesmo diagnosticar erros de correspondência de tipos em funções com listas argumentos variáveis e que são definidas no padrão do C (particularmente printf() e scanf() e suas correlatas). No caso do GCC (gcc e g++), eu sempre recomendo usar as seguintes opções de compilação: -Wall -Werror -O2 -pedantic.

3. Re: strcmp no terminal vs Dev-c++ [RESOLVIDO]

Perfil removido
removido

(usa Nenhuma)

Enviado em 05/06/2016 - 21:56h

char sexo[] poderia ser 1.
daí scanf ("%c",&sexo)
e para comparar um simples ==

mas pode ser falha por causa de se usar C++ ao invés de C como foi dito aqui em outro tópico.
esperarei alguém mais experiente se pronunciar.

----------------------------------------------------------------------------------------------------------------
Nem direita, nem esquerda. Quando se trata de corrupção o Brasil é ambidestro.
(anônimo)

Encryption works. Properly implemented strong crypto systems are one of the few things that you can rely on. Unfortunately, endpoint security is so terrifically weak that NSA can frequently find ways around it. — Edward Snowden[/quote]


4. Obrigado, paulo1205, listeiro_037!!!

Golbery Santos
golbery

(usa Ubuntu)

Enviado em 06/06/2016 - 13:44h

Agradeço a dica listeiro_037!!

Ótima explicação Paulo!
Valeu não apenas pela resposta como também, pelas sugestões de como deveria ficar o código!!!

Valeu!!


5. Re: strcmp no terminal vs Dev-c++ [RESOLVIDO]

Perfil removido
removido

(usa Nenhuma)

Enviado em 06/06/2016 - 17:28h

uma falha que cometi.
não seria char sexo[1]
mas apenas char sexo sem colchetes
daí funciona com ==

----------------------------------------------------------------------------------------------------------------
Nem direita, nem esquerda. Quando se trata de corrupção o Brasil é ambidestro.
(anônimo)

Encryption works. Properly implemented strong crypto systems are one of the few things that you can rely on. Unfortunately, endpoint security is so terrifically weak that NSA can frequently find ways around it. — Edward Snowden[/quote]






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts