Jump to content

Comparar input com array de strings


BrunoMac
Go to solution Solved by BrunoMac,

Recommended Posts

Boas tardes a todos,

Estou a iniciar-me na linguagem C e estou ás voltas com um problema que não consigo resolver.

Quero comparar o input de um utilizador, com um array de strings para verificar se a string é válida ou não. Consigo armazenar as strings , mas o strcmp funciona nalgumas strings e não noutras.

Qualquer ajuda é bem vinda!

Obrigado

O código é o seguinte:

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

char *colors[] = {
    "green",
    "red",
    "blue",
    "yellow",
    "brown",
    "white",
    "black"
};
int n = 5, i, j, l;
char cores[4][7];
char* copy;
char input[5];
int num,result;

void copiar(){
    strcpy(copy,input);
}

int main(){
    
    printf("Add colors\n");

    for (int i = 0; i < n; i++)
    {
        scanf("%s", input);
        strcpy(cores[i],input);
        while(j<n)
        {
            if(strcmp(input,colors[j])==0)
                printf("Gotcha!\n");
            // comparing strings str1 and str2
            result = strcmp(input,colors[j]);
            printf("strcmp(str1, str2) = %d\n", result);
            j++;
            break;
        }
        input[0]='\0';
    }

    for(l=0;l<5;l++)
           printf("%s\n", cores[l]);
        return 0;
}
Link to comment
Share on other sites

Boas, @BrunoMac.
Eis a minha solução com alguns apontamentos.

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

int n = 5, i, j, l, num, result;
char cores[4][7], input[5], *copy;
char *colors[] = {
    "green",
    "red",
    "blue",
    "yellow",
    "brown",
    "white",
    "black"
};

// Esta função atualmente é desnecessaria.
void copiar(){
    strcpy(copy, input);
}

int main(){
    printf("Add colors\n");

    for (int i = 0; i < n; i++) {
        scanf("%s", input);
        
      	// Debug print
        printf("Input: %s\n", input);
        
        /*
        (1)
        De momento n = 5 e o array que tens tem 7 elementos. 
        Portanto destes 7 elementos ele só vai passar pelos 5 primeiros para verificar a comparação.
        
        antes tinhas:
        n = 5;          (lá em cima nas variaveis)
        
        deverias de ter:
        n = 7;          (porque são 7 elementos)
        
        ou então antes de um loop calculas o tamanho do array com isto:
        int colorsCount = sizeof(colors)/sizeof(colors[0]);
        */
        
        strcpy(cores[i], input);
        
      	// (1)
        int colorsCount = sizeof(colors)/sizeof(colors[0]);
      	
      	// O loop while() que aqui tinhas é o equivalente a este ciclo 'for'.
        for (int j = 0; j < colorsCount; j++) {
            if (strcmp(input, colors[j]) == 0) {
                printf("Gotcha!\n");
                
              	// Parar de verificar se encontrar um match
                break;
            }
            
            // comparing strings str1 and str2
            // result = strcmp(input, colors[j]);
            // printf("strcmp(str1, str2) = %d\n", result);
        }
        
        // Acho que só estás a fazer o primeiro caracter ficar o '/0'.
        // input[0]='\0';
    }
    
  	/*
    Aqui só te mostra 4 elementos porque é o que tens definido que o array cores contem.
    Se pretenderes que o array se adapte (array dinamico) terias de trabalhar com "mallocs"
    */
    // (1)
  	int coresCount = sizeof(cores)/sizeof(cores[0]);
    for(l = 0; l < coresCount; l++)
        printf("%s\n", cores[l]);
    
    return 0;
}

Espero conseguir ajudar.

  • Vote 1

Mas façam o que fizerem nunca façam:

sudo apt remove python

 

Link to comment
Share on other sites

Em 06/12/2021 às 04:50, AshKetshup disse:

Boas, @BrunoMac.
Eis a minha solução com alguns apontamentos.

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

