C语言读取PBM文件时如何忽略以#开头的注释行?
问题:读取PBM文件时如何忽略注释行?
我用以下C语言代码读取.pbm格式文件:
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; }
正常的PBM文件内容如下:
P1 5 3 0 0 1 0 1 0 0 1 1 0 1 1 0 0 0
但部分PBM文件会在P1标识与尺寸信息之间存在以#开头的注释行,例如:
P1 # comment here 5 3 0 0 1 0 1 0 0 1 1 0 1 1 0 0 0
或者:
P1 # comment here # another comment to ignore 5 3 0 0 1 0 1 0 0 1 1 0 1 1 0 0 0
我尝试过以下几种代码实现忽略注释,但都失败了:
第一种:
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; } }
请问如何正确实现忽略这些注释行的功能?
解决方案
你之前的代码失败原因:
- 第一种和第三种代码会把文件读到末尾,后续的
fscanf没有内容可读; - 第二种代码只跳过开头是
#的行,但无法处理空行或行内带注释的情况,且跳出循环后没有从当前行解析尺寸。
正确的实现需要逐行处理,跳过注释内容,直到成功读取到尺寸信息,同时兼容行内注释(比如5 3 # width and height这种格式)。将原代码中//line ignorer here的位置替换为以下代码:
char line[2048]; int read_result; // 循环读取,直到成功获取尺寸 while (1) { // 读取一行内容 if (!fgets(line, sizeof(line), arq)) { printf("\nErro: Arquivo PBM inválido, faltam dados de dimensão.\n"); fclose(arq); return NULL; } // 截断行内的注释(从#开始到行尾) char *hash_ptr = strchr(line, '#'); if (hash_ptr != NULL) { *hash_ptr = '\0'; } // 尝试从当前行解析宽和高 read_result = sscanf(line, "%d %d", col, lin); if (read_result == 2) { // 成功读取到两个整数,退出循环 break; } // 读取失败则继续循环,处理下一行 }
这段代码的逻辑:
- 逐行读取文件内容;
- 遇到
#就截断该行后续内容,忽略注释; - 尝试从处理后的行中解析两个整数(PBM的宽和高);
- 只有成功读取到两个整数时才退出循环,否则继续处理下一行,自动跳过纯注释行、空行。
这样就能正确处理各种带注释的PBM文件,同时兼容标准格式的文件。
内容的提问来源于stack exchange,提问作者Duartinho Codes
相关产品推荐
相关产品推荐

