提问人:Duartinho Codes 提问时间:11/4/2023 最后编辑:genpfaultDuartinho Codes 更新时间:11/5/2023 访问量:101
在 C 中读取文件时,我可以忽略以“#”开头的行吗?
Can I ignore a line started with "#" while reading a file in 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;
}
这就是我正在阅读的文件:
P1
5 3
0 0 1 0 1
0 0 1 1 0
1 1 0 0 0
但在某些情况下,文件可以有注释行,如下所示:
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
我怎样才能插入这些线条?(注释始终介于“P1”和尺寸之间)。
我尝试在以下代码中使用最大行大小 (2047) 的缓冲区:
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;
}
}
答:
0赞
SmellyCat
11/4/2023
#1
完成这些调用后,您需要检查缓冲区,以防它不是注释行。你这样做,而不是在不支持注释时使用。fgets
scanf
fscanf
char line[2047];
while (fgets(line, sizeof(line), arq) != NULL)
{
char *hash = strchr(line, '#'); /* You might be able to combine this line into the if-statement. */
if (hash != NULL)
continue; /* comment line */
sscanf(line, "%d %d", col, lin);
printf("%d %d\n", *lin, *col);
int **mat = ....
评论
0赞
chux - Reinstate Monica
11/4/2023
这将跳过包含 的行,即使不是第一个字符。OP 的目标是<忽略以“#”开头的行>'#'
0赞
stark
11/4/2023
您没有检查 sscanf 的返回值。
1赞
Duartinho Codes
11/5/2023
#2
以下代码解决了我的问题。感谢 Chux 建议仅使用 、YuWea 进行缓冲区大小校正,以及 Jonathan Leffler 建议 和 。fgets()
sscanf()
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;
}
评论
2048
\0
sscanf()
来处理该行。continue
break