int n = 5, i, j, l, num, result;
char cores[4][7], input[5], *copy;
char *colors[] = {
    "green",
    "red",
    "blue",
    "yellow",
    "brown",
    "white",
    "black"
};

// Esta função atualmente é desnecessaria.
void copiar(){
    strcpy(copy, input);
}

int main(){
    printf("Add colors\n");

    for (int i = 0; i < n; i++) {
        scanf("%s", input);
        
      	// Debug print
        printf("Input: %s\n", input);
        
        /*
        (1)
        De momento n = 5 e o array que tens tem 7 elementos. 
        Portanto destes 7 elementos ele só vai passar pelos 5 primeiros para verificar a comparação.
        
        antes tinhas:
        n = 5;          (lá em cima nas variaveis)
        
        deverias de ter:
        n = 7;          (porque são 7 elementos)
        
        ou então antes de um loop calculas o tamanho do array com isto:
        int colorsCount = sizeof(colors)/sizeof(colors[0]);
        */
        
        strcpy(cores[i], input);
        
      	// (1)
        int colorsCount = sizeof(colors)/sizeof(colors[0]);
      	
      	// O loop while() que aqui tinhas é o equivalente a este ciclo 'for'.
        for (int j = 0; j < colorsCount; j++) {
            if (strcmp(input, colors[j]) == 0) {
                printf("Gotcha!\n");
                
              	// Parar de verificar se encontrar um match
                break;
            }
            
            // comparing strings str1 and str2
            // result = strcmp(input, colors[j]);
            // printf("strcmp(str1, str2) = %d\n", result);
        }
        
        // Acho que só estás a fazer o primeiro caracter ficar o '/0'.
        // input[0]='\0';
    }
    
  	/*
    Aqui só te mostra 4 elementos porque é o que tens definido que o array cores contem.
    Se pretenderes que o array se adapte (array dinamico) terias de trabalhar com "mallocs"
    */
    // (1)
  	int coresCount = sizeof(cores)/sizeof(cores[0]);
    for(l = 0; l < coresCount; l++)
        printf("%s\n", cores[l]);
    
    return 0;
}

Espero conseguir ajudar.

Boas AshKetshup,

Obrigado pela ajuda.

Já limpei o código agora tenho que avaliar para quando não existe cor igual no array.

Um simples else não funciona porque if (!strcmp(input, palette[j])) retorna true if strcmp retorna 0 (que foi o que acabei por usar).

E isso acontece para todas as outras cores no array, logo strcmp vai ternornar !=0 várias vezes.

Tenho que arranjar maneira de criar uma condição em que se nunca houver TRUE ou seja se !strcmp nunca acontece, então printf("cor não existe").

Link to comment
Share on other sites

Algumas notas:

  • Não se deve usar scanf() para a obtenção de strings de input, mas sim fgets();
  • A string obtida do input pode conter o caracter \n do Enter premido;
  • Deve-se evitar o uso de variáveis globais sempre que possível;
  • A variável input só prevê a existência de 5 caracteres na string, incluindo o caracter terminal \0; o espaço alocado deve ser maior;
  • O uso de caracteres não ASCII pode levar a comportamentos indefinidos por parte do programa.

Sugestão de código (testado)

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

#define QTD  5    // Número de strings a ler
#define MAX 10    // Tamanho máximo de cada string, incluindo o caracter terminal

char *colors[] = {
    "green",
    "red",
    "blue",
    "yellow",
    "brown",
    "white",
    "black"
};

const int DIM = sizeof(colors) / sizeof(colors[0]);   // Dimensão do vetor de cores

/* Verifica se a string pertence ao vetor de cores */
int check(char *s) {
    // Elimina o '\n' que o fgets costuma apanhar na leitura
    if (s[strlen(s) - 1] == '\n') s[strlen(s) - 1] = '\0';
    
    for (int i = 0; i < DIM; i++)
        if (strcmp(s, colors[i]) == 0)
            return 1;
    return 0;
}

