Good afternoon to everyone.
Firstly, i would like to apologize for my code - i am a real beginner in C. My problem is - i am given ppm file and i would need to store values from there into an array. I have already stored height , width and max value of color, now my idea to store a values would be the as shown at the picture - multiplying by three because it is in R G B format.
thank you for your help and please concider the fact i am a real beginner in C.
my code and output
#include <stdio.h>
int main(int argc, char** argv) {
int i = 0;
int j = 0;
FILE *fp;
fp = fopen(argv[1], "r");
printf(" %s ", argv[1]);
printf("\n");
int firstLine[2];
int width;
int next;
int enter;
int loop;
int height;
int max_color;
int pix[width][height];
int mask[3][3] = {// inicializting our given mask
{0, -1, 0},
{-1, 5, -1},
{0, -1, 0}
};
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
printf("%d ", mask[i][j]);
}
printf("\n");
}
fscanf(fp, "%s", &firstLine);
fscanf(fp, "%d", &height);
fscanf(fp, "%d", &width);
fscanf(fp, "%d", &max_color);
printf("%p", firstLine);
printf("\n");
printf("%d ", width);
printf("\n");
printf("%d", height);
printf("\n");
printf("%d", max_color);
printf("\n");
for (i = 0; i < width * 3; i++) {
for (j = 0; j < height * 3; j++) {
loop = fscanf(fp, "%d", &enter);
pix[i][j] = enter;
printf("%d ", enter);
}
}
// fclose(fp);
return (EXIT_SUCCESS);
}
You cannot define array with unknown size, esp height and width are not initialized. You should use dynamic allocated array here, like this:
int ***pix;
pix = malloc(height * sizeof(int**));
for (i = 0; i < height; i++) {
pix[i] = malloc(width * sizeof(int**));
for (j = 0; j < width; j++) {
pix[i][j] = malloc(3 * sizeof(int));
}
}
To correct parse the binary, you cannot use formatted input because they are for strings. You can use fread instead, e.g. to read the width:
fread(&width, sizeof(int), 1, fp);
Then to fill this array:
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++) {
for (k = 0; k < 3; k++) {
fread(&enter, sizeof(int), 1, fp);
pix[i][j][k] = enter;
}
}
}
This only works if what you said about ppm file's format is correct of course.
Related
Given the following piece of code, I don't understand why do we have to initialize every single row of the matrix when we have already created enough space in the stack.
#include <stdio.h>
#include <stdlib.h>
main() {
int **w;
int i, j;
int m, n;
printf("Number of rows in the matrix: ");
scanf("%d", &m);
printf("Number of columns in the matrix: ");
scanf("%d", &n);
w = (int **)malloc(m * n * sizeof(int));
for (i = 0; i < m; i++)
w[i] = (int *)malloc(n * sizeof(int));
for (i = 0; i < m; i++)
for (j = 0; j < n; j++) {
printf("Element [%d][%d]: ", i + 1, j + 1);
scanf("%d", &w[i][j]);
}
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
printf("Element [%d][%d]: %d\n", i + 1, j + 1, w[i][j]);
}
There are many issues in your code:
space is not allocated on the stack, but from the heap.
in both cases, memory allocated for the objects is uninitialized, which means it is not initialized to anything in particular and can have any value whatsoever. Relying on any particular contents is undefined behavior.
the matrix dimensions and all the matrix elements are read from standard input with scanf(). Yet you do not check for scanf() failure to convert integers from the characters read from stdin, so any invalid or missing input is going to cause undefined behavior at some point in the program.
your matrix is actually structured as an array of pointers to arrays of int, which is fine, but inconsistent with the size arguments used to allocate the first array: w = (int **)malloc(m * n * sizeof(int)); should be
w = malloc(m * sizeof(*w));
you could easily get objects pre-initialized to 0 by using calloc() instead of malloc():
for (i = 0; i < m; i++)
w[i] = calloc(n, sizeof(int));
you should also check for malloc() failure and exit with an appropriate diagnostic message.
main() is an obsolete prototype for the main function. You should either use int main(), int main(void) or int main(int argc, char *argv[])...
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
int get_int(void) {
int n;
if (scanf("%d", &n) != 1) {
printf("invalid input\n");
exit(EXIT_FAILURE);
}
return n;
}
void xalloc(size_t size) {
void *p = calloc(size, 1);
if (p == NULL) {
printf("out of memory for %zu bytes\n", size);
exit(EXIT_FAILURE);
}
return p;
}
int main() {
int **w;
int i, j;
int m, n;
printf("Number of rows in the matrix: ");
m = get_int();
printf("Number of columns in the matrix: ");
n = get_int();
w = xalloc(m * sizeof(*w));
for (i = 0; i < m; i++) {
w[i] = xalloc(n * sizeof(int));
}
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
printf("Element [%d][%d]: ", i + 1, j + 1);
w[i][j] = get_int();
}
}
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
printf("Element [%d][%d]: %d\n", i + 1, j + 1, w[i][j]);
}
}
for (i = 0; i < m; i++) {
free(w[i]);
}
free(w);
return 0;
}
I have to read a maze from a file and store it in a twodimensional array.
The characters I'm reading are stored in a .txt file like this:
######
#....#
#..#.#
. .#..
######
Note that the number of rows and columns can vary depending on the file.
My approach in reading the file so far:
#include <stdio.h>
#include <stdlib.h>
void read_arr(char** a, int x_size, int y_size) {
int i, j;
int tmp;
FILE* file = fopen("lab1.txt", "r");
for (i = 0; i < y_size; i++) {
for (j = 0; j < x_size; j++) {
if (tmp = fgetc(file))
a[j][i] = tmp;
printf("Success\n");
}
}
}
void print_arr(char** a, int x_size, int y_size) {
int i, j;
for (i = 0; i < x_size; i++) {
for (j = 0; j < y_size; j++) {
printf("%c", a[i][j]);
}
printf("\n");
}
}
int main() {
int x_size, y_size;
printf("What is the size of the maze (<x> <y>)? ");
scanf("%d %d", &x_size, &y_size);
printf("Maze has size %dx%d\n", x_size, y_size);
char** a = malloc(sizeof(char) * (x_size * y_size));
if (!a)
return -1;
printf("Successfully allocated memory!\n");
read_arr(a, x_size, y_size);
print_arr(a, x_size, y_size);
return 0;
}
But all I get from this is a memory error (I'm afraid I cant't give the exact error message, because it is displayed in german).
Another thing I've tried is using fscanf, but that didn't work either.
I'm on Ubuntu, and using gcc to compile my code.
Any help would be much appreciated!
Memory allocation is not correct
char** a = malloc(sizeof(char) * (x_size * y_size));
I guess what you wanted to do is
char** a = malloc(sizeof(char*) * y_size);
for(i = 0; i < y_size; ++i)
a[i]=malloc(x_size);
Also in read_arr function, you access array as arr[j][i], while j is your inner index, and i is outer
for (i = 0; i < y_size; i++) {
for (j = 0; j < x_size; j++) {
if (tmp = fgetc(file))
a[j][i] = tmp; ==> a[i][j] = tmp;
printf("Success\n");
}
}
I'm having trouble with one task.
I need to read two matrices from a text file and multiply them together.
The problem is that I know how to read one matrix but I don't understand how to read the two matrices separated (for example) by two spaces in a file.
Matrix.txt:
1 2 3 1 2 3
4 5 6 4 5 6
7 8 9 7 8 9
Maybe someone could explain me how to do that.
Now i'm trying to read first matrix:
#include <stdlib.h>
#include <stdio.h>
int main(){
FILE *fp;
int eSk = 0, sSk = 0,
matrix1[10][10] = {0}, i, j;
char c;
fp = fopen("matrix.txt", "r+");
while(!feof(fp)) {
while(getc(fp) != ' ') {
fscanf(fp, "%d", &matrix1[eSk][sSk]);
sSk++;
}
eSk++;
}
for(i = 0; i < eSk; i++) {
for(j = 0; j < sSk; j++) {
printf("%d ", matrix1[eSk][sSk]);
}
printf("\n");
}
puts("");
system("pause");
return 0;
}
what's wrong ?
Thank you for any help.
You need to skip the second matrix while reading the first and viceversa. Try this:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
FILE *file;
int matrixA[3][3], matrixB[3][3];
int garbage[3];
int i, j, k;
i = j = k = 0;
file = fopen("matrix.txt", "rt");
/* Read the first matrix */
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
fscanf(file, "%d", &matrixA[i][j]);
}
/* Skip the second matrix */
for (k = 0; k < 3; k++) fscanf(file, "%d", &garbage[k]);
}
/* Reposition the stream */
fseek(file, 0, SEEK_SET);
/* Read the second matrix */
for (i = 0; i < 3; i++) {
/* Skip the first matrix */
for (k = 0; k < 3; k++) fscanf(file, "%d", &garbage[k]);
for (j = 0; j < 3; j++) {
fscanf(file, "%d", &matrixB[i][j]);
}
}
/* Multiply them ... */
/* Show first matrix */
for (i = 0; i < 3; i++) {
printf("\n");
for (j = 0; j < 3; j++) {
printf(" %d ", matrixA[i][j]);
}
}
printf("\n");
/* Show second matrix */
for (i = 0; i < 3; i++) {
printf("\n");
for (j = 0; j < 3; j++) {
printf(" %d ", matrixB[i][j]);
}
}
return 0;
}
If the format of the string is standardized, you can read both matrices at one go. For your example above, please find a modified version as below.
int main(){
FILE *fp;
int eSk = 0, sSk = 0, i, j;
int mat1[3][3], mat2[3][3];
char line[256];
char c;
fp = fopen("matrix.txt", "r+");
if(NULL == fp) {
printf("Can't open the file\n");
exit(-1);
}
// Read one line
fgets(line, 256, fp);
while(!feof(fp)) {
// Convert line to array
sscanf(line,"%d %d %d %d %d %d", &mat1[eSk][0], &mat1[eSk][1], &mat1[eSk][2], &mat2[eSk][0], &mat2[eSk][1], &mat2[eSk][2]);
// Increment counter
eSk++;
//Read next line
fgets(line, 256, fp);
}
printf("Matrix1\n");
for(i = 0; i < eSk; i++) {
for(j = 0; j < 3; j++) {
printf("%d ", mat1[i][j]);
}
printf("\n");
}
printf("Matrix2\n");
for(i = 0; i < eSk; i++) {
for(j = 0; j < 3; j++) {
printf("%d ", mat2[i][j]);
}
printf("\n");
}
puts("");
system("pause");
return 0;
}
i'm using a pointer to pointer to intger as a 2 Dims array, i wrote these code but i failed on getting the integer value.
#include<stdio.h>
#include<conio.h>
void main(void)
{
int **pptr = 0, size = 0, size2 = 0, i, j;
clrscr();
printf("Enter Size of Main Store n");
scanf("%d", &size);
pptr = (int **) malloc(size * sizeof(int *));
printf("Enter Size of Sub Store n");
scanf("%d", &size2);
for (i = 0; i < size; i++) {
pptr[i] = (int *) malloc(size2 * sizeof(int));
}
printf("Enter Values n");
for (i = 0; i < size; i++) {
for (j = 0; j < size2; j++) {
scanf("%dn", pptr[i][j]);
}
}
clrscr();
printf(" Valuesn");
for (i = 0; i < size2; i++, pptr++) {
printf("%dn", *pptr + i);
}
getch();
}
it prints rubbish!!
scanf("%d", arg) expects a pointer to int, but
for (i = 0; i < size; i++) {
for (j = 0; j < size2; j++) {
scanf("%dn", pptr[i][j]);
}
}
you pass it an int, an uninitialised int at that. The indeterminate value in that memory location is then interpreted as a pointer, and the scan tries to store the converted value who-knows-where. It is not unlikely that that will cause a segmentation fault.
You should pass &pptr[i][j] as the argument there.
for (i = 0; i < size2; i++, pptr++) {
printf("%dn", *pptr + i);
}
prints the int* *pptr +i, which is &pptr[0][i], using the %d format that expects an int argument.
You should
printf("%d\n", pptr[0][i]);
if you want to print the values of the diagonal (as seems to be the case, since you also increment pptr in the loop), or, better
for(i = 0; i < size && i < size2; ++i) {
printf("%d\n", pptr[i][i]);
}
or, if you want to print the entire grid,
for(i = 0; i < size; ++i) {
for(j = 0; j < size2; ++j) {
printf("%d ", pptr[i][j]);
}
printf("\n");
}
scanf takes a int *, not an int. So...
scanf("%dn", pptr[i][j]);
should be:
scanf("%dn", &(pptr[i][j]));
or it could be:
scanf("%dn", (pptr[i]+j));
also, printf needs a value (int), not a pointer. So...
printf("%dn", *pptr + i);
should probably be something like:
printf("%dn", *(*pptr+i));
or the much nicer looking equivalent:
printf("%dn", pptr[0][i]);
I have a graphics program which has some computations in it.
its not giving any errors but after the program is run, its giving 6/4 divide error.
Can anyone help me with this?
#include<stdio.h>
#include<conio.h>
#include<graphics.h>
#include<stdlib.h>
struct face
{
int **vertices;
};
void main()
{
int gd = DETECT,gm;
int x, y, z, i, j, k, m, n;
struct face *f_3d, *f;
FILE *fp;
char c;
initgraph(&gd, &gm, "d:/tc/bgi");
fp=fopen("cube.txt", "r");
clrscr();
if(fp == NULL)
{
printf("\nFile doesn't exist");
exit(0);
}
fscanf(fp, "%d", &m);
fseek(fp, 1, SEEK_CUR); //no of faces
fscanf(fp, "%d", &n); //no of vertices for each face
printf("\n%d %d", m, n);
f = (struct face *) malloc(sizeof(m*sizeof(struct face)));
f_3d = (struct face *) malloc(sizeof(m*sizeof(struct face)));
for(i = 0; i < m; i++)
{
f[i].vertices = (int **) malloc(n*sizeof(int));
f_3d[i].vertices = (int **) malloc(n*sizeof(int));
}
for(i = 0; i < m; i++)
for(j = 0; j < n; j++)
{
f[i].vertices[j] = (int *) malloc(2*sizeof(int));
f_3d[i].vertices[j] = (int *) malloc(3*sizeof(int));
}
for(i = 0; i < m; i++) //for every face
for(j = 0;j < n; j++) // for every vertex in the face
{
fscanf(fp, "%d", &f_3d[i].vertices[j][0]); //read x coord
fseek(fp, 1, SEEK_CUR); //to skip comma
fscanf(fp, "%d", &f_3d[i].vertices[j][1]); //read y coord
fseek(fp, 1, SEEK_CUR);
fscanf(fp, "%d" ,&f_3d[i].vertices[j][2]); //read y coord
fseek(fp, 1, SEEK_CUR);
}
for(i = 0; i < m; i++)
for(j = 0; j < n; j++)
{
x=f_3d[i].vertices[j][0];
y=f_3d[i].vertices[j][1];
z=f_3d[i].vertices[j][2];
f[i].vertices[j][0]=(int)x/z;
f[i].vertices[j][1]=(int)y/z;
}
for(i = 0; i < 6; i++)
{
for(j = 0; j < 3; j++)
line(f[i].vertices[j][0], f[i].vertices[j][1], f[i].vertices[j+1][0], f[i].vertices[j+1][1]);
line(f[i].vertices[j][0], f[i].vertices[j][1], f[i].vertices[0][0], f[i].vertices[0][1]);
}
getch();
}
EDIT: Added additional information from comments:
All the values of the array assigned to x and y are integer values. So the final value assigned should also be an integer only. So, I wanted to know the reason for the divide error.
cube.txt contains vertices of the form 400,200,2, 300,400,2 etc. I am running this program in Turbo C. I am doing 400/2 and 200/2 (where x=400, y=200 and z=2) and assigning it to f[i].vertices[j][0]=x/z and f[i].vertices[j][1]=y/z?. There is no error as such. But when the program is run, the output is not seen. I expect to see the output of f[i].Vertices array.
My guess is that the problem is here:
for(i=0; i<m; i++)
for(j=0; j<n; j++)
{
x=f_3d[i].vertices[j][0];
y=f_3d[i].vertices[j][1];
z=f_3d[i].vertices[j][2];
f[i].vertices[j][0]=(int)x/z;
f[i].vertices[j][1]=(int)y/z;
}
You probably have z = 0 at some point. Try adding some debug code:
for(i=0; i<m; i++)
for(j=0; j<n; j++)
{
x=f_3d[i].vertices[j][0];
y=f_3d[i].vertices[j][1];
z=f_3d[i].vertices[j][2];
if (z == 0)
{
printf("ERROR: i = %d, j = %d, x = %d, y = %d, z = %d\n", i, j, x, y, z);
exit(1);
}
f[i].vertices[j][0]=(int)x/z;
f[i].vertices[j][1]=(int)y/z;
}
The error "divide error" occurs when some division is done by 0 'zero'. Try to identify the place where such division has occurred and modify those part.