Reading an array from a file then writing it to another - arrays

I believe I have a problem with my structure pointer (head), but I'm not sure where I'm doing wrong. It reads the data from the file fine for the headercheck function so I have no clue if that's it or not. I would rather have the structure pointer global, because this is part of a very big program with switch case statements and all that, but it doesn't like that.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define maxheight 1080
#define maxwidth 1920
#define RGB_COMPONENT_COLOUR 255
#define pgmtype "P2"
#define ppmtype "P3"
typedef struct {
int x, y;
}
PPMImage;
typedef struct {
int rgb_comp_colour;
char filetype[2];
int height;
int width;
}
PPMHead;
/*PPMHead head[3];
{
head[3].filetype;
head[3].height;
head[3].width;
}
PPMHead *ptr_head = NULL;
ptr_head = head;*/
PPMPixel * data; //Defines pointer to PPMPixel
int ** Array; //Double pointer defines as a pointer pointing to a pointer that is pointing to an integer
PPMPixel ** RGBArray; //Double pointer defines as a pointer pointing to a pointer that is pointing to the PPMPixel structure
FILE * fp;
int r, g, b;
void headercheck() {
PPMHead * ptr_head, head;
ptr_head = & head;
fscanf(fp, "%s %d %d %d", head.filetype, & head.width, & head.height, & head.rgb_comp_colour);
printf("%s %d %d %d", head.filetype, head.width, head.height, head.rgb_comp_colour);
if (head.width > maxwidth || head.height > maxheight) {
printf("\tInvalid image size. The maximum value of image is 1920x1080.\n");
printf("\tImage size is %d x %d\n", head.width, head.height);
} else {
printf("\tImage size is valid\n");
printf("\tImage size is %d x %d\n", head.width, head.height);
}
if ((strcmp(head.filetype, pgmtype) != 0) && (strcmp(head.filetype, ppmtype) != 0)) {
printf("\tInvalid filetype\n");
} else {
if (strcmp(head.filetype, pgmtype) == 0) {
printf("\t File is PGM type image\n");
} else {
if (strcmp(head.filetype, ppmtype) == 0) {
printf("\t File is PPM type image\n");
}
}
}
if ((head.rgb_comp_colour == RGB_COMPONENT_COLOUR)) {
printf("\t Image is 8 bit\n");
} else {
if (head.rgb_comp_colour > RGB_COMPONENT_COLOUR) {
printf("Maximum bit-depth is 8 bits\n");
} else {
printf("\tImage is not 8 bit\n");
}
}
}
int main(void) {
PPMHead * ptr_head, head;
ptr_head = & head;
char fname[100];
printf("Enter file name: ");
scanf("%s", fname);
fseek(stdin, 0, SEEK_END);
fp = fopen(fname, "r");
if (fp == NULL) {
printf("\tError while opening the file\n");
} else {
printf("\tReading in %s\n", fname);
}
//Checking for comments
//Skip whitespace and comments
headercheck();
if (strcmp(head.filetype, pgmtype) == 0) {
printf("\tReading in PGM image...\n");
* Array = malloc(head.width * sizeof(int * )); //Points to malloc
for (int i = 0; i < head.width; i++) {
Array[i] = (int * ) malloc(head.height * sizeof(int));
if ((Array = NULL)) {
printf("Error allocating memory to the array");
} else {
printf("Memory allocated to the PGM array sucessfully");
}
}
for (int j = 0; j < head.height; j++) {
for (int i = 0; i < head.width; i++) {
fscanf(fp, "%3d ", & Array[i][j]); //Scans the address of Array[i][j]
}
}
}
fclose(fp);
//Save PPM Array Into New PPM File
FILE * pf;
int i, j;
char fname2[100];
printf("Enter file name: ");
scanf("%s", fname2);
fseek(stdin, 0, SEEK_END);
pf = fopen(fname2, "w");
if (pf == NULL) {
printf("\tError while opening the file\n");
} else {
printf("\tWriting in %s\n", fname2);
}
if (strcmp(head.filetype, pgmtype) == 0) {
for (j = 0; j < head.height; j++) {
fprintf(pf, "\n");
for (i = 0; i < head.width; i++) {
fprintf(pf, "%3d ", Array[i][j]);
//fprintf(pf, "%3d ", **(Array+j*head[0].width + i));
}
}
}
fclose(pf);
for (int i = 0; i < head.width; i++) {
free(Array[i]);
Array[i] = NULL;
}
free(Array);
Array = NULL;
return 0;
}

