Usar fgets() junto con strcmp() strcmp no se compara correctamente

Resuelto R0gue asked hace 8 meses • 2 respuestas

Mi tarea actual es codificar una función a la que se le asigna un FILEpuntero 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;
}
R0gue avatar Feb 16 '24 09:02 R0gue
Aceptado

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;
chux - Reinstate Monica avatar Feb 16 '2024 04:02 chux - Reinstate Monica

Dado que está haciendo coincidir palabras y no líneas completas, debe usar fscanfen 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;
}
chqrlie avatar Feb 16 '2024 14:02 chqrlie