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.
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;
}
Basically, the input file should look like this:
4
1 2 3 4
2 1 4 3
4 3 2 1
3 4 1 2
Where the first line is the size of the square matrix. However, I can't properly load the input directly into n and then into the matrix. I avoided such problem by creating a "loader" array.
int n, loader[100], p=0;
while(feof(data) == 0) {
if(p == 0) {
fscanf(data, "%d", &n); //taking n
p++;
} else {
fscanf(data, "%d", &loader[p]); //taking matrix values for p>0
p++;
}
}
//loading the matrix
int mat[n][n], o = 1; //o is set to 1, as the loader
//has been loaded from position 1.
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++){
printf("%d\n", loader[o]);
mat[i][j] = loader[o];
o++;
}
}
However, I think it is just unnecessary and there might be a faster way to directly take the matrix size and its values. When I programmed in such way, I received a welcoming Segmentation Fault error.
This code seems to work:
int loadMatrix(char *pth)
{
int i, j, n, **mat, p = 0, num;
FILE *fd;
fd = fopen(pth, "r");
if(fd == NULL) return(-1);
/* Read matrix size */
if(fscanf(fd, "%d", &n) == EOF) return(-1);
printf("Size: %d\n", n);
mat = malloc(n * sizeof(int *));
for(i = 0; i < n; i++) mat[i] = malloc(sizeof(int) * n);
while(fscanf(fd, "%d", &num) != EOF && p < (n * n)) {
mat[p / n][p % n] = num;
p++;
}
for(i = 0; i < n; i++) {
for(j = 0; j < n; j++) {
printf("%d ", mat[i][j]);
}
printf("\n");
}
for(i = 0; i < n; i++) free(mat[i]);
free(mat);
fclose(fd);
return(0);
}
My code doesn't seem to be able to read the input file correctly. It somehow only reads the first line of my matrix and then it inputs the second line under "right hand side" instead of making another line for the matrix under "coefficient matrix". Additionally, it prints the third line under "Initial Guesses" rather than the third line of the matrix.
I'm assuming the error is somewhere in the code that I have posted below but let me know if you believe the code below is correct and somewhere else in my code is where this problem is originating from.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define MAX_DIM 100
#define MAX_ITER 500
#define TOLERANCE 1.e-6
void gauss_seidel(double **a, double *b, double *x, int n);
void print_screen_A_b_x(double **a, double *b, double *x, int n);
void main()
{
int i, j, *ptr, n;
int violation_counter, answer;
int violation_rows[MAX_DIM];
double sum;
double **a;
double *b, *x;
FILE *input_Ptr; //pointer to input file
//Open the input file
input_Ptr = fopen ( "my_input.txt", "r" );
if (input_Ptr == NULL) {
puts("\nInput file was not opened succesfully.\n");
exit(-1);
}
//read size of the problem
fscanf(input_Ptr, "%d", &n);
//dynamic memory allocation
a = (double **) malloc (n * sizeof(double *));
for (i = 0; i < n; i++) {
a[i] = (double *) malloc (n * sizeof(double));
}
b = (double *) malloc (n * sizeof(double));
x = (double *) malloc (n * sizeof(double));
/* read in data */
//n = MAX_DIM + 1;
//while (n > MAX_DIM) {
//fscanf(input_Ptr, "%d", &n);
//}
printf("\n");
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
fscanf(input_Ptr, "%lf", &a[i][j]);
}
for (i = 0; i < n; i++) {
fscanf(input_Ptr, "%lf", &b[i]);
}
for (i = 0; i < n; i++) {
fscanf(input_Ptr, "%lf", &x[i]);
}
printf("\n");
}
fclose(input_Ptr);
print_screen_A_b_x(a, b, x, n);
puts("Solution vector:");
for (i = 0; i < n; i++) {
printf("x[%d] = %10.5f \n", i, x[i]);
//free memory
for (i = 0; i < n; i++) {
free(a[i]);
}
free(a);
free(b);
free(x);
return 0;
}
/* test the convergence criterion */
violation_counter = 0;
for (i = 0; i < n; i++) {
sum = 0.0;
for (j = 0; j < n; j++)
if (i != j)
sum = sum + fabs(a[i][j]);
if (fabs(a[i][i]) < sum) {
violation_rows[violation_counter] = i;
violation_counter = violation_counter + 1;
}
if (a[i][i] == 0.0) {
printf("Found diagonal element equal to zero;
rearrange equations; exiting ...\n");
exit(0);
}
}
if (violation_counter > 0) {
printf("The Gauss-Seidel convergence criterion is violated in %d rows out of %d\n", violation_counter, n);
printf("Specifically, it was violated in rows:\n");
for (i = 0; i < violation_counter; i++)
printf("%d ", violation_rows[i]);
printf("\n");
printf("Enter 1 if you want to continue; any other number to abort : ");
scanf("%d", &answer);
if (answer != 1)
exit(1);
printf("Check results carefully\n\n");
}
/* initialize the solution vector -- initial guesses */
for (i = 0; i < n; i++) {
printf("Enter an initial guess for x[%d] of the solution vector : ", i);
scanf("%lf", &x[i]);
}
/* solve the system */
gauss_seidel(a, b, x, n);
/* output solution */
for (i = 0; i < n; i++)
printf("x[%d]=%f\n", i, x[i]);
printf("\n");
}
/* function to solve a system using Gauss-Seidel */
void gauss_seidel(double **a, double *b, double *x, int n)
{
double maxerror = 1.0e-7;
double iteration_error;
double e, sum, temp;
int i, j;
while (maxerror > 1.e-6) {
iteration_error = 0.0;
for (i = 0; i < n; i++) {
sum = 0.0;
for (j = 0; j < n; j++) {
if (i != j)
sum = sum + (a[i][j] * x[j]);
}
}
temp = (a[i][n] - sum) / a[i][i];
e = fabs((temp - x[i]) / x[i]);
x[i] = temp;
if (e > iteration_error)
iteration_error = e;
}
maxerror = iteration_error;
}
void print_screen_A_b_x(double **a, double *b, double *x, int n)
{
int i, j;
printf("\n Coefficient matrix:\n");
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
printf("%10.2f", a[i][j]);
}
printf("\n");
}
printf("\n Right hand side vector:\n");
for (i = 0; i < n; i++) {
printf("%10.2f \n", b[i]);
}
printf("\n Initial guess:\n");
for (i = 0; i < n; i++) {
printf("%10.5f \n", x[i]);
}
return;
}
Add \r\n in your post loop if statement.
You show us:
void gauss_seidel(double a[][MAX_DIM], double b[], double x[], int n)
and:
void print_screen_A_b_x(double **a, double *b, double *x, int n)
You cannot pass the same object as the first argument to both functions; they are (radically) different types, even though you use double subscripts with both. Since you've not shown how the matrix is actually defined, there isn't anything more we can do to help you.
Your compiler should be shrieking at you about one (or both) calls. Heed your compiler. It knows more about C than you do at the moment. It won't object unless there's a serious problem. If by some mischance your compiler was not complaining, then you need to either turn on compilation warnings (and work with C11, or perhaps C99, as the version of the standard — definitely not C90) or get a better compiler.
Analysis of one update
One version of the updated code in the question has input code like this:
// read size of the problem
fscanf(input_Ptr, "%d", &n);
// dynamic memory allocation
a = (double **)malloc(n * sizeof(double *));
for (i = 0; i < n; i++)
{
a[i] = (double *)malloc(n * sizeof(double));
}
b = (double *)malloc(n * sizeof(double));
x = (double *)malloc(n * sizeof(double));
printf("\n");
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
fscanf(input_Ptr, "%lf", &a[i][j]);
}
for (i = 0; i < n; i++)
{
fscanf(input_Ptr, "%lf", &b[i]);
}
for (i = 0; i < n; i++)
{
fscanf(input_Ptr, "%lf", &x[i]);
}
printf("\n");
}
The good news is that except for the absence of error checking, the memory allocation looks OK.
The bad news is that under most plausible inferences of what the data looks like, the main input loops are completely wrong. Assuming the value in n is N, the first iteration of the input loop reads N values into a[0] (which is fine), and then reads N values into b (which is fine as far as it goes), and then reads N values into x (which is also fine as far as it goes). The value of i is now n; when it is incremented by the outer loop, i is bigger than n, so the outer loop terminates, but you've only read one row of the main matrix.
Most likely, you should be using:
// read size of the problem
if (fscanf(input_Ptr, "%d", &n) != 1)
…report error and skedaddle…
// Check n for plausibility
if (n < 1 || n > 1000)
…report implausibility and skedaddle…
// dynamic memory allocation
…as before, except you should error check all the allocations…
printf("\n");
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
if (fscanf(input_Ptr, "%lf", &a[i][j]) != 1)
…report error and skedaddle…
}
}
for (i = 0; i < n; i++)
{
if (fscanf(input_Ptr, "%lf", &b[i]) != 1)
…report error and skedaddle…
}
for (i = 0; i < n; i++)
{
if (fscanf(input_Ptr, "%lf", &x[i]) != 1)
…report error and skedaddle…
}
The fact that you don't check for errors means you don't know when things go wrong. You can't afford not to know when things go wrong, so you can't afford not to check for errors.
skedaddle |skɪˈdad(ə)l|
verb [ no obj. ] informal —
depart quickly or hurriedly; run away.
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.
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;
}