int main(void) {
    char line[MAX];        // Temporário
    char valid[QTD][MAX];  // Vetor com strings finais válidas
    int count = 0;         // Contador de strings válidas lidas
    
    /* Obtém a string, verifica se é válida, e copia para o vetor de resultado caso seja */
    for (int i = 0; i < QTD; i++) {
        fgets(line, MAX, stdin);
        if (check(line)) {
            strcpy(valid[count], line);
            count++;
        }
    }
    
    /* Faz output do vetor final */
    printf("Foram identificadas %d strings válidas:\n", count);
    for (int i = 0; i < count; i++)
        printf("%s\n", valid[i]);
    
    return 0;
}

 

Cumprimentos.

Edited by thoga31
Faltava uma nota adicional sobre o input

Knowledge is free!

Link to comment
Share on other sites

Em 06/12/2021 às 15:30, AshKetshup disse:

Consegues verificar se não encontrou uma match inicializando primeiro a variavel j antes do ciclo for ( int j; ) e ao terminares os ciclos usares um if (j == colorsCount).

Alguma duvida diz.

Boas AskKetchup.

Consigo verificar mas vou ter que fazer uma function para retornar um valor e a partir daí fazer a contagem. Porque dentro do FOR se fizer a seguir ao IF, else
            {
                printf("Opcao invalida. Tente de novo!\n");
            }

ele a cada ciclo imprime e não é isso que quero. Tens alguma ideia?

Link to comment
Share on other sites

  • Solution
12 horas atrás, thoga31 disse:

Algumas notas:

  • Não se deve usar scanf() para a obtenção de strings de input, mas sim fgets();
  • A string obtida do input pode conter o caracter \n do Enter premido;
  • Deve-se evitar o uso de variáveis globais sempre que possível;
  • A variável input só prevê a existência de 5 caracteres na string, incluindo o caracter terminal \0; o espaço alocado deve ser maior;
  • O uso de caracteres não ASCII pode levar a comportamentos indefinidos por parte do programa.

Sugestão de código (testado)

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

#define QTD  5    // Número de strings a ler
#define MAX 10    // Tamanho máximo de cada string, incluindo o caracter terminal

char *colors[] = {
    "green",
    "red",
    "blue",
    "yellow",
    "brown",
    "white",
    "black"
};

const int DIM = sizeof(colors) / sizeof(colors[0]);   // Dimensão do vetor de cores

/* Verifica se a string pertence ao vetor de cores */
int check(char *s) {
    // Elimina o '\n' que o fgets costuma apanhar na leitura
    if (s[strlen(s) - 1] == '\n') s[strlen(s) - 1] = '\0';
    
    for (int i = 0; i < DIM; i++)
        if (strcmp(s, colors[i]) == 0)
            return 1;
    return 0;
}

int main(void) {
    char line[MAX];        // Temporário
    char valid[QTD][MAX];  // Vetor com strings finais válidas
    int count = 0;         // Contador de strings válidas lidas
    
    /* Obtém a string, verifica se é válida, e copia para o vetor de resultado caso seja */
    for (int i = 0; i < QTD; i++) {
        fgets(line, MAX, stdin);
        if (check(line)) {
            strcpy(valid[count], line);
            count++;
        }
    }
    
    /* Faz output do vetor final */
    printf("Foram identificadas %d strings válidas:\n", count);
    for (int i = 0; i < count; i++)
        printf("%s\n", valid[i]);
    
    return 0;
}

 

Cumprimentos.

Boas Thoga31,

Obrigado pelas dicas. Realmente já tinha reparado na questão do fgets e das variáveis globais a serem evitadas e tinha percebido que deveria ter que fazer uma função para resolver a questão de poder printar um else
            {
                printf("Opcao invalida. Tente de novo!\n");
            }

no caso da cor não existir no array.

Obrigado pelo código, tá top.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.