Problema ao inserir cadeia de caracteres no gets() [RESOLVIDO]

1. Problema ao inserir cadeia de caracteres no gets() [RESOLVIDO]

Alex G. Martins
agmartins.adm

(usa elementary OS)

Enviado em 05/04/2013 - 00:41h

Pessoas, o que há de errado neste código?
Quando digito uma string (para inserir no nome), não é inserido nada.
Acredito que seja alguma coisa na função gets(), pois quando digito um valor numérico no scanf() funciona certo...
Ps.: O código roda normal. Estou usando o Code:Blocks


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

typedef struct num {
char nome[30];
int a;
};

int main (void){

num *numero;
int qtd, i;

printf("\nDigite a quantidade de elementos: ");
scanf("%d%*c", &qtd);

numero = (num *) malloc (qtd * sizeof(num));

for (i = 0; i < qtd; i++){
printf("\nDigite o nome para [%d]: ", i);
gets((&numero[i])->nome);
printf("\nDigite o valor [%d]: ", i);
scanf("%d%*c", &numero[i].a);
}

for (i = 0; i < qtd; i++){
printf("\nNome: [%d]: %c", i, numero[i].nome);
printf("\nValor [%d]: %d", i, numero[i].a);
}

return 0;
}



  


2. MELHOR RESPOSTA

Paulo
paulo1205

(usa Ubuntu)

Enviado em 05/04/2013 - 01:38h

Acostume-se a não usar gets(). Essa função foi removida na última revisão do padrão do C (2011), e já tinha sido marcada para remoção na versão anterior (1999). E a razão para sua remoção é que ela não oferece garantias de que a sequência de caracteres digitada antes do "Enter" vai caber na string destinada a armazená-la. O recomendável é usat fgets() ou scanf() com limitação máxima de tamanho.

Fora isso, o programa tem outros problemas, a saber:

1) Você não atribuiu um nome de tipo na definição com typedef. Não sei como compilou (você está usando C++)? Em C, provavelmente você teria de fazer a seguinte alteração.

typedef struct num {
char nome[30];
int a;
} num;


2) Não chega a ser erro, mas eu acho que dizer "(&numero[i])->nome", quando se poderia usar simplesmente "numero[i].nome", um desperdício.

3) Na hora de imprimir o nome, você usou "%c" onde deveria ter usado "%s".

4) Você assume que todas as operações de alocação de memória e de entrada de dados serão bem sucedidas. Eis uma assunção perigosa. O recomendável é sempre testar para ver se o valor devolvido por malloc() é não-nulo antes de o utilizar, e também testar o valor devolvido por scanf(), especialmente quando se está tentando converter valores numéricos (já que um usuário criativo poderia digitar um caráter não-numérico que faria a conversão falhar).


Alguns dos problemas acima poderiam ser diagnosticados pelo seu compilador se você ligasse as opções de alerta. Se você estiver usando um compilador da família do GCC, eu recomendo usar as seguintes opções de compilação: "-O2 -Wall -Werror -pedantic".

3. Re: Problema ao inserir cadeia de caracteres no gets() [RESOLVIDO]

Alex G. Martins
agmartins.adm

(usa elementary OS)

Enviado em 05/04/2013 - 02:09h



1) Você não atribuiu um nome de tipo na definição com typedef. Não sei como compilou (você está usando C++)? Em C, provavelmente você teria de fazer a seguinte alteração.

typedef struct num {
char nome[30];
int a;
} num;


2) Não chega a ser erro, mas eu acho que dizer "(&numero[i])->nome", quando se poderia usar simplesmente "numero[i].nome", um desperdício.

3) Na hora de imprimir o nome, você usou "%c" onde deveria ter usado "%s".

4) Você assume que todas as operações de alocação de memória e de entrada de dados serão bem sucedidas. Eis uma assunção perigosa. O recomendável é sempre testar para ver se o valor devolvido por malloc() é não-nulo antes de o utilizar, e também testar o valor devolvido por scanf(), especialmente quando se está tentando converter valores numéricos (já que um usuário criativo poderia digitar um caráter não-numérico que faria a conversão falhar).


Olá Paulo!

Amigo, você resolveu meu problema. Era apenas o %s... :P
Na verdade, estou ciente destes erros. É que este não é um programa realmente, é apenas para testar o funcionamento de structs com ponteiros.

1) Não estou usando um nome de tipo por que o professor não quer que use (já que ele se torna uma variável global, e o professor disse que não quer que trabalhemos com variáveis globais neste caso).

2) Neste momento estava usando o &numero apenas como teste, normalmente eu uso o numero.nome mesmo...
Porém, mais uma vez o professor vai querer que usemos o formato -> de acesso dos campos na struct.

3) Aqui estava meu erro! :P

4) Na verdade, como eu disse, era só pra testar os ponteiros com estruturas. Mas eu faço as verificações normalmente.

Muito obrigado!


4. Re: Problema ao inserir cadeia de caracteres no gets() [RESOLVIDO]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 05/04/2013 - 03:08h

agmartins.adm escreveu:

Olá Paulo!

Amigo, você resolveu meu problema. Era apenas o %s... :P
Na verdade, estou ciente destes erros. É que este não é um programa realmente, é apenas para testar o funcionamento de structs com ponteiros.

1) Não estou usando um nome de tipo por que o professor não quer que use (já que ele se torna uma variável global, e o professor disse que não quer que trabalhemos com variáveis globais neste caso).


Isso está errado. Nome de tipo é uma coisa, e variável global é outra completamente diferente. A declaração
typedef struct num {
char nome[30];
int a;
} num;

não cria uma só variável, mas especifica, isto sim, um tipo "num", equivalente a "struct num", que ficará visível no espaço de nomes global. Não é justamente para isso que se declara um tipo?

Se ele não quiser que você use typedef, estão você teria de mudar a declaração de numero, dentro da função main(), passando a declará-la com o tipo "struct num".

2) Neste momento estava usando o &numero apenas como teste, normalmente eu uso o numero.nome mesmo...
Porém, mais uma vez o professor vai querer que usemos o formato -> de acesso dos campos na struct.


Mesmo que seja desse modo artificial? Acho que não.

As semelhanças entre ponteiros e arrays que existem em C e C++ devem ser usadas de modo proveitoso, não de modo contraproducente. Com qualquer array, você pode sempre escrever "*(array+i)" em lugar de "array[i]", mas seria uma tolice fazê-lo porque seria escrever mais caracteres, usando três operações explícitas no lugar de apenas uma. O caso da notação que você usou é análogo, em que se tem mais trabalho sem ganho algum.

Haverá espaço no seu programa para usar o operador "->" à vontade se você percorrer os membros do array alocado usando ponteiros, em lugar de usar explicitamente índices em sequência. Isso é comum e muitas vezes mais eficiente, mas vai depender de o que você tiver de fazer no programa.

Eu sei que existem professores mal-preparados, que cobram coisas sem sentido porque é a forma que encontram de tentar mostrar autoridade acadêmica por lhes faltar autoridade intelectual. Se for o seu caso, não vou ser eu a lhe dizer para sacrificar sua nota. Mas habitue-se a usar boas práticas quando não estiver sob o controle do eventual professor porcalhão.






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts