Ir ao conteúdo
  • Cadastre-se

C Comparando duas strings com condicional IF


Malcolm X
Ir à solução Resolvido por Malcolm X,

Posts recomendados

Estou tentando comparar duas strings, se alguém poder ajudar agradeço, se eu achar uma solução posto antes.

 

/*Crie um programa que compara duas strings 
obs.:(n ˜ao use a func¸ ˜ao strcmp).*/
main()
{
    char str1[30],str2[30];
    printf("Digite a primeira string: ");
    scanf("%[^\n]", str1);
    fflush(stdin);
    printf("Digite a segunda string: ");
    scanf("%[^\n]", str2);
    fflush(stdin);
    if(str1 == str2)
    {
        printf("O conteudo das duas strings eh igual.");
    }
    else
    {
        printf("O conteudo das duas strings eh diferente.");
    }
}

 

  • Amei 1
Link para o comentário
Compartilhar em outros sites

C Strings ?

 

Em C, string não é um tipo de dado padrão tal qual é int, float e char. Mas sim uma coleção de tipos char, quase sempre, um tipo matriz de char ou uma sequencia de bytes contíguos terminando com valor '\0'.

 

 

Na comparação de strings, compara-se os seus elementos, ou seja, os caracteres em cada índice percorrendo as strings com um loop até o limite delas.

 

 

 

 

  • Curtir 2
Link para o comentário
Compartilhar em outros sites

17 minutos atrás, Mauro Britivaldo disse:

Na comparação de strings, compara-se os seus elementos, ou seja, os caracteres em cada índice percorrendo as strings com um loop até o limite delas.

Então nesse caso vou precisar usar um for pra percorrer e comparar letra por letra, eh isso?

 

17 minutos atrás, Mauro Britivaldo disse:

Em C, string não é um tipo de dado padrão tal qual é int, float e char. Mas sim uma coleção de tipos char, quase sempre, um tipo matriz de char ou uma sequencia de bytes contíguos terminando com valor '\0'.

No caso, String é um Vetor de caracteres(tipo de dado char).

adicionado 3 minutos depois
agora, Malcolm X disse:

Então nesse caso vou precisar usar um for pra percorrer e comparar letra por letra, eh isso?

Só vejo dessa, forma. Apesar de no início querer comparar de forma bruta uma com a outra.

Usando essa função strcmp que eh mencionada no exercício, daria pra comparar de forma bruta uma string com a outra??

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

3 minutos atrás, Malcolm X disse:

Então nesse caso vou precisar usar um for pra percorrer e comparar letra por letra, eh isso?

 

Exato. 🤔Se fosse possível comparar apenas usando if(A==B) provavelmente ninguém ia fazer disso um exercício afinal.

 

Em C uma string é uma sequência de zero ou mais bytes terminada por um 0. E é identificada pelo seu endereço de início.

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

@Malcolm X  Você pode criar uma função e definir os valores de retorno com o resultado da comparação, p.ex 0 diferente e 1 igual. No loop será feita a comparação de char entre uma string e outra.

 

int compara(char *s1, char *s2){
    while(*s1){
        if(*s1++ != *s2++){
            return 0;
        }
    }
    if(*s2){return 0;}
    return 1;
}

...

if(compara(str1,str2))
    printf("Iguais\n");
else
    printf("Diferentes\n");

 

  • Curtir 3
Link para o comentário
Compartilhar em outros sites

2 horas atrás, Malcolm X disse:

Então nesse caso vou precisar usar um for pra percorrer e comparar letra por letra, eh isso?

 

Vai porque esse é o padrão mesmo; Letra por Letra

 

As exceções são abstrações do padrão, por exemplo; uma implementação que fez alinhamento com tipo int compara não 1 simples char (nome para 1 byte ou uma letra), bem precisamente falando da arquitetura 32 bits, compara 4 por 4 bytes ou uma palavra por ciclo. Contudo, como já disse de início a lógica ainda é a mesma .

 

 

2 horas atrás, Malcolm X disse:

No caso, String é um Vetor de caracteres(tipo de dado char).

 

Sim e muito bem colocado; a única peculiaridade é que essa string, que é um vetor e por padrão do tipo char, termina sempre-sempre com o caractere nulo '\0' e seus outros elementos são codificações geralmente usadas para representar palavras nos programas. Qualquer definição diferente dessa é uma abstração ou sinônimo da intepretação padrão igual à essa.

 

 

Foram boas perguntas; A Melhor Ficou por Último

 

2 horas atrás, Malcolm X disse:

Só vejo dessa, forma. Apesar de no início querer comparar de forma bruta uma com a outra.

Usando essa função strcmp que eh mencionada no exercício, daria pra comparar de forma bruta uma string com a outra??

 

A forma bruto ou também para mim uma comparação com tipos de dados padrão ou primitivos é possível porque a arquitetura no processador e as especificações do idioma permite, da maneira primitiva (ou bruta), realizar de pouco código a comparação de primitivos; uma operação lógica com blocos\estrutura de bytes pré-fixados pela própria arquitetura chamados de variáveis;

 

É natural imaginar que dentro do processador, quando comparado tipos de dados brutos (char, int, float ...), aconteça também um loop byte a byte ou bit a bit; 

 

Os engenheiros da Intel, por exemplo, é um grupo de pessoas que conhece profundamente o que acontece e como eletronicamente acontece as operações de lógica com tipos primitivos na CPU e podemos destemidamente  afirma que a função strcmp; compara byte por byte ou letra por letra e é esse motivo de existir um limitador da string e para as funções que manipulam strings: O caractere nulo '\0'.

 

Por último; é exatamente isso que pede o seu exercício; A tua versão da strcmp que compara letra a letra.

 

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

  • Solução
3 horas atrás, arfneto disse:

Se fosse possível comparar apenas usando if(A==B) provavelmente ninguém ia fazer disso um exercício afinal.

Exato kkkk. Antes de apertar o f9, tinha quase certeza q não era daquela forma hahaha

 

 

adicionado 3 minutos depois
/*Crie um programa que compara duas strings
obs.:(n ˜ao use a func¸ ˜ao strcmp).*/
main()
{
    char str1[30],str2[30];
    int contStr=0;
    printf("Digite a primeira string: ");
    scanf("%[^\n]", str1);
    fflush(stdin);
    printf("Digite a segunda string: ");
    scanf("%[^\n]", str2);
    fflush(stdin);
    printf("Comparando...");
    for(int i=0;i<strlen(str1);i++)
    {
        if(str1[i] == str2[i]) //compara A com B
        {
            contStr++; //Conta a qtd de caracteres semelhantes(mesma posição no vetor)
            printf("...");
        }
    }
    if(strlen(str2) == contStr)  //Compara se o tamanho da String(str2) tem o mesmo tamanho do contador (contStr)
    {
        printf("\nAs strings digitadas tem exatamente os mesmos caracteres .");
    }
    else
    {
        printf("\nAs strings possuem conteudo diferente.");
    }
}

Minha lógica foi essa. Não sei se é o mais correto a se fazer, mas funcionou para mim e eu explico nos comentários(ou pelo menos tento) como funciona. Se alguém tiver correções ou melhorias, sou todo ouvidos.

adicionado 9 minutos depois
2 horas atrás, Midori disse:

@Malcolm X  Você pode criar uma função e definir os valores de retorno com o resultado da comparação, p.ex 0 diferente e 1 igual. No loop será feita a comparação de char entre uma string e outra.

 


int compara(char *s1, char *s2){
    while(*s1){
        if(*s1++ != *s2++){
            return 0;
        }
    }
    if(*s2){return 0;}
    return 1;
}

...

if(compara(str1,str2))
    printf("Iguais\n");
else
    printf("Diferentes\n");

 

Achei interessante como você fez, mas entendi mais ou menos, você utiliza ponteiro né? me confunde um pouco por ser um assunto que não estudei ainda.

Pelo que eu entendi Se string1 for diferente de string2 então retorna o valor 0, ou seja falso. Caso contrário retorna 1, verdadeiro, se estiver errado, pfvr pode me corrigir.

3 horas atrás, Midori disse:

*s1++ != *s2++

Não entendi a função do ++ no s1 e s2

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

11 minutos atrás, Malcolm X disse:

Minha lógica foi essa. Não sei se é o mais correto a se fazer, mas funcionou para mim e eu explico nos comentários(ou pelo menos tento) como funciona. Se alguém tiver correções ou melhorias, sou todo ouvidos

 

Está bem assim.

 

Eis o que eu poderia acrescentar:

  • scanf() não é uma boa opção. scanf() foi escrita, como o nome diz, para ler entrada formatada --- scan formatted input.. E o teclado é tudo menos isso. É mais simples e seguro usar gets() ou fgets()
  • fflush(stdin) não é certo. Pelo padrão fflush() só atua em arquivos de saída e o funcionamento em entrada é incerto. E de todo modo não precisava disso
  • Você naturalmente  lê as strings uma depois da outra. Ao ler a primeira já sabe o tamanho dela e então ao ler a segunda sabe o tamanho das duas e então deve imaginar que é meio ingênuo entrar em um loop para comparar as duas se elas tem tamanhos diferentes. Não acha que podia comparar os tamanhos e retornar a resposta de vez? Economizando uns ciclos de CPU?
  • Na primeira diferença entre as duas strings você já pode retornar. Pra que seguir o loop e contar todos que são iguais se basta um diferente? Não acha que seria melhor seguir o caminho contrário?
    Se tem tamanhos diferentes são diferentes. Se tem tamanhos iguais, na primeira letra diferente você diz que são... diferentes, Isso não vai mudar. E encerra o programa: return 0; Se chega ao final do loop é porque nenhuma letra era diferente e aí sim você diz que são iguais e retorna. Pense nisso
  • Curtir 1
