所以我必须以PPM格式读取此图像,然后将其写入另一个文件。 它可以工作,但是如果图像有注释,它将停止工作。 如果图像如下所示:
P3
3 2
255
255 0 0
0 255 0
0 0 255
255 255 0
255 255 255
0 0 0
它可以工作,但如果图像是这样的:
P3
3 2
255
# "3 2" is the width and height of the image in pixels
# "255" is the maximum value for each color
# The part below is image data: RGB triplets
255 0 0 # red
0 255 0 # green
0 0 255 # blue
255 255 0 # yellow
255 255 255 # white
0 0 0 # black
它停止工作。 我真的不知道为什么,因为我已经编程为忽略评论。 我将在下面保留代码,也许有人可以提供帮助。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
typedef struct pixel {
unsigned int r,g,b;
} pixel;
typedef struct imagem{
int cols,rows;
char mnumber[2];
int maxcolor;
pixel *matrix;
}imagem;
static imagem read(const char *filename)
{
imagem img;
FILE *f;
f = fopen(filename,"rb");
if(f == NULL) {
scanf("%c %c",&img.mnumber[0],&img.mnumber[1]);
scanf("%d %d",&img.cols,&img.rows);
scanf("%d",&img.maxcolor);
img.matrix = (pixel*) malloc(img.cols*img.rows*sizeof(pixel));
for(int i = 0; i < img.cols*img.rows;i++)
{
scanf("%u %u %u",&img.matrix[i].r,&img.matrix[i].g,&img.matrix[i].b);
}
} else {
int i = 0;
while(i != 2)
{
img.mnumber[i] = getc(f);
//printf("%cn",(char) img.mnumber[i]);
i++;
}
int c = getc(f);
while (c == '#') {
while (getc(f) != 'n') {
getc(f);
}
c = getc(f);
}
ungetc(c, f);
fscanf(f,"%d %d",&img.cols,&img.rows);
fscanf(f,"%d",&img.maxcolor);
img.matrix = (pixel*)malloc(img.cols * img.rows* sizeof(pixel));
for(int i = 0; i < img.cols*img.rows;i++)
{
fscanf(f,"%u %u %u",&img.matrix[i].r,&img.matrix[i].g,&img.matrix[i].b);
}
fclose(f);
return img;
}
return img;
}
我会这样写:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
typedef struct pixel {
unsigned int r,g,b;
} pixel;
typedef struct imagem{
int cols, rows;
char mnumber[2];
int maxcolor;
pixel *matrix;
} imagem;
static imagem read(const char *filename)
{
imagem img;
FILE *f;
int i;
char buf[BUFSIZ];
if (filename == NULL) {
f = stdin;
} else {
f = fopen(filename, "r");
if (f == NULL) {
fprintf(stderr, "Can't open %sn", filename);
exit(1);
}
}
if (fgets(buf, sizeof buf, f) == NULL) {
fprintf(stderr, "Can't read datan");
exit(1);
}
for (i = 0; i < 2; i++) {
img.mnumber[i] = buf[i];
}
if (fgets(buf, sizeof buf, f) == NULL) {
fprintf(stderr, "Can't read datan");
exit(1);
}
sscanf(buf, "%d %d", &img.cols, &img.rows);
if (fgets(buf, sizeof buf, f) == NULL) {
fprintf(stderr, "Can't read datan");
exit(1);
}
sscanf(buf, "%d", &img.maxcolor);
img.matrix = malloc(img.cols * img.rows * sizeof(pixel));
if (img.matrix == NULL) {
fprintf(stderr, "malloc failedn");
exit(1);
}
i = 0;
while (fgets(buf, sizeof buf, f) != NULL) {
if (buf[0] == '#') continue;
else {
sscanf(buf, "%u %u %u", &img.matrix[i].r, &img.matrix[i].g, &img.matrix[i].b);
i++;
}
} fclose(f);
return img;
}
- 正如建议的那样,最好使用
fgets()
和sscanf()
而不是fscanf()
,尤其是当我们需要处理不规则的线条时。 - 您不必编写特定的代码来读取
stdin
当 省略文件名。只需将文件指针f
分配给stdin
即可。 - 建议将函数名称
read()
更改为其他名称 因为它与现有的系统调用函数冲突read(2)
。