Ir para conteúdo
Fórum Script Brasil
  • 0

Definição de variável!


Italoo

Pergunta

Olá, estou iniciando meus estudos com a linguagem C e me deparei com um pequeno problema que está me dando uma dor de cabeça!

Basicamente preciso que o usuário digite um nome, por exemplo, José Maria. Este nome deve ser jogado para dentro de uma variável A, só que como eu fiz, apenas a letra J vai para dentro da variável.

Segue abaixo o algoritmo;

#include<stdio.h>

int cont,p1,p2;

float n1,n2,mp;

char a;

main()

{

p1=1;

p2=2;

cont=1;

while(cont<4)

{

cont=cont+1;

printf("\nEntre com o nome do aluno: ");

scanf("%s",&a);

printf("\nEntre com a nota A: ");

scanf("%f",&n1);

printf("\nEntre com a nota B: ");

scanf("%f",&n2);

mp=(n1*p1+n2*p2)/(p1+p2);

printf("\nO aluno %s tem média: %f\n",a,mp);

}

}

Quando compilo o algoritmo aparece o seguinte erro:

e3.c: In function ‘main’:

e3.c:20: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘int’

Se eu mudar o parâmetro %s para %c funciona, mas acontece o que falei alí encima, apenas a primeira letra do nome é jogada para dentro da variável.

Então decidi pesquisar um pouco e encontrei isso aqui:

#include <stdio.h>

int main()

{

char str[20];

scanf("%s",str);

printf("A string digitada foi: %s\n", str);

return 0;

}

Neste exemplo, na hora da definição da variável, basta definir um número máximo de caracteres.Só que quando defino esse número, por exemplo char A[20], o seguinte erro aparece:

e3.c: In function ‘main’:

e3.c:14: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char (*)[20]’

A partir daqui já não encontrei mais nada. Caso alguém possa me dar uma forcinha, agradecería, pois é um trabalho avaliado :/

Valeu galera, abraço!

Link para o comentário
Compartilhar em outros sites

19 respostass a esta questão

Posts Recomendados

  • 0
O código acima funciona

Onde está sua dúvida ?

João, consegui fazer o código funcionar aqui apenas retirando o & da linha scanf("%s",&a);

Mas agora minha dúvida sería como fazer para jogar um espaço para dentro da variável, por exemplo um nome como Joao Vitor.

Obrigado!

Editado por Italoo
Link para o comentário
Compartilhar em outros sites

  • 0

Italoo, a função scanf() quando usada pra ler uma string, pára a leitura ao encontrar um espaço em branco qualquer, seja um TAB, um espaço ou um enter. Se você quiser ler a palavra até ser precionado o ENTER com o scanf() você deve usar o que algumas literaturas chamam de scanset:

#include <stdio.h>

int main(void){
    char string[30];

    printf("Digite uma frase: ");
    scanf("%[^\n]", string);

    printf("String digitada: %s\n", string);
    return 0;
}

No código acima, o scanf irá ler todo e qualquer caractere da entrada pra string até que o caractere ENTER (\n) seja precionado, ao ser precionado o scanf não o processa.

Porém outras funções são aconselháveis em se tratando de leitura de strings, pesquise sobre fgets() e gets() para saber mais sobre o assunto.

Há uma ótima referencia da biblioteca padrão do C aqui nesse site: http://www.cplusplus.com/reference/clibrary/cstdio/

Espero ter ajudado. =]

EDIT: Da mesma forma com que excluimos o \n do processamento no scanf, podemos fazer com que ele leia apenas alguns caracteres, por ex.: scanf("%[aeiou]", string), para ler somente vogais e etc. Espero que tenha compreendido. T+

Editado por Arrk
Link para o comentário
Compartilhar em outros sites

  • 0

Jonathan (desculpa te chamei de João) e Arrk, muito obrigado mesmo, vocês foram demais!

Arrk, quanto ao link que me mandou, alí é C++ parece um pouco diferente, mesmo que sejam muito parecidas as linguagens, para mim que sou iniciante complica hehehehe....