Related

Reading In PPM Pixels As RGB Integers

So my code involves reading in a PPM image and then storing it in an array so it can be saved in an new ppm file. Though I think there is a problem with my pointers that means its not actually reading the file. Also my code ends after allocating the memory for the array. Any help is much appreciated.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define maxheight 1080
#define maxwidth 1920
#define RGB_COMPONENT_COLOUR 255
#define pgmtype "P2"
#define ppmtype "P3"
typedef struct
{
int red, green, blue;
} PPMPixel;
typedef struct
{
int x, y;
} PPMImage;
typedef struct
{
int rgb_comp_colour;
char filetype[3];
int height;
int width;
} PPMHead;
/*PPMHead head[3];
{
head[3].filetype;
head[3].height;
head[3].width;
}*/
PPMHead head;
PPMHead* head_ptr = &head;
PPMPixel p;
PPMPixel* p_ptr = &p;
PPMPixel *data; //Defines pointer to PPMPixel
int **Array; //Double pointer defines as a pointer pointing to a pointer that is pointing to an integer
PPMPixel **RGBArray; //Double pointer defines as a pointer pointing to a pointer that is pointing to the PPMPixel structure
FILE *fp;
int r, g, b;
void headercheck ()
{
fscanf(fp, "%s %d %d %d", head.filetype, &head.width, &head.height, &head.rgb_comp_colour);
printf("%s %d %d %d", head.filetype, head.width, head.height, head.rgb_comp_colour);
if (head.width > maxwidth || head.height > maxheight)
{
printf("\tInvalid image size. The maximum value of image is 1920x1080.\n");
printf("\tImage size is %d x %d\n", head.width, head.height);
}
else
{
printf("\tImage size is valid\n");
printf("\tImage size is %d x %d\n", head.width, head.height);
}
if ((strcmp (head.filetype, pgmtype)!=0) && (strcmp (head.filetype, ppmtype)!=0))
{
printf("\tInvalid filetype\n");
}
else
{
if(strcmp (head.filetype, pgmtype)==0)
{
printf("\t File is PGM type image\n");
}
else
{
if(strcmp (head.filetype, ppmtype)==0)
{
printf("\t File is PPM type image\n");
}
}
}
if ((head.rgb_comp_colour == RGB_COMPONENT_COLOUR))
{
printf("\t Image is 8 bit\n");
}
else
{
if (head.rgb_comp_colour > RGB_COMPONENT_COLOUR)
{
printf("Maximum bit-depth is 8 bits\n");
}
else
{
printf("\tImage is not 8 bit\n");
}
}
}
int main(void)
{
char fname[100];
printf("Enter file name: ");
scanf("%s", fname);
fseek(stdin,0,SEEK_END);
fp = fopen(fname, "r");
if (fp == NULL)
{
printf("\tError while opening the file\n");
}
else
{
printf("\tReading in %s\n", fname);
}
headercheck();
if (strcmp (head.filetype, ppmtype)==0)
{
RGBArray = (PPMPixel **)malloc(head.height*sizeof(PPMPixel*)); //Points to malloc
if((RGBArray == NULL))
{
printf("Error allocating memory to the array");
}
else
{
printf("Memory allocated to the PPM array sucessfully");
}
for (int i=0;i<head.width;i++)
{
RGBArray[i] = (PPMPixel *)malloc(head.width*sizeof(PPMPixel));
}
printf("Error 2");
//Initialising each element
for (int j=0;j<head.height;j++)
{
for (int i=0;i<head.width;i++)
{
fscanf(fp, "%3d %3d %3d ", &p.red, &p.green, &p.blue); //Scans in integers of the address pointer to PPMPixel
data = &RGBArray[i][j]; //Defines data pointer pointing to address of RGBArray[i][j]
data->red = p.red; //Access member of PPMPixel structure to equal one of the three RGB channels
data->green = p.green;
data->blue = p.blue;
}
}
}
fclose(fp);
//Save PPM Array Into New PPM File
FILE *pf;
int i, j;
char fname2[100];
printf("Enter file name: ");
scanf("%s", fname2);
fseek(stdin,0,SEEK_END);
pf = fopen(fname2, "w");
if (pf == NULL)
{
printf("\tError while opening the file\n");
}
else
{
printf("\tWriting in %s\n", fname2);
}
for(j=0;j<head.height;j++)
{
fprintf(pf, "\n");
for(i=0;i<head.width;i++)
{
fprintf(pf, "%3d ", RGBArray[i][j].red);
fprintf(pf, "%3d ", RGBArray[i][j].green);
fprintf(pf, "%3d ", RGBArray[i][j].blue);
//fprintf(pf, "%3d ", (RGBArray+j*head.width + i)*r);
//fprintf(pf, "%3d ", (RGBArray+j*head.width + i)*g);
//fprintf(pf, "%3d ", (RGBArray+j*head.width + i)*b);
}
}
fclose(pf);
free(RGBArray);
RGBArray = NULL;
for(int i=0;i<head.width;i++)
{
free(RGBArray[i]);
RGBArray[i] = NULL;
}
return 0;
}
You mainly mixed width and height, but there are other issues.
width is the number of columns
height is the number of rows
The C two dimensional array in memory order is Row Major.
The convention for storing an image in memory is "by rows".
The indexing is RGBArray[col][row] (in your code it should be RGBArray[j][i]).
Illustration:
RGBArray[0][0] RGBArray[0][14]
| |
V V
<--- width --->
RGBArray[0] -> ############### ^
RGBArray[1] -> ############### |
RGBArray[2] -> ############### height
RGBArray[3] -> ############### |
RGBArray[4] -> ############### V
I used the following PPM text file for testing (in.ppm):
P3
# ppm comment
4 3
255
1 2 3 11 12 13 21 22 23 31 32 33
101 102 103 111 112 113 121 122 123 131 132 133
201 202 203 211 212 213 221 222 223 231 232 233
Corrected code (please read the comments):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define maxheight 1080
#define maxwidth 1920
#define RGB_COMPONENT_COLOUR 255
#define pgmtype "P2"
#define ppmtype "P3"
typedef struct
{
int red, green, blue;
} PPMPixel;
typedef struct
{
int x, y;
} PPMImage;
typedef struct
{
int rgb_comp_colour;
char filetype[3];
int height;
int width;
} PPMHead;
PPMHead head;
PPMHead* head_ptr = &head;
PPMPixel p;
PPMPixel* p_ptr = &p;
PPMPixel *data; //Defines pointer to PPMPixel
int **Array; //Double pointer defines as a pointer pointing to a pointer that is pointing to an integer
PPMPixel **RGBArray; //Double pointer defines as a pointer pointing to a pointer that is pointing to the PPMPixel structure
FILE *fp;
int r, g, b;
void headercheck()
{
char tmp[201]; //Temporary string.
fscanf(fp, "%2s", head.filetype); //%2s ensures that no more than two characters are read.
fscanf(fp, "%200s", tmp);
if (tmp[0] == '#')
{
//The second line may be a comment starting with '#'
fgets(tmp, 200, fp); //Skip the comment.
fscanf(fp, "%d", &head.width);
}
else
{
//If not a comment, read width from tmp.
sscanf(tmp, "%d", &head.width);
}
//fscanf(fp, "%s %d %d %d", head.filetype, &head.width, &head.height, &head.rgb_comp_colour);
fscanf(fp, "%d %d", &head.height, &head.rgb_comp_colour);
printf("%s %d %d %d", head.filetype, head.width, head.height, head.rgb_comp_colour);
if (head.width > maxwidth || head.height > maxheight)
{
printf("\tInvalid image size. The maximum value of image is 1920x1080.\n");
printf("\tImage size is %d x %d\n", head.width, head.height);
}
else
{
printf("\tImage size is valid\n");
printf("\tImage size is %d x %d\n", head.width, head.height);
}
if ((strcmp(head.filetype, pgmtype) != 0) && (strcmp(head.filetype, ppmtype) != 0))
{
printf("\tInvalid filetype\n");
}
else
{
if (strcmp(head.filetype, pgmtype) == 0)
{
printf("\t File is PGM type image\n");
}
else
{
if (strcmp(head.filetype, ppmtype) == 0)
{
printf("\t File is PPM type image\n");
}
}
}
if ((head.rgb_comp_colour == RGB_COMPONENT_COLOUR))
{
printf("\t Image is 8 bit\n");
}
else
{
if (head.rgb_comp_colour > RGB_COMPONENT_COLOUR)
{
printf("Maximum bit-depth is 8 bits\n");
}
else
{
printf("\tImage is not 8 bit\n");
}
}
}
int main(void)
{
const char *fname = "in.ppm";
//char fname[100];
//printf("Enter file name: ");
//scanf("%s", fname);
//fseek(stdin, 0, SEEK_END);
fp = fopen(fname, "r");
if (fp == NULL)
{
printf("\tError while opening the file\n");
}
else
{
printf("\tReading in %s\n", fname);
}
headercheck();
if (strcmp(head.filetype, ppmtype) == 0)
{
RGBArray = (PPMPixel **)malloc(head.height * sizeof(PPMPixel*)); //Points to malloc
if ((RGBArray == NULL))
{
printf("Error allocating memory to the array\n");
}
else
{
printf("Memory allocated to the PPM array successfully\n");
}
//for (int i = 0; i < head.width; i++)
for (int i = 0; i < head.height; i++) //Iterate height rows
{
RGBArray[i] = (PPMPixel *)malloc(head.width * sizeof(PPMPixel));
if ((RGBArray[i] == NULL))
{
printf("Error allocating memory to the array\n");
}
}
//printf("Error 2");
//Initializing each element
for (int j = 0; j < head.height; j++)
{
for (int i = 0; i < head.width; i++)
{
fscanf(fp, "%3d %3d %3d ", &p.red, &p.green, &p.blue); //Scans in integers of the address pointer to PPMPixel
//data = &RGBArray[i][j]; //Defines data pointer pointing to address of RGBArray[i][j]
data = &RGBArray[j][i]; //The row index comes first - (use [j][i] instead of [i][j])
data->red = p.red; //Access member of PPMPixel structure to equal one of the three RGB channels
data->green = p.green;
data->blue = p.blue;
}
}
}
fclose(fp);
//Save PPM Array Into New PPM File
FILE *pf;
int i, j;
//char fname2[100];
//printf("Enter file name: ");
//scanf("%s", fname2);
//fseek(stdin, 0, SEEK_END);
const char *fname2 = "out.ppm";
pf = fopen(fname2, "w");
if (pf == NULL)
{
printf("\tError while opening the file\n");
}
else
{
printf("\tWriting in %s\n", fname2);
}
//Write the PPM header
////////////////////////////////////////////////////////////////////////////
fprintf(fp, "%s\n", head.filetype);
fprintf(fp, "%d %d\n", head.width, head.height);
fprintf(fp, "%d\n", head.rgb_comp_colour);
////////////////////////////////////////////////////////////////////////////
for (j = 0; j < head.height; j++)
{
//fprintf(pf, "\n");
for (i = 0; i < head.width; i++)
{
//fprintf(pf, "%3d ", RGBArray[i][j].red);
//fprintf(pf, "%3d ", RGBArray[i][j].green);
//fprintf(pf, "%3d ", RGBArray[i][j].blue);
fprintf(pf, "%3d ", RGBArray[j][i].red); //row index comes first - use [j][i] instead of [i][j]
fprintf(pf, "%3d ", RGBArray[j][i].green);
fprintf(pf, "%3d ", RGBArray[j][i].blue);
}
fprintf(pf, "\n");
}
fclose(pf);
//free(RGBArray);
//RGBArray = NULL;
for (int i = 0; i < head.height; i++)
{
free(RGBArray[i]);
RGBArray[i] = NULL;
}
free(RGBArray); //Free RGBArray after free RGBArray[i]
RGBArray = NULL;
return 0;
}
Output file (out.ppm):
P3
4 3
255
1 2 3 11 12 13 21 22 23 31 32 33
101 102 103 111 112 113 121 122 123 131 132 133
201 202 203 211 212 213 221 222 223 231 232 233

