Estou tentando obter um programa para permitir que um usuário insira uma palavra ou caractere, armazene-o e imprima-o até que o usuário digite novamente, saindo do programa. Meu código fica assim:
#include <stdio.h>
int main()
{
char input[40];
char check[40];
int i=0;
printf("Hello!\nPlease enter a word or character:\n");
gets(input);
printf("I will now repeat this until you type it back to me.\n");
while (check != input)
{
printf("%s\n", input);
gets(check);
}
printf("Good bye!");
return 0;
}
O problema é que eu continuo recebendo a impressão da sequência de entrada, mesmo quando a entrada do usuário (cheque) corresponde ao original (entrada). Estou comparando os dois incorretamente?
gets( )
foi removido do padrão. Use emfgets( )
vez disso.strcmp()
retornar zero quando suas entradas são iguais explica como comparar seqüências de caracteres para igualdade, desigualdade, menor que, maior que, menor que ou igual e maior que ou igual. Nem todas as comparações de strings são para igualdade. As comparações sensíveis a maiúsculas e minúsculas são diferentes novamente; outras comparações especiais (ordem do dicionário, por exemplo) requerem comparadores mais especializados e existem expressões regulares para comparações ainda mais complexas.gets()
é um não-go. Também foi removida do padrão desde C11 -> Por favor, leia Por que a função gets é tão perigosa que não deve ser usada?Respostas:
Você não pode (utilmente) comparar seqüências de caracteres usando
!=
ou==
, você precisa usarstrcmp
:A razão para isso é porque
!=
e==
comparará apenas os endereços base dessas strings. Não é o conteúdo das próprias strings.fonte
while (strcmp(check, input))
é suficiente e é considerado uma boa prática.Ok, algumas coisas:
gets
é inseguro e deve ser substituído por,fgets(input, sizeof(input), stdin)
para que você não obtenha um estouro de buffer.Em seguida, para comparar cadeias, você deve usar
strcmp
, onde um valor de retorno 0 indica que as duas cadeias correspondem. O uso dos operadores de igualdade (ie.!=
) Compara o endereço das duas cadeias, em oposição aos indivíduoschar
dentro delas.E observe também que, embora neste exemplo não cause problemas,
fgets
armazena o caractere de nova linha,'\n'
nos buffers também;gets()
não. Se você comparasse a entrada do usuário defgets()
uma string literal como"abc"
nunca corresponderia (a menos que o buffer fosse muito pequeno para que'\n'
ele não caísse nele).fonte
fgets()
, a string pode ser"abc\n"
porquefgets()
mantém a nova linha. Se você comparar isso com"abc"
, você obterá 'not equal' devido à diferença entre um byte nulo que termina"abc"
e a nova linha nos dados lidos. Então, você precisa zapear a nova linha. A maneira confiável de uma linha de fazer isso é obuffer[strcspn(buffer, "\n")] = '\0';
que tem o mérito de funcionar corretamente, independentemente de haver algum dado no buffer ou se esse dado termina com uma nova linha ou não. Outras formas de zapear a nova linha são facilmente travadas.Use
strcmp
.Isso está na
string.h
biblioteca e é muito popular.strcmp
retorne 0 se as seqüências de caracteres forem iguais. Veja isso para uma melhor explicação do questrcmp
retorna.Basicamente, você tem que fazer:
ou
ou
Você pode verificar isso , um tutorial sobre
strcmp
.fonte
Você não pode comparar matrizes diretamente assim
Você deve compará-los char a char; para isso, você pode usar uma função e retornar um valor booleano (True: 1, False: 0). Em seguida, você pode usá-lo na condição de teste do loop while.
Tente o seguinte:
fonte
checker
encontra'\0'
em uma das cadeias, não verifica a outra cadeia'\0'
. A função retorna1
("igual") mesmo que uma sequência seja apenas o prefixo da outra (por exemplo,"foo"
e"foobar"
).||
vez de&&
.Bem-vindo ao conceito do ponteiro. Gerações de programadores iniciantes acharam o conceito ilusório, mas se você deseja se tornar um programador competente, deve dominar esse conceito - além disso, você já está fazendo a pergunta certa. Isso é bom.
Está claro para você o que é um endereço? Veja este diagrama:
No diagrama, o número inteiro 1 é armazenado na memória no endereço 0x4000. Por que em um endereço? Como a memória é grande e pode armazenar muitos números inteiros, assim como uma cidade é grande e pode abrigar muitas famílias. Cada número inteiro é armazenado em um local de memória, pois cada família reside em uma casa. Cada local de memória é identificado por um endereço , assim como cada casa é identificada por um endereço.
As duas caixas no diagrama representam dois locais distintos de memória. Você pode pensar neles como se fossem casas. O número inteiro 1 reside na localização da memória no endereço 0x4000 (pense em "4000 Elm St."). O número inteiro 7 reside no local da memória no endereço 0x4004 (pense em "4004 Elm St.").
Você pensou que seu programa estava comparando o 1 ao 7, mas não estava. Ele estava comparando o 0x4000 ao 0x4004. Então, o que acontece quando você tem essa situação?
Os dois números inteiros são iguais, mas os endereços diferem. Seu programa compara os endereços.
fonte
Sempre que você estiver tentando comparar as strings, compare-as com relação a cada caractere. Para isso, você pode usar a função de string incorporada chamada strcmp (input1, input2); e você deve usar o arquivo de cabeçalho chamado
#include<string.h>
Tente este código:
fonte
Vamos nos aprofundar para ver por que
check != input
não é suficiente .Em C, string é uma especificação de biblioteca padrão.
input
acima não é uma string .input
é matriz 40 de caracteres .O conteúdo de
input
pode se tornar uma string .Na maioria dos casos, quando uma matriz é usada em uma expressão, ela é convertida no endereço do seu primeiro elemento.
O abaixo converte
check
einput
para seus respectivos endereços do primeiro elemento, então esses endereços são comparados.Para comparar strings , precisamos usar esses endereços e, em seguida, examinar os dados para os quais eles apontam.
strcmp()
faz o trabalho . §7.23.4.2O código não apenas pode descobrir se as seqüências de caracteres têm os mesmos dados, mas qual é maior / menor quando elas diferem.
O abaixo é verdadeiro quando a string é diferente.
Para obter informações, consulte Criando minha própria
strcmp()
funçãofonte
Esta é uma solução muito simples na qual você obterá sua saída conforme desejar.
fonte
gets();
não faz parte do padrão C desde C11.strcmp(s1,s2)
é UB, pois os2
conteúdo não é especificado primeiro.