Mas vou aproveitar o tópico e perguntar algumas coisas sobre comparação de string. Eu acho que consegui fazer uma comparação, mas o loop alí não está funcionando...

Segue o código abaixo:

#include<stdio.h>

#include<string.h>

int fat,num,num1,fat1,rep;

main()

{

char re [20];

do{

printf("Entre com um número: ");

printf("");

scanf("%d",&num);

printf("");

num1=num;

fat=1;

while(num!=0){

fat=fat*num;

num=num-1;

fat1=fat;

}

printf("Fatorial de %d é %d.\n",num1,fat1);

printf("Outro número (sim/não)?\n");

scanf("%s",re);

while((strcmp(re,"sim") == 1 && strcmp(re,"não") == 1))

{

printf("Digite \"sim\" ou \"não\": ");

scanf("%s",re);

}

}

while(strcmp(re,"não") == 1);

return 0;

}

Estou com problemas mais precisamente aqui, o código é compilado sem erros, mas quando eu vou digitar sim ou não, tento escrever uma palavra aleatoria, para entrar no while até eu digitar sim ou não e seguir, mas quando escrevo qualquer besteira ele sai do programa.

while((strcmp(re,"sim") == 1 && strcmp(re,"não") == 1))

{

printf("Digite \"sim\" ou \"não\": ");

scanf("%s",re);

Agradeço tes de já!

Link para o comentário
Compartilhar em outros sites

  • 0
Arrk, quanto ao link que me mandou, alí é C++ parece um pouco diferente, mesmo que sejam muito parecidas as linguagens, para mim que sou iniciante complica hehehehe....

Cara, não tire conclusões precipitadas =]

O site é realmente sobre C++, o nome dele já diz tudo. Mas ele cobre a biblioteca do C também. Ele usa alguns dos conceitos nascidos no C++ para descrever as funções do C, como por exemplo quando ele chama a struct FILE de objeto e tal, e quando em vez de falar arquivo, fala stream. O site não é exclusivamente sobre C++, se você prestar bem atenção os códigos de exemplo sobre as funções do C são escritos no próprio C mesmo. Todos os headers do C em vez de <header>.h, no C++ são incluidos de forma diferente, colocando-se um c antes e omitindo o .h , daí a forma diferente de mencionar as bibliotecas. Quando eu estudava C eu usava o site sem problemas, recomendei porque além do conteúdo nele ser excelente, li bastante os exemplos =]

Estou com problemas mais precisamente aqui, o código é compilado sem erros, mas quando eu vou digitar sim ou não, tento escrever uma palavra aleatoria, para entrar no while até eu digitar sim ou não e seguir, mas quando escrevo qualquer besteira ele sai do programa.

while((strcmp(re,"sim") == 1 && strcmp(re,"não") == 1))

{

printf("Digite \"sim\" ou \"não\": ");

scanf("%s",re);

O "erro" é quando você iguala o valor de strcmp() a 1. A strcmp() retorna um valor positivo se a segunda string for maior, negativo se a primeira for maior e zero se as duas forem iguais. Se eu bem entendi o que você quer fazer, você quer ler outro número se o usuário digitar sim e sair do do...while se ele digitar não, então seu código ficaria assim:

strcmp()

#include <stdio.h>
#include <string.h>

int fat,num,num1,fat1,rep;

main(){
    char re[20];

    do{
        printf("Entre com um número: ");

        scanf("%d", &num);

        num1 = num;
        fat = 1;

        while(num!=0){

            fat=fat*num;

            num=num-1;
            fat1=fat;

        }

        printf("Fatorial de %d é %d.\n",num1,fat1);
        printf("Outro número (sim/não)?\n");
        scanf("%s", re);
    }while(strcmp(re,"não") && strcmp(re,"NÃO"));

    return 0;
}

Tenha cuidado com o valor de retorno da strcmp(), porque alí no while final você só passava pra leitura do próximo número se a string re fosse menor que não e o certo seria continuar enquanto o usuário digitasse algo diferente de não e NÃO.

Espero que tenha ajudado. Qualquer coisa estamos aqui ;D

Link para o comentário
Compartilhar em outros sites

  • 0
Arrk, quanto ao link que me mandou, alí é C++ parece um pouco diferente, mesmo que sejam muito parecidas as linguagens, para mim que sou iniciante complica hehehehe....

Cara, não tire conclusões precipitadas =]

