我对 C 语言相当陌生,我的任务是创建一个读取图像并显示该图像的程序。我创建了(我认为是)一个函数来读取文件格式/注释等,并尝试创建一个函数来显示每个像素的 RGB 值。
我无法测试它,因为我的程序中有一个错误 - “getPPM 类型冲突”。谁能解释一下为什么我会收到此错误?任何可能的修复都会很棒。
如果有人可以建议一种能够存储评论(也许在数组中?)并稍后打印它们的方法,那也会非常有帮助!谢谢。
也请随意检查整个程序并向我提供反馈,我不完全确定一旦修复上述错误它是否会真正执行任何操作。 非常感谢!
#include <stdio.h>
#include <stdlib.h>
#define MAX_HEIGHT 600
#define MAX_WIDTH 400
int main(int argc, char ** argv){
// get image file
FILE *file;
file = fopen("aab(1).ppm", "r");
//if there is no file then return an error
if(file == NULL){
fprintf(stderr, "File is not valid");
return 0;
}
else {
struct PPM *newPPM = getPPM(file);
return 0;
}
}
struct PPM {
char format[2]; //PPM format code
int height, width; //image pixel height and width
int max; //max rgb colour value
} PPM;
struct PPM_Pixel {
//Create variables to hold the rgb pixel values
int red, green, blue;
} PPM_Pixel;
struct PPM *getPPM(FILE * fd){
struct PPM *image;
char buffer[16];
char c;
char commentArray[256];
fd = fopen(fd, "r");
struct PPM *newPPM = malloc(sizeof(PPM));
//checks if the file being read is valid/the correct file
if(fd == NULL){
exit(1);
}
//read the image of the format
if(!fgets(buffer, sizeOf(buffer), fd)){
exit(1);
}
//checks the format of the ppm file is correct
if(buffer[0] != 'P' || buffer[1] != '3'){
fprintf(stderr, "Invalid image format! \n");
exit(1);
}else {
printf("%s", newPPM->format);
}
//allocate memory for the image
image = malloc(sizeof(PPM));
if(!image){
fprintf(stderr, "Cannot allocate memory");
exit(1);
}
//checks whether the next character is a comment and store it in a linked list
c = getc(fd);
while(c == '#'){
while(getc(fd) != '\n'){
c = getc(fd);
}
}
if(fscaf(fd, "%d %d", &image->height, &image->width)!= 2){
fprintf(stderr, "Size of image is invalid");
exit(1);
}
fclose(fd);
return newPPM;
};
showPPM(struct PPM * image){
//two-dimensional array to show the rows and columns of pixels.
int rgb_array[MAX_HEIGHT][MAX_WIDTH];
int i;
int j;
for(i = 0; i<MAX_HEIGHT; i++){
for(j = 0; j<MAX_WIDTH; j++){
printf("%d", rgb_array[i][j]);
}
}
};
最佳答案
下面的代码
- 包含大量关于错误和/或如何纠正的评论
- 执行适当的错误检查
- 更正了一些函数签名
- 为每个函数正确声明原型(prototype)
- 纠正了一些“按键”错误
- 更正“语法”错误
- 将结构定义移至首次引用这些定义之前
警告:此代码无法解决访问 PPM 图像文件的问题。
警告:此代码仍然不会将 malloc 的内存区域传递给 free()
,因此仍然需要添加这些语句。
#include <stdio.h>
#include <stdlib.h>
#define MAX_HEIGHT 600
#define MAX_WIDTH 400
// 1) giving the struct tag name the same as an instance name is a bad idea
// 2) good programming practice is to define a struct separately
// from the instance of that struct
struct PPM
{
char format[2]; //PPM format code
int height, width; //image pixel height and width
int max; //max rgb colour value
};
struct PPM myPPM;
struct PPM_Pixel
{
//Create variables to hold the rgb pixel values
//int red, green, blue;
// follow the axiom:
// only one statement per line and (at most) one variable declaration per statement
int red;
int green;
int blue;
};
struct PPM_Pixel myPPM_Pixel;
// prototypes
struct PPM *getPPM(FILE * fp);
void showPPM(struct PPM * image);
// this line will cause the compiler to raise two warnings
// about unused variable 'argc' and 'argv'
//int main(int argc, char ** argv)
int main( void )
{
// get image file
//FILE *file;
//file = fopen("aab(1).ppm", "r");
//if there is no file then return an error
//if(file == NULL)
FILE *fp == NULL;
if( NUL == (fp = fopen("aab(1).ppm", "r") ) )
{
//fprintf(stderr, "File is not valid");
// should include system error message
perror( "fopen for read of aab(1).ppm failed" );
//return 0;
// need to indicate an error occurred
exit( EXIT_FAILURE );
}
// implied else, fopen was successful
// following statement will raise a compiler warning
// about: 'set but not used variable'
struct PPM *newPPM = getPPM(fp);
fclose( fp ); // moved to here from 'getPPM()'
} // end function: main
struct PPM *getPPM(FILE * fp)
{
struct PPM *image;
char buffer[16];
//char c;
// the returned value from 'getc()' is an integer, not a character
int c;
char commentArray[256];
// following line is nonsence and the passed in parameter is already open
//fd = fopen(fd, "r");
// when allocating memory, always check the returned value
// to assure the operation was successful
struct PPM *newPPM = NULL;
if( NULL == (newPPM = malloc( sizeof struct PPM ) ) )
{
perror( "malloc for struct PPM failed" );
exit( EXIT_FAILURE );
}
// implied else, malloc successful
// already done in main()
//checks if the file being read is valid/the correct file
//if(fd == NULL){
// exit(1);
//}
//read the image of the format
if(!fgets(buffer, sizeOf(buffer), fd)){
exit(1);
}
//checks the format of the ppm file is correct
if(buffer[0] != 'P' || buffer[1] != '3'){
fprintf(stderr, "Invalid image format! \n");
exit( EXIT_FAILURE );
}
// implied else, file format correct
printf("%s", newPPM->format);
//allocate memory for the image
// note: there is no item named 'PPM'
// image = malloc(sizeof(PPM));
//if(!image){
// best to keep things together
if( NULL == (image = malloc( sizeof struct PPM ) ) )
{
//fprintf(stderr, "Cannot allocate memory");
// should include the OS message for the failure
perror( "malloc for struct PPM failed" );
exit( EXIT_FAILURE );
}
// implied else, malloc successful
// the following code does not store a comment in a linked list
// and
// skips over 1/2 the characters in the line due to the double call
// to 'getc()' in the inner while loop
//checks whether the next character is a comment and store it in a linked list
//c = getc(fd);
//while(c == '#'){
// while(getc(fd) != '\n'){
// c = getc(fd);
// }
//}
// this line does not compile! did you actually mean to call: 'fscanf()'?
//if(fscaf(fd, "%d %d", &image->height, &image->width)!= 2)
if( 2 == fscanf( fp, "%d %d", &image->height, &image->width) )
{
// next line NOT true, what actually happened is the call to 'fscanf()' failed
//fprintf(stderr, "Size of image is invalid");
perror( "fscanf for image height and width failed" );
exit( EXIT_FAILURE );
}
// implied else, fscanf successful
// best practice to close a file, where it was opened.
//fclose(fd);
return newPPM;
//}; do not follow a function definition with a semicolon
}
// Note: the following function is never called
// showPPM(struct PPM * image) each function signature needs a return type, even if 'void'
void showPPM(struct PPM * image)
{
// Note: PPM images have the number of pixels in each row rounded up to a multiple of 4
// but this posted code fails to handle that
//two-dimensional array to show the rows and columns of pixels.
// bad idea, suggest passing the (already input) width and height
// and use those passed in values to define the array sizes
int rgb_array[MAX_HEIGHT][MAX_WIDTH];
int i;
int j;
for(i = 0; i<MAX_HEIGHT; i++)
{
for(j = 0; j<MAX_WIDTH; j++)
{
printf("%d", rgb_array[i][j]);
}
}
// }; do not follow a function definition with a semicolon
}
关于c - 在C中显示ppm图像的rgb值和冲突类型错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35326911/