Trying to compare chars from matrix C - c

I'm tryingto compare chars from a matrix, but it's not adding any values and i don't know why
so here's my code:
#include <stdio.h>
#include <math.h>
#include <assert.h>
#include <limits.h>
#include <string.h>
#include <stdlib.h>
#define MAX_LINES 1000
#define MAX_LINE_LENGTH 1000
//---------------------
//READING & WRITING
//---------------------
char *ints_new(int n)
{
return (char *) malloc(n * sizeof(char));
}
char **ints2_new(int rows, int cols)
{
char **result = (char **) malloc(rows * sizeof(char *));
char *p = ints_new(rows * cols);
for (int i = 0; i < rows; i++, p += cols)
result[i] = p;
return result;
}
int str_readline(FILE *f, char *s)
{
int result = EOF;
char *p = fgets(s, INT_MAX, f);
if (p != NULL)
{
result = (int) strlen(s);
if (result > 0 && s[result-1] == '\n')
s[--result] = '\0';
}
return result;
}
char *str_dup(const char *s)
{
char *result = (char *) malloc(strlen(s) + 1);
strcpy(result, s);
return result;
}
int strings_read(FILE *f, char **a)
{
int result = 0;
char line[MAX_LINE_LENGTH + 2];
while (str_readline(f, line) != EOF)
a[result++] = str_dup(line);
return result;
}
// --------------------
// Problema A
// --------------------
void values_to_m(char **m, int rows, int cols, char **readings)
{
int i;
int j;
int k = 0;
int l = 0;
for(i = 0; i < rows; i++)
{
for(j = 0; j < cols; j++)
{
m[i][j] = readings[k][l];
l++;
}
k++;
l = 0;
}
}
int count_points(char **m, int i, int j, int rows, int cols)
{
int result = 0;
if(i < rows-2)
{
if(m[i][j] == m[i+1][j] == m[i+2][j])
result++;
if(j < cols-2)
{
if(m[i][j] == m[i][j+1] == m[i][j+2])
result++;
if(m[i][j] == m[i+1][j+1] == m[i+2][j+2])
result++;
}
if(j > 1)
{
if(m[i][j] == m[i+1][j-1] == m[i+2][j-2])
result++;
}
}
else
{
if(j < cols-2)
{
if(m[i][j] == m[i][j+1] == m[i][j+2])
result++;
}
}
printf("%d\n", result);
return result;
}
void points(char **m, int rows, int cols)
{
int i;
int j;
int player1 = 0; //O's
int player2 = 0; //X's
for(i = 0; i < rows; i++)
{
for(j = 0; j < cols; j++)
{
int count;
count = count_points(m, i, j, rows, cols); //counts points
if (m[i][j] == 'X') //if values i'm couning are X, points go to player 2
player2 += count;
else if(m[i][j] == 'O') //if O go to player 1
player1 += count;
}
}
printf("%d %d\n", player1, player2);
}
// --------------------
// --------------------
void test_problem_A()
{
char **readings = malloc((MAX_LINES * MAX_LINE_LENGTH) * sizeof(char) + 1);
int rows = strings_read(stdin, readings); //to read from console
int cols = strlen(readings[0]);
printf("%d\n%d\n", rows, cols); //just to make sure nr of rows and cols is right
char **m = ints2_new(rows, cols); //create matrix
values_to_m(m, rows, cols, readings); //put the values to matrix
points(m, rows, cols); //calculate points
ints2_printf(m, rows, cols, "%c");
}
// --------------------
// --------------------
int main(int argc, char **argv)
{
test_problem_A();
return 0;
}
My programm has to read a bunch of 'X', 'O' and '.'.
If there are 3 'X' in a row(vertical, horizontal or diagonal) player 2 gets 1 point, if the same happens to 'O', player 1 gets 1 point. '.' don't count any points.
my matrix had to have minimum 3 rows and cols and maximum 1000 rows and cols.
example:
If i put in console
XXO
OXO
OXO
player 1 and 2 each get 1 point
if i put:
XXXXXO //(int this line Player 2 get 3 points because there are 3 times 3 X in a row)
OXOXOO
OXOOXO
OXOXOO
player 1 gets 5 points
and player 2 gets 6 points
So my problema is with function "count_points" it's not counting any points, when I print "result" it always gives me 0 points.
Can't I compare 2 chars if they belong in a matrix?
Thanks