O site é realmente sobre C++, o nome dele já diz tudo. Mas ele cobre a biblioteca do C também. Ele usa alguns dos conceitos nascidos no C++ para descrever as funções do C, como por exemplo quando ele chama a struct FILE de objeto e tal, e quando em vez de falar arquivo, fala stream. O site não é exclusivamente sobre C++, se você prestar bem atenção os códigos de exemplo sobre as funções do C são escritos no próprio C mesmo. Todos os headers do C em vez de <header>.h, no C++ são incluidos de forma diferente, colocando-se um c antes e omitindo o .h , daí a forma diferente de mencionar as bibliotecas. Quando eu estudava C eu usava o site sem problemas, recomendei porque além do conteúdo nele ser excelente, li bastante os exemplos =]

Estou com problemas mais precisamente aqui, o código é compilado sem erros, mas quando eu vou digitar sim ou não, tento escrever uma palavra aleatoria, para entrar no while até eu digitar sim ou não e seguir, mas quando escrevo qualquer besteira ele sai do programa.

while((strcmp(re,"sim") == 1 && strcmp(re,"não") == 1))

{

printf("Digite \"sim\" ou \"não\": ");

scanf("%s",re);

O "erro" é quando você iguala o valor de strcmp() a 1. A strcmp() retorna um valor positivo se a segunda string for maior, negativo se a primeira for maior e zero se as duas forem iguais. Se eu bem entendi o que você quer fazer, você quer ler outro número se o usuário digitar sim e sair do do...while se ele digitar não, então seu código ficaria assim:

strcmp()

#include <stdio.h>
#include <string.h>

int fat,num,num1,fat1,rep;

main(){
    char re[20];

    do{
        printf("Entre com um número: ");

        scanf("%d", &num);

        num1 = num;
        fat = 1;

        while(num!=0){

            fat=fat*num;

            num=num-1;
            fat1=fat;

        }

        printf("Fatorial de %d é %d.\n",num1,fat1);
        printf("Outro número (sim/não)?\n");
        scanf("%s", re);
    }while(strcmp(re,"não") && strcmp(re,"NÃO"));

    return 0;
}

Tenha cuidado com o valor de retorno da strcmp(), porque alí no while final você só passava pra leitura do próximo número se a string re fosse menor que não e o certo seria continuar enquanto o usuário digitasse algo diferente de não e NÃO.

Espero que tenha ajudado. Qualquer coisa estamos aqui ;D

Ok Arrk, muito obrigado! Masss essa parte eu já consegui fazer, acho que você não entendeu muito bem. Na hora de escrever SIM ou não, caso eu escreva CIDADE por exemplo, quero que apareça uma mensagem dizendo, seila, "Escreva SIM ou não" e um scanf logo após. Isso que não estou conseguindo fazer, mas as suas dicas com strcmp() foram de grande ajuda! Obrigado.

Aproveitando o tópico, eu também estou impacado na verificação de um número para ver se é inteiro ou não. Eu fiz desta forma e aparentemente deu certo:

scanf("%d",&n1);

while(n1>10 || n1%2!=1 && n1%2!=0 || n1<0){

printf("Valor invalido\n");

scanf("%d",&n1);

}

Neste caso, um número entre 1 e 10, só que a minha variável n1 já esta definida como inteiro, então quando entro com um valor não inteiro como 3.4, meu programa pula uma etapa, como se tivesse entrado com 2 valores.....

Desculpa estar fazendo esse monte de perguntas, mas recebi um trabalho para fazer sem ao menos ter a matéria completa. :S

Valeu!

scanf("%d",&n1);

Link para o comentário
Compartilhar em outros sites

  • 0

Que nada cara, não precisa se desculpar, no que puder a gente ajuda =]

