BrunoMac Posted December 5, 2021 at 02:55 PM Report Share #624798 Posted December 5, 2021 at 02:55 PM 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 More sharing options...
AshKetshup Posted December 6, 2021 at 03:50 AM Report Share #624804 Posted December 6, 2021 at 03:50 AM 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. 1 Report Mas façam o que fizerem nunca façam: sudo apt remove python Link to comment Share on other sites More sharing options...
BrunoMac Posted December 6, 2021 at 01:33 PM Author Report Share #624817 Posted December 6, 2021 at 01:33 PM 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 More sharing options...
AshKetshup Posted December 6, 2021 at 03:30 PM Report Share #624825 Posted December 6, 2021 at 03:30 PM 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. Mas façam o que fizerem nunca façam: sudo apt remove python Link to comment Share on other sites More sharing options...
thoga31 Posted December 8, 2021 at 12:05 AM Report Share #624856 Posted December 8, 2021 at 12:05 AM (edited) 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 December 8, 2021 at 12:09 AM by thoga31 Faltava uma nota adicional sobre o input Knowledge is free! Link to comment Share on other sites More sharing options...
BrunoMac Posted December 8, 2021 at 12:24 PM Author Report Share #624865 Posted December 8, 2021 at 12:24 PM 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 More sharing options...
Solution BrunoMac Posted December 8, 2021 at 12:28 PM Author Solution Report Share #624866 Posted December 8, 2021 at 12:28 PM 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 More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now