Link para o comentário
Compartilhar em outros sites

7 horas atrás, arfneto disse:

ciclos de CPU

Tu aprendeu Assembly Arfneto?

adicionado 0 minutos depois

@arfneto

adicionado 3 minutos depois
7 horas atrás, Malcolm X disse:

Crie um programa que compara duas strings

E se o caractere foi maiúsculo?@Malcolm X

adicionado 16 minutos depois
7 horas atrás, arfneto disse:

diferença entre as duas strings você já pode retornar.

Só pelo tamanho já poderia saber que as duas são diferentes.

 

poderia ser assim:

{
    char str1[31],str2[31];
    int contStr=0;
    
    printf("Digite a primeira string: ");
    gets(str1);
    fflush(stdin);
    printf("Digite a segunda string: ");
    gets(str2);
    //caso queira ignorar maiusculas strupr();
    
    if(strlen(str2) != strlen(str1))  
        printf("\nAs strings possuem conteudo diferente.");
    else{
   		printf("Comparando...");
    	for(int i=0;i<strlen(str1);i++)
   		{
        	if(str1[i] == str2[i]) 
        	{
           		 contStr++; 
           		 printf("...");
      		}
       		else 
				break;
   	    }
  	    if(strlen(str2) == contStr)  
  	      	printf("\nAs strings digitadas tem exatamente os mesmos caracteres .");
  	  	else
        	printf("\nAs strings possuem conteudo diferente.");
  	}
}

@Malcolm X 

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

10 horas atrás, Malcolm X disse:

Não entendi a função do ++ no s1 e s2

 

Quando passo a string como argumento da função, os ponteiros recebem o endereço do primeiro elemento do vetor. Para comparar esses elementos tenho que ir deslocando os endereços com ++.

 

Eu poderia fazer assim,

if(*s1 != *s2){
    return 0;
}
s1++;
s2++;

 

Veja que na comparação uso o operador "*" para pegar o conteúdo no endereço de memória que ele aponta. E depois quando incremento com ++ (sem o "*") desloco o ponteiro para o próximo endereço de memória. Na parte (*s1++ != *s2++) eu já faço isso na mesma linha.

 

  • Curtir 1
  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

6 horas atrás, Luiz Paulo Escobar disse:

Tu aprendeu Assembly Arfneto?

 

Sim. Tempos atrás.

6 horas atrás, Luiz Paulo Escobar disse:

E se o caractere foi maiúsculo?

 

Não faz diferença. A menos que esteja falando em considerar iguais maiúsculas e minúsculas. Nesse caso o que se faz é observar que a diferença entre 'A'e 'a' é 32. Então para comparar duas letras sem diferenciar 'x' de 'X' você simplesmente compara zerando esse bit antes. 

Claro que pode chamar funções como tolower() ou toupper() ou usar usar qualquer outra técnica desde que funcione. Mas isso é o ótimo.

6 horas atrás, Luiz Paulo Escobar disse:

poderia ser assim:

 