Se você quiser verificar um se um número é inteiro ou não uma solução seria se valer das conversões implícitas que o C faz: subtraindo do número real a sua parte inteira e verificando se sobrou alguma coisa, se tiver sobrado é porque o número tem parte fracionária, não sendo então inteiro:

#include <stdio.h>
    
 int main(void){
        float fnum, temp;
        int parte_inteira;
    
        printf("Numero em ponto flutuante: ");
        scanf("%f", &fnum);
    
        temp = fnum;
        if(fnum < 0)
            fnum = -fnum;
        parte_inteira = fnum;
        fnum = fnum - parte_inteira;
    
        if(fnum)
            printf("Voce digitou um numero não inteiro: %.3f", temp);
        else
            printf("Voce digitou um numero inteiro: %.0f", temp);
    
        return 0;
  }
Há uma função da math.h que já faz isso, a modf(). Ela recebe dois parâmetros: o número a ser quebrado, o endereço de uma variável que conterá a parte inteira do número e retorna a parte fracionária do número:
#include <stdio.h>
 #include <math.h>
    
 int main (){
      double param, fractpart, intpart;
    
      param = 3.14159265;
      fractpart = modf (param , &intpart);
      printf ("%lf = %lf + %lf n", param, intpart, fractpart);
      return 0;
 }

O exemplo acima foi tirado de: http://www.cplusplus.com/reference/clibrary/cmath/modf/

Espero ter ajudado.

Editado por Arrk
Link para o comentário
Compartilhar em outros sites

  • 0
Que nada cara, não precisa se desculpar, no que puder a gente ajuda =]

Se você quiser verificar um se um número é inteiro ou não uma solução seria se valer das conversões implícitas que o C faz: subtraindo do número real a sua parte inteira e verificando se sobrou alguma coisa, se tiver sobrado é porque o número tem parte fracionária, não sendo então inteiro:

#include <stdio.h>
    
 int main(void){
        float fnum, temp;
        int parte_inteira;
    
        printf("Numero em ponto flutuante: ");
        scanf("%f", &fnum);
    
        temp = fnum;
        if(fnum < 0)
            fnum = -fnum;
        parte_inteira = fnum;
        fnum = fnum - parte_inteira;
    
        if(fnum)
            printf("Voce digitou um numero não inteiro: %.3f", temp);
        else
            printf("Voce digitou um numero inteiro: %.0f", temp);
    
        return 0;
  }
Há uma função da math.h que já faz isso, a modf(). Ela recebe dois parâmetros: o número a ser quebrado, o endereço de uma variável que conterá a parte inteira do número e retorna a parte fracionária do número:
#include <stdio.h>
 #include <math.h>
    
 int main (){
      double param, fractpart, intpart;
    
      param = 3.14159265;
      fractpart = modf (param , &intpart);
      printf ("%lf = %lf + %lf n", param, intpart, fractpart);
      return 0;
 }
O exemplo acima foi tirado de: http://www.cplusplus.com/reference/clibrary/cmath/modf/ Espero ter ajudado.
Pôôô! Ótima função essa!!! Ajudou mesmo, finalizei essa parte :D Pesquisei sobre o parâmetro fgets neste site que me recomendou e consegui resolver aparentemente o último problema que tenho, mas não ficou exatamente como eu queria. Segue abaixo o código:
.
.
.
printf("Entre com o nome do aluno: ");
fgets(nome, 20, stdin);
scanf("%100[^\n]",nome);
.
.
.
Aí a variável ''nome'' string só que ao executar, eu escrevo o nome por exemplo João da Silva e tenho que dar dois ENTERS, ou seja, um enter é jogado para dentro da variável nome também, pois logo após quando dou um PRINTF com a variável inclusa, a frase sai fragmentada, com um ENTER no meio. Caso queira o código todo para ver o que estou falando:
#include<stdio.h>
#include<string.h>

int cont,p1,p2;

float n1,n2,mp;
char nome[20];

main()