Reading two dimensional array from file and printing it

I have some problems with my code. Everything is fine; gcc shows no errors or warnings; valgrind says no memory leaks, but my array isn't printed and I'm not sure why. Is fscanf() not working correctly or am I printing it incorrectly?
#include <stdio.h>
#include <stdlib.h>
int arrsize (FILE *file)
{
if (file == NULL) {
printf("Error: file pointer is null.");
return 0;
}
int sizer;
fscanf(file, "%d", &size);
return size;
}
int main()
{
int i = 0, j = 0, k = 0,a=0;
FILE *fp;
if ((fp = fopen("matrix.txt", "r")) == NULL)
{
printf("Error: file pointer is null.\n");
return 1;
}
int size = arrsize(fp);
printf("Array size is %d x %d \n", size, size);
double **array = (double **)malloc(size * sizeof(double *));
for (i; i < size; i++)
array[i] = (double *)malloc(size * sizeof(double));
for (i; i < size; i++)
{
for (j = 0; j < size; j++)
{
fscanf(fp, " %lf", &array[i][j]);
printf(" %lf ",array[i][j]);
}
}
for (k ; k < size; k++) {
free(array[k]);
}
free(array);
fclose(fp);
return 0;
}
Check the return of fscanf and malloc to make sure of success.
Add fflush ( stdout); to the print loops since the format string does not have a newline.
#include <stdio.h>
#include <stdlib.h>
int arrsize (FILE *file)
{
if (file == NULL) {
printf("Error: file pointer is null.");
return 0;
}
int size;
if ( 1 == fscanf(file, "%d", &size)) {
return size;
}
return -1;
}
int main()
{
int i = 0, j = 0, k = 0;
FILE *fp;
if ((fp = fopen("matrix.txt", "r")) == NULL)
{
printf("Error: file pointer is null.\n");
return 1;
}
int size = arrsize(fp);
if ( -1 == size) {
fprintf( stderr, "Error: problem parsing array size.\n");
return 1;
}
printf("Array size is %d x %d \n", size, size);
double **array = NULL;
if ( NULL != ( array = malloc(size * sizeof(double *)))) {
for (i = 0; i < size; i++) {
if ( NULL == ( array[i] = malloc(size * sizeof(double)))) {
fprintf ( stderr, "problem allocation array[]\n");
while ( i) {
i--;
free ( array[i]);
}
free ( array);
return 1;
}
}
}
else {
fprintf ( stderr, "problem allocation array\n");
return 1;
}
for (i = 0; i < size; i++)
{
for (j = 0; j < size; j++)
{
if ( 1 == fscanf(fp, "%lf", &array[i][j])) {
printf(" %lf ",array[i][j]);
}
else {
fprintf ( stderr, "problem parsing double\n");
break;
}
}
fflush ( stdout);
}
for (k = 0; k < size; k++) {
free(array[k]);
}
free(array);
fclose(fp);
return 0;
}