O código que postou é mais eficiente. Mas não muito  :( 

  • não precisa do fflush() e nem deveria usar de todo modo. fflush() só está definido para fluxos de saída.
  • Se os comprimentos são diferentes simplesmente retorne. Para que um else?
  • Ao invés de testar se todos são iguais teste se algum é diferente. É mais esperto. Qual o propósito de saber se 8 letras de uma string de 9 são diferentes se só quer saber se elas são diferentes?
  • Curtir 2
  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

🙃

adicionado 14 minutos depois

Como o problema já foi resolvido vou postar duas soluções seguindo o que expliquei antes

 

O Simples

int main(int argc, char** argv)
{
	char uma[20];
	char outra[20];
	printf("Primeira string: ");
	fgets(uma, 20, stdin);
	int N = strlen(uma);
	printf("Segunda string: ");
	fgets(outra, 20, stdin);
	if (N != strlen(outra))
	{
		printf("As strings sao diferentes\n");
		return 0; // se os comirmentos sao diferentes ja era
	};	// if()
	for (int i = 0; i < (N-1); i += 1)
		if (uma[i] != outra[i])
		{
			printf("As strings sao diferentes\n");
			return 0; // basta uma letra diferente
		};
	printf("As strings sao iguais\n");
	return 1; // comparou todas
};
  • Se os comprimentos diferem não há razão para um loop. Retorna 0 que equivale a falso em C
  • Se os comprimentos são iguais compara as letras, mas apenas até encontrar a primeira diferença
  • Se chegou ao fim do loop é porque as strings são iguais e retorna não-zero, verdadeiro em C

E se não for diferenciar maiúsculas de minúsculas?

 

Nesse caso muda a comparação, mas apenas para o caso de ter letras na mesma posição das duas strings.

Ela pode ter números por exemplo... É claro que se pode chamar uma função, mas não faz sentido chamar uma função dentro de uma coisa tão simples.

 

Eis uma função dessas
 

int main(int argc, char** argv)
{
	char uma[20];
	char outra[20];
	printf("Primeira string: ");
	fgets(uma, 20, stdin);
	int N = strlen(uma);
	printf("Segunda string: ");
	fgets(outra, 20, stdin);
	if (N != strlen(outra))
	{
		printf("As strings sao diferentes\n");
		return 0;
	};	// if()
	// se forem duas letras ignora a diferenca entre
	// maiusculas e minusculas
	for (int i = 0; i < (N-1); i += 1)
	{
		char a = uma[i];
		char b = outra[i];
		char letras =
			((a >= 'a') && (a <= 'z') || (a >= 'A') && (a <= 'Z')) &&
			((b >= 'a') && (b <= 'z') || (b >= 'A') && (b <= 'Z'));
		if (
			( letras && ((a & 95) != (b & 95)) ) ||
			(!letras && (a != b))
			)
		{
			printf("As strings sao diferentes\n");
			return 0;
		};
	};	// for()
	printf("As strings sao iguais\n");
	return 1;
};

Sim, podia ser escrito sem as variáveis a, b e letras. Ia ficar ruim de ler o if gigante. E ia calcular os índices umas 16 vezes. Então assim deve ser mais eficiente e dá até pra ler...

 

E de onde vem o 95?
 

A diferença entre uma maiúscula e uma minúscula na tabela,('a' - 'A') por exemplo, é de 32. No popular o bit 5. Nos 7 bits de um char cabe até 127. Então 127-32 = 95 é o número que tem todos os bits 1 exceto o 5: 0101 1111 em binário. Se você fizer um AND de um char então com esse valor vai zerar o que tem no bit 5 E o resto vai ficar igualzinho. E nesse caso é o que queremos: comparar as letras sem diferenciar maiúsculas de minúsculas.

 

 

 

Link para o comentário
Compartilhar em outros sites

Ponteiro e Identificador de Matrizes

 

Agradou-me bastante essa sua função  @Midori, note mais tarde @Malcolm X que apontadores e nomes de matrizes tem operação de notação intercambiável, ou seja, o que tem num tem no outro e se existe uma diferença que precisa ser ressaltada é na declaração; onde no caso das matrizes existe memória associada de imediato.

/*---[ Declaração de Variavéis ]----*/

 char  str [25]; //_ Aqui  tem memória
 char *str;      //_ Aqui ~tem memória

 

 

# Uma solução ...

Em 21/07/2020 às 19:28, Midori disse:

@Malcolm X  Você pode criar uma função e definir os valores de retorno com o resultado da comparação, p.ex 0 diferente e 1 igual. No loop será feita a comparação de char entre uma string e outra.

 


int compara(char *s1, char *s2){
    while(*s1){
        if(*s1++ != *s2++){
            return 0;
        }
    }
    if(*s2){return 0;}
    return 1;
}

...

if(compara(str1,str2))
    printf("Iguais\n");
else
    printf("Diferentes\n");

 

 

 

Apontador com Notação de Vetores + 'top-down'

/*============================================================[ COMPARE ]=*/
 int str_compare (const char *s1, const char *s2){
	
	unsigned int index = -0x1;
	do {
		++ index;
		if ((s1 [index]) - (s2 [index])){

			if (s1 [index] > s2 [index]) return 2; /*_s2 é menor  */
						else return 1; /*_s1 é menor  */
	}	}
	while ((s2 [index]) != '\000');
	return 0; /*_ são iguais */	
 }
/*-----[ FIM_COMPARE ]----------------------------------------------------*/

 

Em 21/07/2020 às 22:22, Malcolm X disse:

me confunde um pouco por ser um assunto que não estudei ainda.

O ponteiro é subestimado por quase todo mundo, mas é interessante, útil e fácil depois de um tempo.

 

~~

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Outra forma é com fgetc comparando os caracteres  no loop do input,

 

int main(){
    int i = 0, iguais = 1;
    char str[50], c;
    
    fgets(str,50,stdin);
    
    while((c=fgetc(stdin))!='\n'){
        if(c!=str[i++]) iguais = 0;;     
    }
    if(str[i]!='\n'){iguais = 0;}

    if(iguais)
        printf("Iguais");
    else
        printf("Diferentes");

    return 0;
}

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!