Usar fgets() junto con strcmp() strcmp no se compara correctamente
Mi tarea actual es codificar una función a la que se le asigna un FILE
puntero y un puntero a una cadena. La función debe analizar cuántas veces aparece la cadena en el archivo dado y devolver el valor como un número entero. También es necesario prestar atención a la distinción entre mayúsculas y minúsculas. En mi programa actual, tomo la palabra "perro" como una cadena que se encuentra en el archivo. Pero sigue dándome 0 aunque el archivo .txt tiene la palabra perro tres veces. Esta es mi primera publicación aquí y revisé las otras publicaciones sobre este tema, pero no pudieron solucionarlo.
Esto es lo que probé:
#include <stdio.h>
#include <string.h>
int searchAndCount(FILE *fp, const char *searchWord) {
int count = 0;
char buffer[4096];
while ((fgets(buffer, sizeof(buffer), fp)) != NULL) {
buffer[strlen(buffer) - 1] = '\0';
if (strcmp(buffer, searchWord) == 0) {
count++;
}
}
return count;
}
int main() {
FILE *fp;
int searchedWord;
const char *c = "dog";
fp = fopen("test.txt", "r");
if (fp == NULL) {
perror("File couldn't open properly");
return 1;
}
searchedWord = searchAndCount(fp, c);
printf("The word 'dog' occurs %d-times in the file\n", searchedWord);
fclose(fp);
return 0;
}
mi test.txt se ve así:
dog dog dogoggo dog.
y me sale esto:
The word 'dog' occurs 0-times in the file
Editar: A juzgar por los comentarios, parece que necesito implementarlo. strtok()
Estaré investigando esta función.
Pero usando:
int searchAndCount(FILE *fp, const char *searchWord) {
int count = 0;
char buffer[4096];
while ((fscanf(fp, "%4095s", buffer)) == 1) {
if (strcmp(buffer, searchWord) == 0) {
count++;
}
}
return count;
}
Más o menos resolvió el problema, mientras que "perro" no se cuenta debido al punto.
Solución:
int searchAndCount(FILE *fp, const char *searchWord) {
int count = 0;
char buffer[4096];
for (;;) {
fscanf(fp, "%*[^a-zA-Z]");
if (fscanf(fp, "%4095[a-zA-Z]", buffer) != 1)
break;
if (strcmp(buffer, searchWord) == 0)
count++;
}
return count;
}
En lugar de strcmp()
, que puede coincidir si toda la línea de entrada es solo eso, utilícelo strstr()
para buscar múltiples apariciones dentro de una línea.
El siguiente código utiliza s++
para contar 4 cuando la línea de entrada es "ababa aba abax\n"
y la clave es "aba"
. Si el conteo debería haber sido 1, investigue strtok()
.
size_t len = strlen(searchWord);
while (fgets(buffer, sizeof buffer, fp)) {
char *s = buffer;
while ((s = strstr(s, searchWord)) != NULL) {
count++;
// Use s++ to search for keys within matches
s++; // Resume searching at the next character.
// OR continue at the end of the match.
s += len);
}
}
return count;
Dado que está haciendo coincidir palabras y no líneas completas, debe usar fscanf
en lugar de fgets
:
#include <stdio.h>
#include <string.h>
int searchAndCount(FILE *fp, const char *searchWord) {
int count = 0;
char buffer[4096];
// %4095s means store up to 4095 characters into buffer
// before the null terminator
while (fscanf(fp, "%4095s", buffer) == 1) {
if (strcmp(buffer, searchWord) == 0) {
count++;
}
}
return count;
}
int main(void) {
FILE *fp;
int count;
const char *str = "dog";
fp = fopen("test.txt", "r");
if (fp == NULL) {
perror("File couldn't open properly");
return 1;
}
count = searchAndCount(fp, str);
printf("The word 'dog' occurs %d times in the file\n", count);
fclose(fp);
return 0;
}
Si quieres ignorar la puntuación, aquí tienes una versión más elaborada:
int searchAndCount(FILE *fp, const char *searchWord) {
int count = 0;
char buffer[4096];
// repeat indefinitely
for (;;) {
// consume any separators (sequences of non letters)
fscanf(fp, "%*[^a-zA-Z]");
// try and read the next word
if (fscanf(fp, "%4095[a-zA-Z]", buffer) != 1)
break;
// test the target word
if (strcmp(buffer, searchWord) == 0)
count++;
}
return count;
}