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.
Related
We were asked to convert 2D static array to dynamic array. So I will need to create an array of pointers in which every pointer points to a different row. I have written this code but my code breaks when i=1 on line *(dynamicStr[i] + v) = rowStr[v]; Additionally, if I enable free(ptr); section my debugger gets stuck there for 6 or 7 times and then contiunes.
EDIT: In the end, I solved the problem with appying the answers #dodooft and #Viktor Terziev gave.
#include <stdio.h>
#include <stdlib.h>
void toDynamic(int x,int y, char toDyna[x][y]);
void toDynamic2(int x,int y, char toDyna[x][y]);
int main()
{
char toDyna[7][12] = {
"JOHN",
"MARK",
"PIERCEPIERCE",
"20",
"ROSIE",
"ALEX",
"MARLYN"
};
int x = 7;
int y = 12;
toDynamic2(x, y, toDyna);
return 0;
}
void toDynamic2(int x,int y, char toDyna[x][y]){
char *dynamicStr[x];
int rowToCheck = 0;
int size;
char *ptr;
int c;
for(int i = 0; i < x; i++){
printf("i: %d\n",i);
c = 0;
size = strlen(toDyna[rowToCheck]);
ptr = (char*) malloc(size * sizeof(char));
for(int j = 0; j < y; j++){
if(toDyna[i][j] != '\0'){
*(ptr+c) = toDyna[i][j];
c++;
} else{
break;
}
}
*(ptr+size) = '\0';
printf(" ");
char rowStr[size];
for(int v = 0; v < size; v++){
rowStr[v] = *(ptr+v);
printf("Added Char: %c\n", rowStr[v]);
*(dynamicStr[i] + v) = rowStr[v];
}
//free(ptr);
//printf("\n%s\n", rowStr);
//dynamicStr[i] = &rowStr;
rowToCheck++;
}
for(int i = 0; i < x; i++){
printf("%s\n", dynamicStr[i]);
}
}
EDIT: This is the working verion of the code:
#include <stdio.h>
#include <stdlib.h>
char** toDynamic(int x,int y, char toDyna[x][y]);
void free2DArray(int x, char **dynamicStr);
int main()
{
char toDyna[7][12] = {
"JOHN",
"MARK",
"PIERCEPIERCE",
"20",
"ROSIE",
"ALEX",
"MARLYN"
};
int x = 7;
int y = 12;
char **dynamicArr;
dynamicArr = toDynamic(x, y, toDyna);
free2DArray(x, dynamicArr);
return 0;
}
char** toDynamic(int x,int y, char toDyna[x][y]){
printf("Q2\n");
char **dynamicStr;
int rowToCheck = 0;
int size;
int c;
dynamicStr = (char*)malloc(x * sizeof(char*));
for(int i = 0; i < x; i++){
dynamicStr[i] = (char*)malloc(y * sizeof(char));
c = 0;
size = strlen(toDyna[rowToCheck]);
char *ptr = (char*) malloc((size + 1) * sizeof(char));
for(int j = 0; j < y; j++){
if(toDyna[i][j] != '\0'){
*(ptr+c) = toDyna[i][j];
c++;
} else{
break;
}
}
*(ptr+size) = '\0';
dynamicStr[i] = ptr;
rowToCheck++;
}
for(int i = 0; i < x; i++){
printf("%s\n", dynamicStr[i]);
}
printf("----------------------------\n");
return dynamicStr;
}
void free2DArray(int x, char **dynamicStr){
printf("Q3\n");
for(int i = 0; i < x; i++){
free(dynamicStr[i]);
printf("dynamicStr %d freed\n", i);
}
free(dynamicStr);
printf("dynamicStr array freed\n");
printf("----------------------------\n");
}
You define dynamicStr as an array of char pointers, when you are trying to assign a value to it with *(dynamicStr[i] + v) = rowStr[v]; you are basically copying the value of rowStr[v] to the address that is pointed by dynamicStr[i] + v. That address is not defined in your code, so you got a segfault.
If you are trying to fill dynamicStr with pointers to new arrays with dynamic memory, you should try something like
dynamicStr[i] = ptr;
where ptr is the pointer returned by the malloc call to the i-th row. Also, as you are working with strings you can use strcpy to copy the data from the static array to the dynamic one.
Its much easier than you think, please refer to strcpy documentation and strlen documentation, and (if you use my code) don't forget to free your memory.
char * * toDynamic2(size_t n, size_t m, char strings[n][m])
{
char * * arr = malloc(n * sizeof(char*));
for(size_t i = 0; i < n; ++i)
{
size_t size = strlen(strings[i]);
arr[i] = malloc((size + 1) * sizeof(char));
strcpy(arr[i], strings[i]);
}
for(size_t i = 0; i < n; ++i)
{
printf("%s\n", arr[i]);
}
return arr;
}
I want to do a two-dimensional array of strings using pointers, since by doing that I can later release the dynamic memory and make a smaller or larger array using the same identifier (variable).
I used the code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
unsigned long rows = 0;
unsigned long cols = 0;
unsigned long chrs = 30;
char ***mtx = NULL;
int rszmtx(char ***, unsigned long, unsigned long);
int main(int argc, char *argv[]) {
rszmtx(mtx, 0, 0);
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
strcpy(mtx[r][c], "[]");
}
}
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
printf("%s ", mtx[r][c]);
}
printf("\n");
}
return 0;
}
int rszmtx(char ***matrix, unsigned long y, unsigned long x) {
if (y <= 0) {
printf("Enter the number of rows: ");
scanf("%lu", &rows);
} else {
y = rows;
}
if (x <= 0) {
printf("Enter the number of cols: ");
scanf("%lu", &cols);
} else {
x = cols;
}
free(matrix);
matrix = (char ***) malloc(rows * sizeof(char **));
if (matrix == NULL)
return 1;
for (int r = 0; r < rows; r++) {
matrix[r] = (char **) malloc(cols * sizeof(char *));
for (int c = 0; c < cols; c++) {
matrix[r][c] = (char *) malloc (chrs * sizeof(char));
}
}
return 0;
}
In the function "main" I want to call the function "rszmtx" and assign a size to "mtx" given by the user. Then I want all the strings to be "[]" and print them out. The problem is that I can neither assign nor print anything. When testing I noticed that if I put the mapping and/or printing inside the "rszmtx" function everything works fine. Why is this, how can I map and print "mtx" outside the "rszmtx" function?
You have to pass the pointer by reference. For example
int rszmtx(char ****mtx, unsigned long y, unsigned long x);
//…
rszmtx(&mtx, 0, 0);
Otherwise the function deals with a copy of the original pointer mtx and changing a copy in the function does not influence on the original; pointer.
And there is no sense to define the pointer globally.
If it is a string matrix I would not do it like your solution with ********* pointers, only create set of functions like this:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdio.h>
#define SFUNC 1
typedef struct
{
int malloced;
char *string;
}STRING_t;
typedef struct
{
size_t xsize;
size_t ysize;
STRING_t strings[];
}STR2D_t;
STR2D_t *init(size_t xsize, size_t ysize)
{
STR2D_t *str2D = calloc(sizeof(str2D) + xsize * ysize * sizeof(str2D -> strings[0]), 1);
str2D -> xsize = xsize;
str2D -> ysize = ysize;
return str2D;
}
char *setstr2D(STR2D_t *str2D, const char *str, size_t xpos, size_t ypos)
{
char *result = NULL;
#if SFUNC
if(str2D && str2D -> xsize > xpos && str2D -> ysize > ypos)
#endif
{
STRING_t *strStruct = &str2D -> strings[xpos + ypos * str2D -> ysize];
#if SFUNC
if(strStruct -> malloced)
{
free(strStruct -> string);
strStruct -> malloced = 0;
}
#endif
strStruct -> string = (char *)str;
result = (char *)str;
}
return result;
}
char *strcpy2D(STR2D_t *str2D, const char *str, size_t xpos, size_t ypos)
{
char *result = NULL;
#if SFUNC
if(str2D && str2D -> xsize > xpos && str2D -> ysize > ypos)
#endif
{
STRING_t *strStruct = &str2D -> strings[xpos + ypos * str2D -> ysize];
if(strStruct -> string) strcpy(strStruct -> string, str);
result = strStruct -> string;
}
return result;
}
char *strmalloc2D(STR2D_t *str2D, size_t size, size_t xpos, size_t ypos)
{
char *result = NULL;
#if SFUNC
if(str2D && str2D -> xsize > xpos && str2D -> ysize > ypos)
#endif
{
STRING_t *strStruct = &str2D -> strings[xpos + ypos * str2D -> ysize];
result = realloc(strStruct -> malloced ? strStruct -> string : NULL, size);
if(result)
{
strStruct -> string = result;
strStruct -> malloced = 1;
}
}
return result;
}
char *strdup2D(STR2D_t *str2D, const char *str, size_t xpos, size_t ypos)
{
char *result = strmalloc2D(str2D, strlen(str) + 1, xpos, ypos);
if(result) result = strcpy2D(str2D, str, xpos, ypos);
return result;
}
The exercise, that I have to complete says:
That array_remove function must remove from the array arr the value, that is in the position pos, and scale of a position successive values of pos, and eventually change the array size for no gaps.
If this value is not included in the array (if pos is greater than pn (array size)), then you should not do anything.
My problem is:
Probably very wrong to use the malloc function, because when it is performed, it shows the following error:
MAIN.C:
#include "array.h"
int main(void)
{
double arr[] = { 1.0,2.0,3.0,4.0,5.0 };
size_t pn = 5;/*array length*/
size_t pos = 2;/*position of the number to be deleted*/
array_remove(arr, &pn, pos);
}
ARRAY.C:
#include "array.h"
void array_remove(double *arr, size_t *pn, size_t pos)
{
int x = *pn;
int y = pos;
if (x > y)
{
for (int i = y; i < x; i++)
{
arr[i] = arr[i + 1];
}
realloc(&arr, sizeof(double) * 4);
}
}
According to the C docs:
realloc Reallocates the given area of memory that must be previously allocated
by malloc(), calloc() or realloc() and not yet freed with free,
otherwise, the results are undefined.
You have an out of bound problem as well at the following lines when i=x-1 you try to access at arr[i+1] = arr[x=pn]:
for (int i = y; i < ; i++) {
arr[i] = arr[i + 1];
Check the following code out *(live: https://ideone.com/mbSzjL
#include<stdlib.h>
void array_remove(double **arr, int *pn, int pos) {
int x = *pn;
int y = pos;
if (x > y) {
//check if after deletion size is zero!
if (x > y) {
for (int i = y; i < x-1; i++) {
(*arr)[i] = (*arr)[i + 1];
}
*arr=realloc(*arr, sizeof(double) * x-1);
*pn=*pn-1;
}
}
}
int main(void) {
int pn = 20;/*array length*/
int pos = 5;/*position of the number to be deleted*/
double *arr = malloc(sizeof(double)*pn);
printf("%p\n",arr);
for(int i=0;i<pn;i++){
arr[i] = i;
}
for(int i=0;i<pn;i++){
printf("%.f ",arr[i]);
}
printf("\n");
printf("%i\n",pn);
array_remove(&arr, &pn, pos);
printf("%p\n",arr);
for(int i=0;i<pn;i++){
printf("%.f ",arr[i]);
}
printf("\n");
printf("%i",pn);
free(arr);
}
Don't forget to realloc using the right size (not using an hardcoded 4) and check for the edge case in which size is zero after deletion!
In addition,
free the memory at the end and to update the size variable.
http://en.cppreference.com/w/c/memory/realloc
arr array is stack allocated. You cannot realloc something that wasn't mallocated.
You probably want something like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
bool array_remove(double **arr, size_t *pn, size_t pos)
{
int x = *pn - 1;
int y = pos;
int i;
double *temp;
if (x > y) {
for (i = y; i < x; i++) {
(*arr)[i] = (*arr)[i + 1];
}
temp = realloc(*arr, sizeof(double) * x);
}
if (arr != NULL)
{
*arr = temp;
*pn -=1;
return true;
}
else
{
return false;
}
}
int main(void)
{
size_t pn = 5; // array length
size_t pos = 2; // position of the number to be deleted
int i;
double *arr = malloc(pn*sizeof(double));
if (arr != NULL)
{
for (i=0; i<pn; i++)
{
arr[i] = (double)(i+1);
}
if (array_remove(&arr, &pn, pos) == false)
{
printf("Failed to remove element %zu\n", pos);
}
for (i=0; i<pn; i++)
printf ("arr[%d]: %f\n", i, arr[i]);
free(arr);
}
else
{
printf("Failed to alloc array\n");
}
return 0;
}
As you can see I changed the loop of array_remove. In your code you are addressing the array out of bound on the last loop, because of i=4 and then:
arr[i] = arr[i + 1]; is arr[4] = arr[5]
Indexes of a 5 elements array start from 0 to 4.
actually you have a different problem here:
int x = *pn; //x=5
int y = pos; //y=2
if (x > y) {
for (int i = y; i < x; i++) {
arr[i] = arr[i + 1];
}
On the last iteration, you do
arr[4] = arr[5]
This is out of range addressig and that's probably your problem, or at least your first one.
Also, even though it's not technically wrong it's conceptually wrong:
array_remove(arr, &pn, pos);
Never pass a value by pointer unless you plan on modifying it. Not the case here, so you can pass it by value.
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);
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