In count_points, you try to compare three values with expressions like
if (a == b == c) ...
This doesn't do what you think it does. You treat it like a comparison in mathematical notation, but C interprets it as:
if ((a == b) == c) ...
The comparison a == b yields either 0 or 1. That result is then compared with c.
You could rewrite your desired expression as
if (a == b && b == c) ...
Given that your a, b and c are compound expressions, you could write a small function for that:
static int eq3(int a, int b, int c)
{
return (a == b && b == c);
}
int count_points(char **m, int i, int j, int rows, int cols)
{
int result = 0;
if (i < rows-2) {
if (eq3(m[i][j], m[i+1][j], m[i+2][j]))
result++;
if (j < cols - 2) {
if (eq3(m[i][j], m[i][j+1], m[i][j+2]))
result++;
if (eq3(m[i][j], m[i+1][j+1], m[i+2][j+2]))
result++;
}
if (j > 1) {
if (eq3(m[i][j], m[i+1][j-1], m[i+2][j-2]))
result++;
}
} else {
if (j < cols-2) {
if (eq3(m[i][j], m[i][j+1], m[i][j+2]))
result++;
}
}
return result;
}
As for the allocation of your matrix, see alk's answer. Your method of allocation - one char ** for the rows and then string duplication for the row data, could leave you with a ragged array and you may not safely access m[j + 1][i] for some cases where i is a valid index for row j, but not for row j + 1.

For starters, here you want to allocate pointers to char:
char **readings = malloc((MAX_LINES * MAX_LINE_LENGTH) * sizeof(char) + 1);
So do so:
char **readings = malloc((MAX_LINES * MAX_LINE_LENGTH) * sizeof(char*) + 1);
or even better:
char **readings = malloc((MAX_LINES * MAX_LINE_LENGTH) * sizeof *readings + 1);

Related

Pointer arrays allocated with malloc/calloc initializing with values other than 0