{

p1=1;

p2=2;

cont=1;

do

{
cont=cont+1;
printf("Entre com o nome do aluno: ");
fgets(nome, 20, stdin);
scanf("%100[^\n]",nome);
printf("");

printf("Entre com a nota A: "); 
scanf("%f",&n1);

while(n1<0){
printf("ERRO: Valor inválido. Digite novamente: ");
scanf("%f",&n1);
}
printf("Entre com a nota B: ");
scanf("%f",&n2);
while(n2<0){
printf("ERRO: Valor inválido. Digite novamente: ");
scanf("%f",&n2);
}

mp=(n1*p1+n2*p2)/(p1+p2);
printf("");

printf("O aluno %s tem média: %f\n",nome,mp);
}
while(cont<4);
return 0;

}

Obrigado Arrk pela ajuda até aqui, prometo que essa é a última dúvida :)

Editado por Italoo
Link para o comentário
Compartilhar em outros sites

  • 0
Se você quiser verificar um se um número é inteiro ou não uma solução seria se valer das conversões implícitas que o C faz: subtraindo do número real a sua parte inteira e verificando se sobrou alguma coisa, se tiver sobrado é porque o número tem parte fracionária, não sendo então inteiro:

Outro modo é usar as funções ceil e floor. Quando um número é inteiro o resultado das duas funções é o mesmo. Melhor do que converter um float ou double p/ int e perder a representação.

Por que você está usando variáveis globais?

printf("Entre com o nome do aluno: ");
fgets(nome, 20, stdin);
scanf("%100[^\n]",nome);
Por que você colocou um scanf depois do fgets se você já leu o nome do aluno?
printf("Entre com a nota A: ");
scanf("%f",&n1);

while(n1<0){
printf("ERRO: Valor inválido. Digite novamente: ");
scanf("%f",&n1);
}
Estruture melhor isso.
do {
            printf("Entre com a nota A: ");
            scanf("%f",&n1);
            if (n1 < 0)
                printf("ERRO: Valor inválido. Digite novamente: ");
        } while (n1 <0);

- Você não está incrementando a variável cont. E já que o loop não tem outra condição senão o valor dessa variável, use um for.

- P/ tirar o \n da string use strchr.

Link para o comentário
Compartilhar em outros sites

  • 0
Por que você colocou um scanf depois do fgets se você já leu o nome do aluno?

Porque se eu não colocar, o código lê o nome a primeira vez, depois quando for ler a segunda vez, ele pula a etapa de leitura.

Deixando o fgets e o scanf, eu consigo jogar uma string para dentro da variável, mas depois de entrar com a string preciso apertar duas vezes ENTER, e um desses ENTERs vai pra dentro da variável junto.... não sei se existe alguma outra forma de jogar uma string com espaços e acentos para uma variável :/

- P/ tirar o \n da string use strchr.

Ok, valeu cara!

Mas como ficaria esse strchr?

Eu declaro 2 variáveis CHAR, tipo..

A=strchr(NOME,'\n');

Aí ele procura pelos ''ENTERS'' na string e já retira eles ou o que?

Abraço.

Editado por Italoo
Link para o comentário
Compartilhar em outros sites

  • 0
Outro modo é usar as funções ceil e floor. Quando um número é inteiro o resultado das duas funções é o mesmo. Melhor do que converter um float ou double p/ int e perder a representação.

Não vai necessariamente perder a representação, é só guardar o valor como fiz no exemplo.

Mas como ficaria esse strchr?

Eu declaro 2 variáveis CHAR, tipo..

A=strchr(NOME,'\n');
Aí ele procura pelos ''ENTERS'' na string e já retira eles ou o que?
A função retorna um ponteiro para o primeiro caractere '\n' na string nome caso encontre, caso contrário, retorna NULL, com isso você pode remover o '\n' fazendo:
ptr = strchr(nome, '\n');
  *ptr = *(ptr+1);

Eu fiz do jeito que tá aí, mas foi só pra você ver, quando for fazer, verifique o valor de retorno.

Abraço.