Rotate bmp image in C

I'm rotating a bmp image file in C.
I successfully tested copying image(rotate 0 degree). But, It must be a problem in rotating image. Here is my code
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<string.h>
#pragma warning (disable:4996)
#define FILENAMELENGTH 30
#define MAXROW 512
#define MAXCOL 512
//location of pixels
typedef struct
{
int row;
int col;
}COORDI;
//function declarations
void RotatePixel(float Theta, COORDI org, COORDI before, COORDI* after);
void ReadImage(char* original_image);
void WriteImage(char* rotate_image);
char source[MAXROW][MAXCOL];
char dest[MAXROW][MAXCOL];
COORDI org;
float Theta;
int main(void)
{
char original_image[FILENAMELENGTH];
char rotate_image[FILENAMELENGTH];
printf("image name : ");
scanf("%s", original_image);
//rotate angle(radian)
printf("angle : ");
scanf("%f", &Theta);
printf("after rotate file name : ");
scanf("%s", rotate_image);
org.row = MAXROW / 2;
org.col = MAXCOL / 2;
dest[MAXROW][MAXCOL] = { 0, };
ReadImage(original_image);
WriteImage(rotate_image);
printf("rotate completed!\n");
return 0;
}
void ReadImage(char* original_image)
{
FILE* fp;
int i, j;
fp = fopen(original_image, "rb");
if (fp == NULL)
{
printf("File cannot open\n");
exit(-1);
}
for (i = 0; i < MAXROW; i++)
{
for (j = 0; j < MAXCOL; j++)
fread(&source[i][j], sizeof(unsigned char), 1, fp);
}
printf("image read completed !\n");
fclose(fp);
return;
}
//writing a pixel to file
void WriteImage(char* rotate_image)
{
FILE* fp;
int i, j;
COORDI locn;
COORDI* after = (COORDI*)malloc(sizeof(COORDI));
fp = fopen(rotate_image, "wb");
if (fp == NULL)
{
printf("File cannot open\n");
exit(-1);
}
for (i = 0; i < MAXROW; i++)
{
for (j = 0; j < MAXCOL; j++)
{
locn.row = i;
locn.col = j;
RotatePixel(Theta, org, locn, after);
if (after->col < 0) continue;
if (after->row < 0) continue;
if (after->col >= MAXCOL) continue;
if (after->row >= MAXROW) continue;
dest[after->row][after->col] = source[i][j];
putc(dest[after->row][after->col], fp);
}
}
printf("image write completed !\n");
fclose(fp);
return;
}
//rotate pixels
void RotatePixel(float Theta, COORDI org, COORDI before, COORDI* after)
{
int x, y;
x = before.col - org.col;
y = before.row - org.row;
after->col = (int)(x* cos(Theta) - y*sin(Theta)) + org.col; // x
after->row = (int)(x* sin(Theta) + y*cos(Theta)) + org.row; // y
}
I think writing a pixel to file is a problem. where is the missing point?

