我正在尝试制作一个读取文本文件的程序。文本文件包含代表 rgb 数字的数字。 test.txt 示例:
P3
3 4
255
12 32 222 12 32 222 12 32 222 12 32 222 12 32 222 12 32 222 12 32 222
12 32 222 12 32 222 12 32 222 12 32 222 12 32 222
模拟 PPM 文件。然后我忽略第一行,读取以下三个整数用于以后的计算。我一直在测试的不正常行为是尝试将以下数字存储在结构类型 RGB 的数组中,该数组包含三个类型为 unsigned char 的元素:r、g、b。我不明白的是,当我尝试打印前几个元素时,我的第一个像素(第一个结构,第一个 r、g、b)是正确的,然后,接下来的三个数字是随机的,之后的每次执行都会生成那个用随机数设置。其余为零。我虽然我的理解是正确的,但有人可以帮助我吗?代码:
#include filter.h
#include <stdio.h>
#include <stdlib.h>
RGB *readPPM(const char *file, int *width, int *height, int *max)
{
width = malloc(sizeof(int)*10);
height = malloc(sizeof(int)*10);
max = malloc(sizeof(int)*3);
FILE *fp;
int numOfPix, i=0;
char garbage[3];
if ((fp = fopen(file,"r")) == NULL)
{
printf("No such file exists!");
}
fgets(garbage,sizeof(garbage),fp);
fscanf(fp,"%d %d %d",width,height,max);
int numofPix = (*width) * (*height);
RGB pixels[numOfPix];
RGB *returnptr = pixels;
printf("w: %d h: %d m: %d pix: %d\n",*width,*height,*max,numofPix);
while (!feof(fp))
{
fscanf(fp,"%hhd %hhd %hhd", &pixels[i].r, &pixels[i].g, &pixels[i].b);
i++;
}
fclose(fp);
return returnptr;
}
int main()
{
RGB *RGBValues;
int *width, *height, *max;
int j=0;
char *testfile = "test.txt";
RGBValues = readPPM(testfile,width,height,max);
for(j=0;j<5;j++)
{
printf("r: %d g: %d b: %d\n",RGBValues[j].r,RGBValues[j].g,RGBValues[j].b);
}
}
filter.h中的结构体定义:
typedef struct { unsigned char r, g, b; } RGB;
示例输出:
w: 3 h: 4 m: 255 pix: 12 //Correct
r: 12 g: 32 b: 222 //Correct
r: 232 g: 253 b: 85 //Changes every execution
r: 0 g: 0 b: 19 //Static
r: 0 g: 0 b: 0 //Static
r: 0 g: 0 b: 0 //Static
最佳答案
您正在声明指针 int *width, *height, *max;
并将它们传递给 readPPM
。然后在 readPPM
中放置
width = malloc(sizeof(int)*10);
height = malloc(sizeof(int)*10);
max = malloc(sizeof(int)*3);
这些 malloc
分配为 width
、height
、max
创建整数数组。显然,创建宽度和高度数组不是您的意图。不要那样做。只需声明整数并传递地址。
也不要使用while(feof(fp))
,而是检查fscanf
的返回值,如果fscanf
则中断循环> 失败。
正如评论中所指出的,RGB pixels[numOfPix]
在函数退出时被销毁。在这种情况下,请对 RGB *pixels
使用 malloc
。这将在堆上创建内存,函数退出时它不会被销毁。您稍后必须释放该内存。
RGB *readPPM(const char *file, int *ptr_width, int *ptr_height, int *ptr_max)
{
int width, height, max;
FILE *fp;
int numOfPix, i = 0;
char garbage[3];
if((fp = fopen(file, "r")) == NULL)
{
printf("No such file exists!");
}
fgets(garbage, sizeof(garbage), fp);
fscanf(fp, "%d %d %d", &width, &height, &max);
int numofPix = width * height;
RGB *pixels = malloc(numofPix * sizeof(RGB));
printf("w: %d h: %d m: %d pix: %d\n", width, height, max, numofPix);
while(fscanf(fp, "%d %d %d", &pixels[i].r, &pixels[i].g, &pixels[i].b) == 3)
{
i++;
}
fclose(fp);
*ptr_width = width;
*ptr_height = height;
*ptr_max = max;
return pixels;
}
int main()
{
RGB *RGBValues;
int width, height, max;
int j = 0;
char *testfile = "test.txt";
//pass the address of width, height, and max
RGBValues = readPPM(testfile, &width, &height, &max);
for(j = 0; j<5; j++)
{
printf("r: %d g: %d b: %d\n", RGBValues[j].r, RGBValues[j].g, RGBValues[j].b);
}
//width, height, max should be modified:
printf("%d %d %d\n", width, height, max);
//free the memory which was allocated in `readPPM`
free(RGBValues);
}
关于c - 尝试将输入存储在具有意外行为的结构类型数组中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47544272/