Search code examples
cfilepbm

Can I ignore a line started with "#" while reading a file in C?


the following code is used to read a .pbm file

int **leArquivoImagem(char *nomeImagem, char *tipo, int *lin, int *col)
{
    FILE *arq = fopen(nomeImagem, "r");
    if (arq == NULL)
    {
        printf("\nErro ao abrir arquivo - leArquivoImagem.\n");
        return NULL;
    }
    fscanf(arq, "%s", tipo);
    printf("%s\n", tipo);

    //line ignorer here

    fscanf(arq, "%d %d", col, lin);
    printf("%d %d\n", *lin, *col);
    int **mat = alocaMatrizImagem(*lin, *col);
    if (mat == NULL)
    {
        printf("\nErro ao alocar mat imagem - leArquivoImagem.\n");
        return NULL;
    }
    for (int i = 0; i < *lin; i++)
    {
        for (int j = 0; j < *col; j++)
        {
            fscanf(arq, "%d", &mat[i][j]);
        }
    }
    fclose(arq);
    return mat;
}

and that's the file I'm reading:

P1
5 3
0 0 1 0 1
0 0 1 1 0
1 1 0 0 0

but in some cases files can have commented lines, like this:

P1
# comment here
5 3
0 0 1 0 1
0 0 1 1 0
1 1 0 0 0

or even like this:

P1
# comment here
# another comment to ignore
5 3
0 0 1 0 1
0 0 1 1 0
1 1 0 0 0

How can I ingore those lines? (Comments are always between the "P1" and the dimensions).

I tried using a buffer with the max line size (2047) in the following codes:

char line[2047];
while (fgets(line, sizeof(line), arq) != NULL)
    {
        char *hash = strchr(line, '#');
        if (hash != NULL)
            *hash = '\0';
    }

    char buffer[2047];
    while (fgets(buffer, 2047, arq) != NULL) {
        if (buffer[0] != '#') {
            break;
        }
    }

    char line[2047];
    while (fgets(line, sizeof(line), arq)) {
        if (line[0] == '#') {
            continue;
        }
    }

Solution

  • The following code solved my problem. Thanks to Chux for suggesting to use only fgets(), YuWea for the buffer size correction, and Jonathan Leffler for suggesting sscanf() and break.

    int **leArquivoImagem(char *nomeImagem, char *tipo, int *lin, int *col) {
        FILE *arq = fopen(nomeImagem, "r");
        if (arq == NULL) {
            printf("\nErro ao abrir arquivo - leArquivoImagem.\n");
            return NULL;
        }
    
        char buffer[2048];
        while (fgets(buffer, sizeof(buffer), arq) != NULL) {
    
            sscanf(buffer, "%s", tipo);
            printf("%s\n", tipo);
    
            // Ignore all commented lines and get dimensions
            while (fgets(buffer, sizeof(buffer), arq) != NULL) {
                if (buffer[0] != '#') {
                    sscanf(buffer, "%d %d", col, lin);
                    printf("%d %d\n", *lin, *col);
                    break;
                }
            }
    
            int **mat = alocaMatrizImagem(*lin, *col);
            if (mat == NULL) {
                printf("\nErro ao alocar mat imagem - leArquivoImagem.\n");
                fclose(arq);
                return NULL;
            }
    
            int count = 0;
            for (int i = 0; i < *lin; i++) {
                fgets(buffer, sizeof(buffer), arq);
                char *ptr = buffer;
                for (int j = 0; j < *col; j++) {
                    while (*ptr == ' ') ptr++;
                    if (*ptr == '\n' || *ptr == '\0') {
                        j--;
                        continue;
                    }
                    mat[i][j] = strtol(ptr, &ptr, 10);
                }
            }
    
            fclose(arq);
            return mat;
        }
    
        fclose(arq);
        return NULL;
    }