Reading a dynamic array from a file with function

I have the following code:`
#include <stdio.h>
#include <stdlib.h>
void load_from_file(int A[], int *n);
int main()
{
int *A;
A = (int*)malloc(0);
int count = 0;
int i;
load_from_file(A, &count);
for(i = 0; i < count; i++)
{
printf("A[%d]=%d ", i, A[i]);
printf("\n");
printf("&A[%d]=%p \n\n", i, &A[i]);
}
return 0;
}
void load_from_file(int A[], int *n)
{
FILE* fp;
int temp, i;
fp = fopen("data.txt", "r");
if (fp == NULL)
{
printf("error!!");
exit (1);
}
fscanf(fp, "%d", &temp);
*n = temp;
A = (int*) realloc(A, temp * sizeof(int));
if (*A == NULL)
{
printf("error realloc!!");
exit(1);
}
for(i = 0; i < temp; i++)
{
fscanf(fp, "%d", &A[i]);
}
for(i = 0; i < temp; i++)
{
printf("A[%d]=%d ", i, A[i]);
printf("\n");
printf("&A[%d]=%p \n\n", i, &A[i]);
}
fclose(fp);
}
I'm trying to read a text file into an array.
First line of the file has the number of elements of the array, and second line the numbers-elements.
We create the array through realloc.
But something is going wrong.....
I have some patches, printing the address of array's elements.
But unfortunatelly they are different(not all the times) inside the function, and outside the function, although an array is passed by reference (as I think...)
Please, tell me where is the mistake, and how can I fix the problem.
Thanks in advance...
Dimitri
Call:
int *A = load_from_file(&count);
Function:
int *load_from_file(int *n)
{
FILE* fp;
int temp,i;
int *A = 0;
fp=fopen("data.txt","r");
if (fp==NULL){fprintf(stderr, "error!!\n");exit (1);}
fscanf(fp,"%d",&temp);
*n=temp;
A = (int*) realloc(A,temp * sizeof(int));
if (A == NULL) {fprintf(stderr, "error realloc!!\n");exit(1);}
for(i=0;i<temp;i++)
fscanf(fp, "%d",&A[i]);
for(i=0;i<temp;i++)
{
printf("A[%d]=%d ",i,A[i]);
printf("\n");
printf("&A[%d]=%p \n\n",i,&A[i]);
}
fclose(fp);
return A;
}
This is a totally minimal set of changes; the code needs a lot more work. In particular, the fscanf() calls should be error checked. There's a subtle but important change in the allocation test: if (A == NULL) rather than the original if (*A == NULL).
With somewhat more complete error checking:
int *load_from_file(int *n)
{
FILE *fp;
int temp, i;
int *A = 0;
const char file[] = "data.txt";
fp = fopen(file, "r");
if (fp == NULL)
{
fprintf(stderr, "Failed to open file %s for reading\n", file);
exit(1);
}
if (fscanf(fp, "%d", &temp) != 1)
{
fprintf(stderr, "Failed to read number of entries\n");
exit(1);
}
*n = temp;
A = (int *) realloc(A, temp * sizeof(int));
if (A == NULL)
{
fprintf(stderr, "Failed to reallocate %zu bytes of memory\n",
temp * sizeof(int));
exit(1);
}
for (i = 0; i < temp; i++)
{
if (fscanf(fp, "%d", &A[i]) != 1)
{
fprintf(stderr, "Failed to read entry number %d\n", i);
exit(1);
}
}
for (i = 0; i < temp; i++)
printf("A[%d]=%d: &A[%d]=%p\n", i, A[i], i, &A[i]);
fclose(fp);
return A;
}
I have a library of error reporting functions that I use which would reduce the error handling from 4 lines to 1 line per error. I strongly recommend creating and using such a library for yourself.

fscanf() doesn't want to read values after the first two are read

Basically, I'm reading a bunch of values from a text file, which has them in the following layout:
4 1 1 2 3 4
But the following block of code doesn't want to read the double type value following the first two int type values:
int matrix_read(struct matrep *mat, const char *filename)
{
FILE *fptr;
unsigned m, n;
double *ptr = NULL;
int i, j;
double x;
if ((fptr = fopen(filename, "r")) == NULL)
{
fprintf(stderr, "Cannot Open File %s\n", filename);
return -1;
}
if(fscanf(fptr, "%u", &m) != 1)
{
fprintf(stderr, "Failed to read number of rows\n");
return -1;
}
if(fscanf(fptr, "%u", &n) != 1)
{
fprintf(stderr, "Failed to read number of columns\n");
return -1;
}
mat->matrix = (double *)malloc(sizeof(double) * m * n);
if (mat->matrix == 0)
{
fprintf(stderr, "Failed to allocate %d*%d matrix\n", m, n);
return -1;
}
ptr = mat->matrix;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
double x;
if (fscanf(fptr, "%f", &x) != 1)
{
fprintf(stderr, "Failed to read element matrix[%d,%d]\n", i, j);
free(mat->matrix);
mat->matrix = 0;
mat->cols = 0;
mat->rows = 0;
return -1;
}
*ptr++ = x;//Here it reads nothing, it just gives me: -9.2559604281615349e+061
}
}
fclose(fptr);
mat->cols = m;
mat->rows = n;
return 0; // Success
}
What am I doing wrong?
fscanf(fptr, "%f", &x)
For scanning doubles, you need the %lf format. %f scans a float. Using the wrong format invokes undefined behaviour, what probably happens is that the scanned value is converted to a float and then stored in the first four bytes of the pointed-to double.

Resources