Editado por Arrk
Link para o comentário
Compartilhar em outros sites

  • 0

#include<stdio.h>
#include<string.h>

int cont,p1,p2;

float n1,n2,mp;
char nome[30];

main()

{

p1=1;

p2=2;

cont=1;

do

{
cont=cont+1;
printf("Entre com o nome do aluno: ");
fgets(nome, 20, stdin);
scanf("%100[^\n]",nome);
printf("");

printf("Entre com a nota A: "); 
scanf("%f",&n1);

while(n1<0){
printf("ERRO: Nota inválido. Digite novamente: ");
scanf("%f",&n1);
}
printf("Entre com a nota B: ");
scanf("%f",&n2);
while(n2<0){
printf("ERRO: Nota inválido. Digite novamente: ");
scanf("%f",&n2);
}

mp=(n1*p1+n2*p2)/(p1+p2);
printf("");

printf("O aluno %s tem média: %f\n",nome,mp);
}
while(cont<4);
return 0;

}

Tipo o código é esse. Testem para ver o que estou falando, pois fiz o que vocês falaram e não deu certo :/

Link para o comentário
Compartilhar em outros sites

  • 0

Desculpa, mas o quê que não deu certo? você ainda está lendo o nome duas vezes e você não usou a strchr pra remover o '\n' caso queira usar o fgets.

- Voce pode estruturar melhor o código que obrigue o usuário a digitar um valor correto, tente usar um do-while em vez de while. ( na parte que obriga que a nota digitada tem que ser válida )

- E já que o while mais externo só é reponsável por mera contagem use um for em vez dele.

- Existem notas maiores que 10? =]

Abraço.

Editado por Arrk
Link para o comentário
Compartilhar em outros sites

  • 0
Desculpa, mas o quê que não deu certo? você ainda está lendo o nome duas vezes e você não usou a strchr pra remover o '\n' caso queira usar o fgets.

- Voce pode estruturar melhor o código que obrigue o usuário a digitar um valor correto, tente usar um do-while em vez de while. ( na parte que obriga que a nota digitada tem que ser válida )

- E já que o while mais externo só é reponsável por mera contagem use um for em vez dele.

- Existem notas maiores que 10? =]

Abraço.

O problema não pede nada além disso.

É que quando o programa pede para digitar um nome, tenho que apertar 2 vezes enter, sendo que 1 enter vai pra dentro da variável e quando dou printf nessa variável da uma quebra de linha.

Link para o comentário
Compartilhar em outros sites

  • 0
É que quando o programa pede para digitar um nome, tenho que apertar 2 vezes enter, sendo que 1 enter vai pra dentro da variável e quando dou printf nessa variável da uma quebra de linha.

Pois é. Como foi mencionado antes, você lê a string duas vezes, uma com fgets e outra com scanf, escolha uma das duas maneiras. Seu programa está certo, só estou vendo estranho o fato de você ler a string duas vezes. Escolha uma das maneiras pra ler. Tente fazer com fgets e use a função mencionada pelo nuts - a strchr - pra remover o '\n'.

Abraço.

Link para o comentário
Compartilhar em outros sites

  • 0
É que quando o programa pede para digitar um nome, tenho que apertar 2 vezes enter, sendo que 1 enter vai pra dentro da variável e quando dou printf nessa variável da uma quebra de linha.

Pois é. Como foi mencionado antes, você lê a string duas vezes, uma com fgets e outra com scanf, escolha uma das duas maneiras. Seu programa está certo, só estou vendo estranho o fato de você ler a string duas vezes. Escolha uma das maneiras pra ler. Tente fazer com fgets e use a função mencionada pelo nuts - a strchr - pra remover o '\n'.

Abraço.

Sim sim, mas não funcionou aqui quando usei apenas fgets, daí me perdi todo....

Cara mas mesmo assim, você já foi demais me ajudando! Muito obrigado mesmo, deixa assim... acho que meu professor considerará.

Abraaço

Editado por Italoo
Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152k
    • Posts
      651,7k
×
×
  • Criar Novo...