I have came across a problem that while reading from a file, I couldn't give my variables a proper value.
I have used a similar approach at a previous project, the only difference is that there I was only supposed to store the height and width of a matrix, and now I also have to store an additional line before I can store the height and width values.
Code:
int fromMountain = 0, fromWater = 0, fromSand = 0, height = 0, width = 0;
char **terrain;
void readFiles() {
inFile = fopen("be.txt", "r");
outFile = fopen("ki.txt", "w");
}
void storeData() {
fscanf(inFile, "%d %d %d\n", &fromMountain, &fromWater, &fromSand);
fscanf(inFile, "%d %d\n", &height, &width);
terrain = (char**)malloc(height*sizeof(char*));
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
fscanf(inFile, "%c", &terrain[i][j]);
}
}
}
void testPrint() {
printf("%d %d %d\n", fromMountain, fromWater, fromSand);
printf("%d %d\n", height, width);
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
printf("%c", terrain[i][j]);
}
printf("\n");
}
}
Output:
Code doesn't seem to run properly, there is no output.
Source file:
1 2 2
10 10
~00000000A
00000000AA
00~~~A00XX
000~0A0000
000000000~
A00000000~
000000000~
0000~00000
00000X0000
0A0A000AAA
I have tried changing things up a bit and make my integer variables char type.
That didn't seem to help anything, nothing has changed. Output was still non-existent and I got nowhere closer to a proper solution.
Any form of help is appreciated! :)
Alright, so here's the thing, anyone looking for something similar.
It is not enough to allocate memory for your variable, **terrain in this case, you also have to allocate a piece of memory for the data you would like to store.
After allocating memory for the variable itself, you will need another piece of code, something similar to this:
for (int i = 0; i < height; i++) {
terrain[i] = (char*)malloc(width * sizeof(char));
}
Thanks for Raildex for pointing it out!
Related
I'm building a program that is saving information on a matrix of Pixels (a struct). A pixel must have its color (another struct) the color is a struct with three integers (red=vermelho, green=verde and blue=azul). But when I set them their value change right after the end of the for.
For example, if I put the value 250 on all the red attributes of pixels it somehow changes if I print them after the for is finished if I print them while the for is running the values are right.
I'm also reading the information of the value of the red, green and blue values of a file, but I printed them and they are right.
Bellow are the functions that I'm using, and I'm having problems in the function clear from it I'm getting "250 0 0" (the right value) for all the pixels inside the for but the values change being sometimes "250 0 0", "0 250 0" and "250 250 0" in the second for inside the clear function.
I've tried printing all the variables, but it seems they somehow magically change after I set them in the first for. I'm not really experienced at C so I'm really lost right now.
typedef struct cor{
int vermelho;
int verde;
int azul;
} Cor;
typedef struct pixel{
Cor cordopixel;
} Pixel;
typedef struct imagem{
Pixel **pintura;
int largura;
int altura;
} Imagem;
void image(FILE *pont_arq, Imagem *desenho){
int i, j, k;
fscanf(pont_arq, "%d %d", &i, &j);
desenho->altura = j; //value equals 400
desenho->largura = i; //value equals 600
printf("Cria imagem %dx%d\n", i, j);
desenho->pintura = calloc(i, sizeof(Pixel*));
for (k = 0; k < i; ++k){
desenho->pintura[k] = calloc(j, sizeof(Pixel));
}
printf("Saiu\n");
}
int* lerIntArquivo(FILE *pont_arq, int inicio, int vezes, int val[]){
if(vezes==inicio-1){
fscanf(pont_arq, "%d", &val[inicio]);
return val;
}else{
fscanf(pont_arq, "%d", &val[inicio]);
lerIntArquivo(pont_arq, inicio+1,vezes, val);
}
}
void clear(FILE *pont_arq, Imagem *desenho){
int val[3], i, j;
lerIntArquivo(pont_arq, 0, 3, val);
printf("Cria imagem");
printf("%d %d %d\n",val[0],val[1], val[2]); //val[0]=250 val[1]=0 val[2]=0
//this for is printing the right values
for (i = 0; i < desenho->altura; ++i){
for (j = 0; j < desenho->largura; ++j){
printf("%d %d\n",i,j);
desenho->pintura[i][j].cordopixel.vermelho = val[0];//setting the values
desenho->pintura[i][j].cordopixel.verde = val[1];//setting the values
desenho->pintura[i][j].cordopixel.azul = val[2];//setting the values
printf("%d ", desenho->pintura[i][j].cordopixel.vermelho);
printf("%d ", desenho->pintura[i][j].cordopixel.verde);
printf("%d\n", desenho->pintura[i][j].cordopixel.azul);
}
}
//this for is not printing the right values
for (i = 0; i < desenho->altura; ++i){
for (j = 0; j < desenho->largura; ++j){
printf("%d ", desenho->pintura[i][j].cordopixel.vermelho);
printf("%d ", desenho->pintura[i][j].cordopixel.verde);
printf("%d\n", desenho->pintura[i][j].cordopixel.azul);
}
}
printf("\n");
}
There were no error messages, just wrong values.
When you allocate memory for your image the value of largura is the first size of the 2D array and the value of altura is its second size
desenho->altura = j;
desenho->largura = i;
...
desenho->pintura = calloc(i, sizeof(Pixel*));
for (k = 0; k < i; ++k){
desenho->pintura[k] = calloc(j, sizeof(Pixel));
}
I.e. you create an array of [largura][altura] size.
But when you latter work with the array you suddenly reverse their roles
for (i = 0; i < desenho->altura; ++i){
for (j = 0; j < desenho->largura; ++j){
...
desenho->pintura[i][j]
I.e. you access it as a [altura][largura] array, which is incorrect.
At some step you managed to swap the values. Most likely, when you allocated the image memory it was supposed to be
desenho->altura = i;
desenho->largura = j;
not the other way around.
I'm trying to read in the data from a .bmp image file so that I can manipulate it. However, after I read in the data I get two problems that I feel are related. Firstly, on the call of fclose() I get a sigabrt, and secondly, if I simply comment out the fclose() all the data I read into the structure array is set to 255 even though it was read-in correctly earlier. I'm pretty new to C so this is almost certainly rookie mistake with allocating dynamic memory.
Pixel** readFile(FILE* fp,Header* header,InfoHeader* infoHeader)
{
if(fp == NULL)
{
printf("file not found\n");
return NULL;
}
fread(&header->Type,SHORTSIZE,1,fp);
fread(&header->Size,INTSIZE,1,fp);
fread(&header->Reserved1,SHORTSIZE,1,fp);
fread(&header->Reserved2,SHORTSIZE,1,fp);
fread(&header->Offset,INTSIZE,1,fp);
fread(&infoHeader->Size,INTSIZE,1,fp);
fread(&infoHeader->Width,INTSIZE,1,fp);
fread(&infoHeader->Height,INTSIZE,1,fp);
fread(&infoHeader->Planes,SHORTSIZE,1,fp);
fread(&infoHeader->Bits,SHORTSIZE,1,fp);
fread(&infoHeader->Compression,INTSIZE,1,fp);
fread(&infoHeader->ImageSize,INTSIZE,1,fp);
fread(&infoHeader->xResolution,INTSIZE,1,fp);
fread(&infoHeader->yResolution,INTSIZE,1,fp);
fread(&infoHeader->Colors,INTSIZE,1,fp);
fread(&infoHeader->ImportantColors,INTSIZE,1,fp);
int rows = infoHeader->Height;
int cols = infoHeader->Width;
Pixel** pixelArr = malloc(rows * sizeof(Pixel*));
int i;
for (i = 0; i < cols; i++)
{
pixelArr[i] = (Pixel*) malloc(sizeof(Pixel));
}
int j;
for(i = 0; i < rows; i++)
{
for(j = 0; j < cols; j++)
{
fread(&pixelArr[i][j].Red,CHARSIZE,1,fp);
fread(&pixelArr[i][j].Green,CHARSIZE,1,fp);
fread(&pixelArr[i][j].Blue,CHARSIZE,1,fp);
}
printf("\n");
}
fclose(fp);
return pixelArr;
}
I am trying to randomly fill a 2d array with values then multiply them, but for some odd reason when I run my code, on the last iteration, I get a segmentation fault. I have tried decreasing the number I am passing it and everything, but the fault still persists. Here is the code I am trying to execute, any help is much appreciated, thanks.
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
FILE *matrixFile;
int n = atoi(argv[1]); // the number of matrices
int i, j; // must declare outside of for loop due to resolve C99 mode error
double arrA[n][n];// = CreateRandomMatrix(n);
double arrB[n][n];
double sumArr[n][n];
matrixFile = fopen("home/acolwell/Documents/CPE631_HW2_Number1/results.txt", "w+");
printf("Usage: %s <size of nxn matrices>\n", argv[1]);
// randomly populate arrA and arrB
for(i = 0; i < n; i++)
{
printf("%d\n", i);
for(j = 0; j < n; j++)
{
printf("%4d", j);
arrA[i][j] = (double)rand()/(double)RAND_MAX;
arrB[i][j] = (double)rand()/(double)RAND_MAX;
}
}
printf("Exiting Matrix randomization");
// multiply the matrices and write them to the file
for(i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
{
sumArr[i][j] = arrA[i][j] * arrB[i][j];
printf("Writing matrix ");
fprintf(matrixFile, "%0.3lf\n", sumArr[i][j]);
}
}
if(matrixFile)
{
fclose(matrixFile);
}
matrixFile = NULL;
return 0;
}
This error is going to come down to writing off the end of your array or failure to open your file. I would suggest running gdb to check out your program when it is running, but from a quick glance I wonder if you don't mean to have
"/home/acolwell/Documents/CPE631_HW2_Number1/results.txt"
as the file to write instead of
"home/acolwell/Documents/CPE631_HW2_Number1/results.txt"
I would suggest checking the result of your fopen call before calling fprintf.
If n is large enough, you'll generate a stack overflow using VLAs. I've verified this experimentally with your code (e.g. use n of 5000).
So, you'll need to use malloc to allocate from heap. But, that would require a bit of a rewrite.
Here's a way to use heap allocation and get the benefit of a VLA [using some slight trickery]:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define C(_arr) (double (*)[(size_t)(n)]) _arr
void
docalc(FILE *fout,int n,double arrA[n][n],double arrB[n][n],double sumArr[n][n])
{
// must declare outside of for loop due to resolve C99 mode error
int i,
j;
// randomly populate arrA and arrB
for (i = 0; i < n; i++) {
printf("%d\n", i);
for (j = 0; j < n; j++) {
printf("%4d", j);
arrA[i][j] = (double) rand() / (double) RAND_MAX;
arrB[i][j] = (double) rand() / (double) RAND_MAX;
}
}
printf("Exiting Matrix randomization");
// multiply the matrices and write them to the file
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
sumArr[i][j] = arrA[i][j] * arrB[i][j];
printf("Writing matrix\n");
fprintf(fout, "%0.3lf\n", sumArr[i][j]);
}
}
}
int
main(int argc, char *argv[])
{
FILE *matrixFile;
int n = atoi(argv[1]); // the number of matrices
printf("Usage: %s <size of nxn matrices>\n", argv[1]);
matrixFile = fopen("/tmp/results.txt", "w+");
if (matrixFile == NULL) {
perror("fopen");
exit(1);
}
double *arrA = malloc(sizeof(double) * n * n);
double *arrB = malloc(sizeof(double) * n * n);
double *sumArr = malloc(sizeof(double) * n * n);
docalc(matrixFile,n,C(arrA),C(arrB),C(sumArr));
if (matrixFile)
fclose(matrixFile);
matrixFile = NULL;
return 0;
}
I just compiled and tested your code. The file name you are giving is incorrect; you need a "/" in front of "home".
Not sure what the requirements are, but write your matrixFile like a matrix: add a new line after each row of the matrix is "multiplied", not after every element:
for(i = 0; i < n; i++) {
for(j = 0; j < n; j++) {
sumArr[i][j] = arrA[i][j] * arrB[i][j];
printf("Writing matrix ");
fprintf(matrixFile, "%0.3lf ", sumArr[i][j]);
}
fprintf(matrixFile, "\n");
}
Also, take Craig Easley's comment seriously. Stack Overflow can happen, even off the premises this website ;) Consider allocating your matrix dynamically on the heap.
I'm trying to write a program to blur an image, but first of am trying to see if I can even reproduce the image, pixel by pixel, in another file. I've allocated a 2-dimensional char array to hold the value of each pixel in the image.
Note: The image is in grayscale, and it is of type .raw
However, whenever I attempt to read the pixels into my 2D array, my program crashes. I feel like it has something to do with me not looping through the dimensions of the image correctly, but I'm not sure.
Code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fin, *fout;
char path_in[64], path_out[64], **rev, px;
int width, height, read, i, j;
printf("Input file name: ");
scanf("%s", path_in);
printf("Output file name: ");
scanf("%s", path_out);
printf("Width of image (in pixels): ");
scanf("%d", &width);
printf("Height of image (in pixels): ");
scanf("%d", &height);
fin = fopen(path_in, "rb");
fout = fopen(path_out, "wb");
row = 0;
rev = (char **)malloc(height * sizeof(char));
for(i = 0; i < width; i++)
rev[i] = (char *)malloc(width * sizeof(char));
for(i = 0; i < height; i++)
{
for(j = 0; j < width; j++)
{
read = fread(&px, sizeof(char), 1, fin);
rev[i][j] = px;
}
}
fclose(fout);
fclose(fin);
return 0;
}
My program is pretty narrow, as it only accepts grayscale .raw image type.
Change these lines as this:
row = 0;
rev = malloc(height * sizeof *rev);
for(i = 0; i < width; i++)
rev[i] = malloc(width * sizeof **rev);
You were allocating memory for height chars, not for height pointers to chars, as you intended.
Also, don't cast the result of malloc if developing with C
This line: rev = (char **)malloc(height * sizeof(char));
should be rev = (char **)malloc(height * sizeof(char*));
I think is better to use contiguous memory to manage the image!
Using char ** in the way as in your code you don't have a block of memory that contains the whole image, but a lot of not contiguous vectors each one containing a line!
The following code reads the image in a contiguous block of memory using only one malloc:
char * rev;
/* HERE your code to insert width and height */
rev = malloc(height * width *sizeof(char));
if (rev==NULL) {
/* Ops! The buffer is not allocated!!! */
}
/* HERE you open the file and so on */
for(i = 0; i < height; i++)
{
for(j = 0; j < width; j++)
{
read = fread(&rev[i*width+j], sizeof(char), 1, fin);
if (read!=1) { /* 1 is the number of bytes fread reads if ok */
/* Ops, there's a problem! The fread didn't read! */
}
}
}
Using char * you might load all the image with one fread, thus avoiding the two for loops :)
fread(rev,witdh,height,fin);
In this way you may point each single pixel using:
rev[y*width+x];
When we have an IplImage, how can we save it so we can use it later, or view it as an image outside of our code (such as via png, or jpeg)?
As a code example, I have the following:
void SaveImage()
{
CvSize size;
IplImage *rgb_img;
int i = 0;
size.height = HEIGHT;
size.width = WIDTH;
rgb_img = cvCreateImageHeader(size, IPL_DEPTH_8U, 3);
rgb_img->imageData = my_device.ColorBuffer;
rgb_img->imageDataOrigin = rgb_img->imageData;
/*for (i = 2; i < rgb_img->imageSize; i+= 3)
{
// confirming all values print correctly
printf("%d, ", rgb_img->imageData[i]);
}*/
cvSaveImage("foo.png",rgb_img);
}
I have printed out all of the values in the commented out for loop, and it seems like the data is in the buffer correctly. Using cvShowImage to display the image also works correctly, so it seems like the structure of the image is fine.
void SaveImage()
{
CvSize size;
IplImage *rgb_img;
int i = 0;
size.height = HEIGHT;
size.width = WIDTH;
rgb_img = cvCreateImageHeader(size, IPL_DEPTH_8U, 3);
rgb_img->imageData = my_device.ColorBuffer;
// You should NOT have the line below or OpenCV will try to deallocate your data
//rgb_img->imageDataOrigin = rgb_img->imageData;
for (i = 0; i < size.height; i++)
{
for (j = 0;j < size.width; j++)
{
// confirming all values print correctly
printf("%c, ", rgb_img->imageData[i*width + j]);
}
}
cvSaveImage("foo.png",rgb_img);
}
Running this should not crash.
Some problems with your code
You use %f to print but IPL_DEPTH_8U is 1-byte uchar
To save:
cvSaveImage(outFileName,img)
If you wanted to check it had saved, you could do the following:
if(!cvSaveImage(outFileName,img)) printf("Could not save: %s\n",outFileName);
Taken from http://www.cs.iit.edu/~agam/cs512/lect-notes/opencv-intro/opencv-intro.html#SECTION00052000000000000000 - top result on Google for "opencv write iplimage".