I have been given a school assignment in C to create a program that multiplies matrices. I will list assignment constraints below so people don't respond with questions as to why I am doing things this way.
Constraints from instructor:
Cannot use square brackets anywhere in code (use pointer notation instead)
Matrices A, B, C must be single integer pointer variables (int *A, *B, *C)
Can only use main function and those specified by header
Must compile with "gcc -ansi -Wall -o p2 p2.c"
I have not implemented the matrix multiplication function yet, as the issues I am having relate to either file reading or memory allocation.
The specific problem I am having is when I allocate space to the pointer matrix with either malloc OR calloc (tried both), the program inserts 33 in some places in the output instead of 0. I've tried everything at this point and am convinced my knowledge of pointers is fundamentally flawed.
p2.h (given by instructor)
#include <stdio.h>
#include <stdlib.h>
/* This function reads m, n, and p from the datafile.
It then allocates the correct amount of memory required for matrices
A, B, and C.
Then matrices A and B are filled from the datafile.
The values for m, n, and p are passed by reference, and are
thus filled in by this function
PARAMETERS in order are:
int ** matrix A
int ** matrix B
int ** matrix C
int * m The number of rows in matrix A
int * n The number of columns in matrix A and
The number of rows in matrix B
int * p The number of columns in matrix B
char * The name of the datafile, from the command line
*/
void read_matrices(int **, int **, int **, int *, int *, int *, char *);
/* This function prints a matrix. Rows and columns should be preserved.
PARAMETERS in order are:
int * The matrix to print
int The number of rows in the matrix
int The number of columns in the matrix
*/
void print_matrix(int *, int, int);
/* The two matrices A and B are multiplied, and matrix C contains the
result.
PARAMETERS in order are:
int * Matrix A
int * Matrix B
int * Matrix C
int m
int n
int p
*/
void mult_matrices(int *, int *, int *, int, int, int);
p2.c (sorry for the mess a lot of debugging went on)
#include <stdio.h>
#include <stdlib.h>
#include "./p2.h"
/* constants for testing */
#define cM 3
#define cN 2
#define cP 5
int main(int argc, char **argv) {
if (argc < 2) {
printf("Must include an argument.\n");
exit(1);
}
char *path = *(argv + 1);
int *m = (int *) malloc(sizeof(int));
int *n = (int *) malloc(sizeof(int));
int *p = (int *) malloc(sizeof(int));
*m = cM; *n = cN; *p = cP;
int i,j; /* loop counters */
/* allocate space for 2d pointer arrays */
int **A = NULL;
A = (int **) malloc(*m * sizeof(int *));
for (i = 0; i < *m; i++) {
*(A+i) = (int *) malloc(*n * sizeof(int));
}
int **B = NULL;
B = (int **) malloc(*n * sizeof(int *));
for (i = 0; i < *n; i++) {
*(B+i) = (int *) malloc(*p * sizeof(int));
}
int **C = NULL;
C = (int **) malloc(*m * sizeof(int *));
for (i = 0; i < *m; i++) {
*(C+i) = (int *) malloc(*p * sizeof(int));
}
/* write data to A */
for (i = 0; i < *m; i++) {
for (j = 0; j < *n; j++) {
*(*(A+i)+j) = 0;
}
}
/* testing a */
for (i = 0; i < *m; i++) {
for (j = 0; j < *n; j++) {
if (*(*(A+i)+j) != 0) {
printf("[x]");
} else {
printf("[0]");
}
}
}
printf("\n");
/* write data to B */
for (i = 0; i < *n; i++) {
for (j = 0; j < *p; j++) {
*(*(B+i)+j) = 0;
}
}
/* testing b */
for (i = 0; i < *n; i++) {
for (j = 0; j < *p; j++) {
if (*(*(B+i)+j) != 0) {
printf("[x]");
} else {
printf("[0]");
}
}
}
printf("\n");
/* write data to C */
for (i = 0; i < *m; i++) {
for (j = 0; j < *p; j++) {
*(*(C+i)+j) = 0;
}
}
/* testing c */
for (i = 0; i < *m; i++) {
for (j = 0; j < *p; j++) {
if (*(*(C+i)+j) != 0) {
printf("[x]");
} else {
printf("[0]");
}
}
}
printf("\n");
printf("Matrix A: \n");
print_matrix(*A, *m, *n);
printf("Matrix B: \n");
print_matrix(*B, *n, *p);
printf("Matrix C: \n");
print_matrix(*C, *m, *p);
return 0;
}
void read_matrices(int **A, int **B, int **C, int *m, int *n, int *p, char *path) {
FILE *fptr;
fptr = fopen(path, "r");
if (fptr == NULL) {
printf("Cannot open file: ./p2 [filename].txt\n");
exit(1);
}
/* get first 3 numbers from file, set m,n,p */
*m = fgetc(fptr);
fgetc(fptr);
*n = fgetc(fptr);
fgetc(fptr);
*p = fgetc(fptr);
fgetc(fptr);
/* read first matrix */
/* 1) calculate matrix size m x n
* 2) loop through malloc'ed matrix
* 3) each loop, insert char in loc
* 4) if next char NOT 10/32, add nextchar*10 to value in loc
*/
char cur;
while ( (cur = fgetc(fptr)) != EOF ) {
if (cur == 10 || cur == 32) {
/* do nothing :) */
} else {
*m = cur;
*n = cur;
*p = cur;
break;
}
}
printf("m: %c\n", *m);
printf("n: %c\n", *n);
printf("p: %c\n", *p);
printf("next: %c\n", fgetc(fptr));
fclose(fptr);
}
void print_matrix(int *X, int rows, int cols) {
int r, c;
int k = 0;
for (r = 0; r < rows; r++) {
for (c = 0; c < cols; c++) {
printf("\t%d", *(X+k));
k++;
}
printf("\n");
}
}
void mult_matrices(int *A, int *B, int *C, int m, int n, int p) {
}
d2.txt (data file)
3
2
4
1 2
3 4
5 6
7 8 9 10
11 12 13 14
Output: ./p2 d2.txt
[0][0][0][0][0][0]
[0][0][0][0][0][0][0][0][0][0]
[0][0][0][0][0][0][0][0][0][0][0][0][0][0][0]
Matrix A:
0 0
0 0
0 0
Matrix B:
0 0 0 0 0
0 33 0 0 0
Matrix C:
0 0 0 0 0
0 33 0 0 0
0 0 0 0 33
If you notice, I have some debug code that checks whether or not the current item in the array is 0. It seems to indicate that they are all 0, making me think it is a printing problem, but I am even more lost on what would be causing that. The ascii code for 33 is an exclamation point, but I am not sure what relevance it has.
Based on the function signatures you're supposed to use, you need to implement your 2D arrays as 1D with the correct index math. This will result in all memory being laid out contiguously, which is not at all guaranteed with the way you're allocating memory now (two calls to malloc for each matrix). For example:
#include <stdio.h>
#include <stdlib.h>
void print_matrix(int* A, int rows, int cols)
{
for (int r=0; r<rows; r++)
{
for (int c=0; c<cols; c++)
{
// If you want to treat A as a 2D matrix, this is where we have to do a bit of
// fancy index math to give you what double bracket notation [][] does for you
// r * cols gives you the index of the right row
// + c give you the column offset in that row
// add that offset to A then dereference
printf("%d\t", *(A + (r * cols + c)));
}
printf("\n");
}
}
int main(void)
{
// matrix A is supposed to be m by n
int* A;
// read these from file, or where ever they're supposed to come from
int m = 2;
int n = 10;
// Allocate the memory in one chunk. This makes the memory all contiguous, just the
// same as if you had done A[m][n]. However, the double call malloc for each int**
// matrix probably will not give you contiguous memory for the entire matrix. Each
// call to malloc is independent.
A = malloc(m * n * sizeof(int)); // or sizeof(*A) would be even better
if (A == NULL)
{
// handle error
}
// We can initialize values for A at this point, still not needing to care about
// rows or columns
for (int i=0; i<m*n; i++)
{
*(A + i) = i; // using i for a better visual when we print
}
print_matrix(A, m, n);
free(A);
return 0;
}
Demo
You are ovecomplicating simple things. Use pointers to arrays and allocate 2D array.
Use the correct type of your size variables.
Try to avoid side effects. Use parameters and function return values.
//this function is for the test purposes only
int writefile(const char *fn)
{
FILE *fo = fopen(fn, "w");
fprintf(fo,
"3\n"
"2\n"
"4\n"
"1 2\n"
"3 4\n"
"5 6\n"
"7 8 9 10\n"
"11 12 13 14\n");
fclose(fo);
}
void *allocIntMatrix(size_t rows, size_t cols)
{
int (*m)[cols] = malloc(rows * sizeof(*m));
return m;
}
void printIntMatrix(size_t rows, size_t cols, int (*m)[cols])
{
for(size_t row = 0; row < rows; row++)
{
for(size_t col = 0; col < cols; col++)
{
printf("[%5d] ", m[row][col]);
}
printf("\n");
}
}
int readData(FILE *fi, size_t rows, size_t cols, int (*m)[cols])
{
for(size_t row = 0; row < rows; row++)
{
for(size_t col = 0; col < cols; col++)
{
fscanf(fi, "%d", &m[row][col]);
}
}
return 0;
}
int main(int argc, char **argv)
{
size_t n,m,p;
writefile("a.aaa");
FILE *fi = fopen("a.aaa", "r");
fscanf(fi, "%zu", &m);
fscanf(fi, "%zu", &n);
fscanf(fi, "%zu", &p);
printf("n = %zu, m = %zu, p = %zu\n", n, m, p);
int (*A)[n] = allocIntMatrix(m, n);
int (*B)[p] = allocIntMatrix(n, p);
readData(fi, m, n, A);
readData(fi, n, p, B);
fclose(fi);
printIntMatrix(m, n, A);
printf("\n");
printIntMatrix(n, p, B);
return 0;
}
https://godbolt.org/z/adoEx1r4f
You need to check for errors (file, memory etc). I skipped it for the sake of simplicity of the example.

Brute force algorithm causes undefined behaviour

I have to create a program for an assignment that solves a sudoku puzzle. User needs to enter the name of a binary file (NOT a true binary file, it just has a .bin extension, it can be opened with notepad, notepad++ etc. as well) that contains numbers. Those numbers represent coordinates on the puzzle as well as the number contained in those coordinates e.g 432 means 4th row 3rd column contains number 2. After filling out the puzzle i need to solve it and print it on screen. After executing the program it crashed, so I decided to use MSVC 2017 debugger which is among the best according to some developers to find and fix the bug. Here is my code:
Sudoku.c
#include <stdio.h>
#include <stdlib.h>
#include "stdafx.h"
#include "sudokulib.h"
#define MALLOC_ERROR 0xFF
#define FILE_NOT_FOUND 0xFFF
#define ROWS 9
#define COLUMNS 9
int main(int argc, char ** argv)
{
char **matrix;
int i, args;
int row, column, num;
FILE * fp;
char * filename;
char * importedData;
matrix = (char **)malloc(ROWS * sizeof(char *));
if (!matrix)
exit(MALLOC_ERROR);
for (i = 0; i<ROWS; ++i)
{
matrix[i] = (char *)malloc(COLUMNS * sizeof(char));
if (!matrix[i])
exit(MALLOC_ERROR);
}
initSudoku(matrix);
printf ("Give me the name of data file: ");
filename = (char *)malloc(100 * sizeof(char));
if (!filename)
exit(MALLOC_ERROR);
scanf("%99s", filename);
fp = fopen(filename, "rb");
if (!fp)
{
printf ("File not found\n");
exit(FILE_NOT_FOUND);
}
importedData = (char *)malloc(sizeof(char)*ROWS*COLUMNS * 3);
if (!importedData)
exit (MALLOC_ERROR);
args = fread(importedData, 1, 243, fp);
i = 0;
while (importedData[i] != ' ' && importedData[i + 1] != ' ' && importedData[i + 2] != ' ' && importedData[i] >= '1' && importedData[i + 1] >= '1' && importedData[i + 2] >= '1' && importedData[i] <= '9' && importedData[i + 1] <= '9' && importedData[i + 2] <= '9' && i < 243)
{
row = importedData[i] - '0' - 1; /* Convert from ascii code to number */
column = importedData[i + 1] - '0' - 1;
num = importedData[i + 2] - '0';
matrix[row][column] = num;
i = i + 3;
}
printf("Sudoku after importing data:\n\n");
printSudoku(matrix);
system("pause");
if (solvePuzzle(matrix))
{
printSudoku(matrix);
}
else
printf ("Puzzle has no solution\n");
fclose(fp);
free(filename);
for (i = 0; i<9; ++i)
{
free(matrix[i]);
}
free(matrix);
return 0;
}
Sudokulib.h
#pragma once
#include <stdlib.h>
#include <stdio.h>
/* Function Prototypes Begin Here */
void printSudoku(char **);
void initSudoku(char **);
int checkRow(char **, int, int);
int checkCol(char **, int, int);
int check3x3(char **, int, int, int);
int checkIfEmpty(char **, int*, int*);
int solvePuzzle (char **);
/* Function Prototypes End Here */
void printSudoku(char ** Mat)
{
int i, j;
for (i = 0; i<9; ++i)
{
printf ("-------------------\n");
printf("|");
for (j = 0; j<9; ++j)
{
printf("%d|", Mat[i][j]);
}
printf("\n");
}
printf ("-------------------\n");
}
void initSudoku(char ** Mat)
{
int i, j;
for (i = 0; i<9; ++i)
for (j = 0; j<9; ++j)
Mat[i][j] = 0;
}
int checkRow (char ** Mat, int row, int num) // if row is free returns 1 else returns 0
{
int col;
for (col = 0; col < 9; col++)
{
if (Mat[row][col] == num)
{
return 0;
}
}
return 1;
}
int checkCol (char ** Mat, int col, int num) // if column is free returns 1 else returns 0
{
int row;
for (row = 0; row < 9; row++)
{
if (Mat[row][col] == num)
{
return 0;
}
}
return 1;
}
int check3x3 (char ** Mat, int row, int col, int num) // if number doesnt exist in the 3x3 grid returns 1 else returns 0
{
row = (row / 3) * 3; // set to first row in the grid
col = (col / 3) * 3; // set to first col in the grid
int i;
int j;
for (i = 0; i < 3; i++) // grid is 3x3
{
for (j = 0; j < 3; j++)
{
if (Mat[row + i][col + j] == num)
{
return 0;
}
}
}
return 1;
}
int isValid (char ** Mat, int row, int col, int num)
{
return (checkRow(Mat, row, num) && checkCol(Mat, col, num) && check3x3(Mat, row, col, num));
}
int checkIfPuzzleSolved (char ** Mat, int *row, int *col) // if function finds a box empty (puzzle not solved) returns 0 else returns 1
{
for (*row = 0; *row < 9; *row++)
{
for (*col = 0; *col < 9; *col++)
{
printf("ROW: %d COL: %d\n",*row,*col);
if (Mat[*row][*col] == 0)
{
return 0;
}
}
}
return 1;
}
int solvePuzzle (char ** Mat)
{
int row;
int col;
if (checkIfPuzzleSolved(Mat, &row, &col))
{
return 1;
}
int num;
for (num = 1; num <= 9; num++)
{
//if (checkRow (Mat,row,num) && checkCol (Mat,col,num) && check3x3 (Mat,row,col,num))
if (isValid(Mat, row, col, num))
{
Mat[row][col] = num;
if (solvePuzzle(Mat))
return 1;
Mat[row][col] = 0;
}
}
return 0;
}
The debugger found a bug at this function:
int checkIfPuzzleSolved (char ** Mat, int *row, int *col) // if function finds a box empty (puzzle not solved) returns 0 else returns 1
{
for (*row = 0; *row < 9; *row++)
{
for (*col = 0; *col < 9; *col++)
{
printf("ROW: %d COL: %d\n",*row,*col);
if (Mat[*row][*col] == 0) /* DEBUGGER ERROR CODE 0xC0000005: Access violation reading location 0xCDCA247C
{
return 0;
}
}
}
return 1;
}
Two things that confused me:
1) I don't understand the reason solvePuzzle gets stuck brute forcing the first box in the puzzle (1st row 1st column). It seems that checkIfPuzzleSolved thinks that the first box is empty (containing 0), even though using printSudoku I can see the algorithm modifying that box toggles its value between 3 and 4 and obviously 0 != 3 and 0 != 4.
2) In checkIfPuzzleSolved, printf prints on screen row and column number and it constantly produces the following result:
ROW: 0 COL: 0
ROW: 0 COL: 0
ROW: 0 COL: -858993460
Also double checked this with the debugger and the values are indeed those mentioned.
My train of thought was the following:
1) Use checkIfEmpty to determine if a box of the puzzle contained 0, that would mean that the puzzle would not be solved yet. Row and col variables are sent into the function by reference, so when function finds an empty box and returns, row and col would save the coordinates of the empty box.
2) In the loop, call checkRow, checkCol and check3x3 to check if a number can be put into the desired box without breaking the sudoku rules. isValid is there for readability purposes.
3) Call solvePuzzle recursively until the puzzle is solved, meanwhile if a number is wrong, reset it to 0.
I have tried everything i could think of to solve this problem, wasting hours reading again and again my code to find a logical error, but everything seems okay. Any ideas?
EDIT: On request of Michael Beer, here is a sample binary file:
data.bin
142156177191216228257289311329364375418422441484534546562579625663682698739743787794824855883896917933951968
*row++; parses as *(row++);, which is equivalent to just row++. You're incrementing the pointer, not the counter.
– melpomene
I see. So am I incrementing the pointer by sizeof(int) and not increasing the value that it refers to by 1? If so what is the correct way of writing "increment the value of the address you are pointing to by 1" regarding the syntax?
(*row)++ or ++(*row) or ++*row or *row += 1.
– melpomene

wrong allocate memory matrix C?

I'm developing a program that read from CSV file and calculate score with a method "calculateMLpa". The method receive array of char and array of 10 float, and transform array of float in matrix 3x3. When read the position 3rd number from array, insert in matrix the 4th number and same for 6th number.
I.E.
array value[]={0.000000;123.814934;234.000000;100.000000;166.000000; 203.086639;383.000000;186.000000;338.000000;173.098419 }
array traj[]={"0-0";"0-1";"0-2";"1-0";"1-1";"1-2";"2-0";"2-1";"2-2"}
Xn_val[]={"0","1","2"}
When transform in matrix the result is:
123.814934 234.000000 166.000000
166.000000 203.086639 186.000000
186.000000 338.000000 173.098419
While the expected for [0;2] is 100.000000 and for [1;2]=383.000000, but when print the currently value of traj it's correct.
How can I fix this problem?
The code is all here:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <math.h>
#include <stdbool.h>
#include <ctype.h>
#define ARRAYSIZE(x) (sizeof(x)/sizeof(*(x)))
int csv_parse ( char *line, int size )
{
char *p;
char *dp;
int inquote;
int na;
int nTo_comma;
char prevc = ',';
char *list[256];
dp = NULL;
// inquote = 0;
na = 0;
prevc = ';';
nTo_comma=0;
for ( p = line; *p != '\n'; p++ )
{
nTo_comma++;
list[nTo_comma] = p;
if(*p == prevc)
{
printf("%s\t", list);
return na;
}
}
printf("\n");
return na;
}
double calculateMLpa(const char *Xn_val[], char *traj[], float value[], double alphaxixj, double tauxi, int sz, int dim) {
double mlx = 0;
double v;
double alphaxi;
char *state;
int i;
int p;
int j;
int k;
// int sz = sizeof(Xn_val) / sizeof(int);
// int dim = sizeof(traj) / sizeof(char);
double trns[sz][sz];
double m[sz];
char *trat="-";
// m[xi] values: the number of transitions leaving the state xi
printf("%d %d \n",sz,dim);
int cont=0;
for (i = 0; i <= sz; i++) {
m[i] = 0.0;
for (j = 0; j <= sz; j++) {
v = 0.0;
int newlength = strlen(Xn_val[i])+strlen(trat)+strlen(Xn_val[j])+1;
state = malloc(sizeof(char)*newlength);
if(state != NULL){
state[0] = '\0';
strcat(state,Xn_val[i]);
strcat(state,trat);
strcat(state,Xn_val[j]);
printf("%s ",state);
}else {
printf(stderr,"malloc failed!\n");
}
// for (k=0; k<=dim;++k){
if (traj[cont] != NULL ){
if (strcmp(traj[cont],state)==0){
v = value[cont+1];
printf("%f \n",v);
}
}
trns[i][j] = v;
printf("%f - \n",trns[i][j]);
if (strcmp(Xn_val[i],Xn_val[j])!=0)
m[i] = m[i] + v;
cont++;
}
}
for (i=0;i<=sz;++i){
for(j=0;j<=sz;++j){
printf("%f ",trns[i][j]);
}
printf("\n");
}
for (p=0;p<=sz;++p){
printf("%f - \n",m[p]);
}
printf("%f %f\n",trns[0][1],trns[0][2]);
alphaxi = alphaxixj * (((double) sz) - 1.0);
alphaxi = alphaxixj;
printf("%d ",sz);
for (i = 0; i <= sz; i++) {
for (j = 0; j <= sz; j++) {
// xi!=xj
if (strcmp(Xn_val[i], Xn_val[j])!=0) {
mlx = mlx + lgamma(alphaxixj + trns[i][j]) - lgamma(alphaxixj);
}
// xi
else {
mlx = mlx + lgamma(alphaxi) - lgamma(alphaxi + m[i]);
mlx = mlx + lgamma(alphaxi + m[i] + 1.0)+ (alphaxi + 1.0) * log(tauxi);
mlx = mlx - lgamma(alphaxi + 1.0)- (alphaxi + m[i] + 1.0) * log(tauxi + trns[i][j]);
}
}
}
return (mlx);
}
#define MAXFLDS 200 /* maximum possible number of fields */
#define MAXFLDSIZE 32 /* longest possible field + 1 = 31 byte field */
void parse(char *record, char *delim, char arr[][MAXFLDSIZE], int *fldcnt) {
char*p = strtok(record, delim);
int fld = 0;
while (p) {
strcpy(arr[fld], p);
fld++;
p = strtok('\0', delim);
}
*fldcnt = fld;
}
void main() {
printf("inizio\n");
FILE *pf;
int N=20;
bool first=true;
const char *a[]={"0","1","2"};
char *traject[]={"0-0","0-1","0-2","1-0","1-1","1-2","2-0","2-1","2-2"};
double bs=0;
char *trat="-";
pf=fopen("//home//user//prova.csv","r");
float array[10][10];
float *t;
char *str= "hello";
char *state;
t = (float *)malloc(N * sizeof(float));
int f=0;
if (pf)
{
size_t i, j, k;
char buffer[BUFSIZ], *ptr;
/*
* Read each line from the file.
*/
for ( i = 0; fgets(buffer, sizeof buffer, pf); ++i )
{
/*
* Parse the comma-separated values from each line into 'array'.
*/
for ( j = 0, ptr = buffer; j < ARRAYSIZE(*array); ++j, ++ptr )
{
array[i][j] = strtof(ptr, &ptr);
}
}
fclose(pf);}
else /* fopen() returned NULL */
{
perror(pf);
}
for(f=0; f<10; ++f){
if(f==0){}
else if(f==1 && array[f][8]==0)
array[f][8]=123.8149353;
t[f]=array[f][8];
//printf("%f \n",t[f]);
}
for (f=0;f<10; ++f){
printf("%f - ",t[f]);
}
//printf("%s, %s, %s \n",a[0],a[1],a[2]);
printf("start\n");
int sz = sizeof(a) / sizeof(char);
int dim = sizeof(traject) / sizeof(char);
printf("%d , %d \n",sz,dim);
bs=calculateMLpa(a,traject,t,1.0,0.1,sz,dim);
printf("done \n");
printf("%f ",bs);
}
EDIT
I try to pass array size
sz=sizeof(a)/sizeof(char)
dim = sizeof(traject) / sizeof(char);
but their value is 24 and 72 respectively, and the execution stops at 0-2 value 100.000000
Arrays passed to functions decay to pointers to the start of the array. So
#define ARRAYSIZE(x) (sizeof(x)/sizeof(*(x)))
Will not return anything meaningful when checking for its size in that case
To fix, pass the Array size as an additional Argument.
One major problem is that when you pass arrays to functions, they decay to pointers, and the sizeof trick you use to get the array size will not work.
You need to pass the actual array sizes as arguments.

Using a structure in a recursive function (referenced structure)

I'm having problems understanding how to write code that solves the following problem: I have a structure containing a 2D-array. Then I have a recursive function that take a pointer to the structure as an argument and I want the recursive function to be able to manipulate the structure sent, not a local copy.
The struct is initialized in the function initStruct, where memory for the 2D-array is allocated. The recursive function builds up an array and at a specific point calls a function to insert it into the structure's array.
The code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int** spBasis(int);
void mpBasis(int**, int, int, int, int, int, int, int*, struct mpBasis *, int, int);
void initMpBasis(struct mpBasis *, int, int);
void insertMpState(struct mpBasis *, int *);
struct mpBasis {
int** basis;
int size;
int capacity;
};
int main() {
int a, b, c, d;
char maxE[256];
char noParticles[256];
char P[256];
char M[256];
FILE *fp;
int **spStates;
struct mpBasis *mp;
int mpState[6] = {0, 0, 0, 0, 0, 0};
printf("Input max e for sp states, no of particles, parity (1 for odd and 0 for even) and magnetic projection: ");
gets(maxE);
gets(noParticles);
gets(P);
gets(M);
spStates = spBasis(atoi(maxE));
fp = fopen("spStates.txt", "a+");
fprintf(fp, "E\tj\tl\tm\n");
for (a = 0; a < 330; a++) {
fprintf(fp, "State %d: ", a+1);
for (b = 0; b < 4; b++) {
fprintf(fp, "%d\t", spStates[a][b]);
}
fprintf(fp, "\n");
}
mp = malloc(sizeof(struct mpBasis));
initMpBasis(mp, 5449, 6);
for (c = 0; c < 5449; c++) {
for (d = 0; d < 6; d++) {
fprintf(fp, "%d: %d\t", c, mp->basis[c][d]);
}
fprintf(fp, "\n");
}
printf("%p\n", (void*) mp);
printf("hello 3");
mpBasis(spStates, 0, atoi(maxE), 0, atoi(M), 0, atoi(P), mpState, mp, 0, 0);
fclose(fp);
return 0;
}
int** spBasis(int maxE) {
int c;
int i, j, k, l;
int q = 0;
int** spStates;
spStates = (int**)malloc(330 * sizeof(int *));
for (c = 0; c < 330; c++) {
spStates[c] = malloc(4 * sizeof(int));
}
for (i = 0; i <= maxE; i++) {
for (j = i % 2; j <= i; j += 2) {
for (k = -(2 * j + 1); k <= (2 * j + 1); k += 2) {
spStates[q][0] = i;
spStates[q][1] = j;
spStates[q][2] = 2 * j + 1;
spStates[q][3] = k;
q += 1;
}
for (l = -(2 * j - 1); l <= (2 * j - 1); l += 2) {
spStates[q][0] = i;
spStates[q][1] = j;
spStates[q][2] = 2 * j - 1;
spStates[q][3] = l;
q += 1;
}
}
}
return spStates;
}
void mpBasis(int** spStates, int e, int maxE, int m, int M, int l,
int P, int * mpState, struct mpBasis *mpB, int position, int lastSpState) {
int i;
for (i = lastSpState; i < 330; i++) {
if (e > maxE) {
break;
} else if (position == 5) {
if (m == M && l % 2 == P) {
insertMpState(mpB, mpState);
break;
}
} else {
// add spState to mpState and make the recursive call for the next position
mpState[position] = i;
mpBasis(spStates, e + spStates[i][0], maxE, m + spStates[i][3], M,
l + spStates[i][1], P, mpState, mpB, position+1, i);
}
}
}
void initMpBasis(struct mpBasis *a, int initialSize, int sizeY) {
int c;
a->basis = (int **)malloc(initialSize * sizeof(int*));
for (c = 0; c < initialSize; c++) {
a->basis[c] = (int *) malloc(sizeY * sizeof(int));
}
a->size = 0;
a->capacity = initialSize;
}
void insertMpState(struct mpBasis *a, int* mpState) {
/*if (a->size == a->capacity) {
a->size *= 2;
a->basis = (int **)realloc(a->basis, a->size * sizeof(int));
}*/
a->basis[a->size++] = mpState;
}
Added all the code.
The problem is that after the recursive function has been called, the "basis" array in structure mpBasis still only contains random values, i.e. the mpBasis function hasn't done anything with it. Am I passing the mp argument by value here?
Thanks for your help!
The first step is to compile with warnings enabled. Eg if you are using GCC you can use option -Wall -Wextra.
EDIT:
(previous listing of >20 errors removed)
Ok, since you are using Visual Studio, enable warnings like this:
Open the project's Property Pages dialog box.
Select C/C++.
On the General property page, modify the Warning Level to /W4

Array value getting changed

So I have two problems:
I'm using netbeans to code this.
The first is that the array value that I am setting in c.sArr is getting changed from 7 to some random number, and I can't figure out why.
The second is that when I try to run debug in netbeans, the code gives me a segfault, whereas when i run it normally it doesn't. It gives a segfault at the atoi function.
Whats going on here?
#include <stdio.h>
#include <stdlib.h>
#include "spoonMatrix.c"
int main(int argc, char** argv) {
int iterations;
int argCounter = 0;
int debug = 1;
int i,j,q;
if(argc < 2)
return -1;
if(debug == 1){
for(q=0;q<argc;q++)
printf("%s\n", argv[argCounter++]); //Checking the params
}
argCounter = 1;
iterations = atoi(argv[argCounter++]);
if(debug == 1)
printf("%d", iterations);
for(i=0;i<iterations;i++){
int rows = 0;
int columns = 0;
int m = 0, n, p, elemCount;
int posCount = 0;
int temp;
cm c;
c.row = rows;
c.column = columns;
c.elems = (char*)calloc(rows*columns, sizeof(char));
c.sArr = (int*)calloc(rows*columns, sizeof(int));
rows = atoi(argv[argCounter++]);
columns = atoi(argv[argCounter++]);
for(m=0;m<rows*columns;m++)
{
c.sArr[m] = -2;
//printf("Here");
}
if(debug == 1)
{
printf("Rows : Columns - %d : %d\n", rows, columns);
}
temp = argCounter;
printf("argCounter is: %d\n", argCounter);
for(elemCount = 0 ; argCounter < temp + rows; argCounter++)
{
for(n=0; n<columns; n++, elemCount++)
{
c.elems[elemCount] = argv[argCounter][n];
//if(debug == 1)
// printf("%c\t", c.elems[elemCount]);
if(c.elems[elemCount]== 's' || c.elems[elemCount] == 'S')
{
c.sArr[posCount] = elemCount;
printf("%c\t%d\t%d\t%d\n", c.elems[elemCount], elemCount, c.sArr[posCount++], posCount);
}
}
}
printf("%d\n", c.sArr[0]);
if(debug == 1)
{
for(j=0; j<rows*columns; j++)
{
printf("%c ", c.elems[j]);
}
printf("\n");
for(j=0;j<rows*columns;j++)
{
printf("%d ", c.sArr[j]);
}
}
}
return (EXIT_SUCCESS);
}
and
the other file is:
struct charMat{
int row;
int column;
char* elems;
int* sArr;
};
typedef struct charMat cm;
Coded in the hurry, excuse the weird debugging statements.
Thanks
You aren't allocating (enough) memory:
int rows = 0;
int columns = 0;
c.elems = (char*)calloc(rows*columns, sizeof(char)); // rows * columns is 0
c.sArr = (int*)calloc(rows*columns, sizeof(int)); // rows * columns is 0
rows = atoi(argv[argCounter++]);
columns = atoi(argv[argCounter++]);
From calloc:
If the size of the space requested is 0, the behavior is
implementation-defined: the value returned shall be either a null
pointer or a unique pointer.

Resources