I have some problems when I use pointers. In this program I want to input a text with ElaboraTesto and after with Sdoppia to put tokens into two different arrays:
StructTesto Pari[] if their length is even.
StructTesto Dispari[] if their length is odd.
Look like it works.
After I use ordinaPari that have to sort tokens according to their length, but when I try to print the array that contains odd tokens, with stampaStruttura, there is no output as well I input odd words.
I try to debug program (see code below) and I saw that vara and varb are always 0.
What am I missing?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DIMMAX 100
typedef char Stringa[DIMMAX];
typedef Stringa TESTO[DIMMAX];
typedef struct{
Stringa parola;
int lunghezza;
} StructTesto;
int ElaboraTesto(TESTO, int);
void Sdoppia(TESTO, int, StructTesto[], int* , StructTesto[], int*);
void stampaStruttura(StructTesto[], int);
void ordinaPari(StructTesto[], int);
void Sdoppia(TESTO t, int l, StructTesto Pari[], int* lp, StructTesto Dispari[DIMMAX], int* ld){
int i;
StructTesto p;
int rest;
int j=0;
int k=0;
ld = &j;
lp = &k;
for(i=0; i<l; i++){
strcpy(p.parola, t[i]);
p.lunghezza = strlen(p.parola);
rest = p.lunghezza % 2;
if (rest != 0){
strcpy(Dispari[j].parola ,p.parola);
Dispari[j].lunghezza = p.lunghezza;
j++;
} else {
strcpy(Pari[k].parola , p.parola);
Pari[k].lunghezza = p.lunghezza;
k++;
}
}
*ld = j;
*lp =k;
}
void stampaStruttura(StructTesto array[], int n){
int i;
for(i=0; i<n; i++){
printf("Parola: %s\n", array[i].parola);
printf("Lunghezza: %d\n", array[i].lunghezza);
}
}
int ElaboraTesto(TESTO t, int n){
char *tokenPtr;
Stringa testo;
int i;
printf("Inserire il testo da elaborare: (MAX %d parole)\n", DIMMAX);
gets(testo);
printf("Il testo che verra' tokenizzato e' il seguente:\n%s\n", testo);
printf("I token sono:\n");
tokenPtr = strtok(testo, " ");
while(tokenPtr != NULL){
printf("%s\n", tokenPtr);
strcpy(t[i], tokenPtr);
tokenPtr = strtok(NULL, " ");
i++;
}
printf("Il testo e' composto da %d parole.\n", i);
return i;
}
void ordinaPari(StructTesto P[], int n){
int i;
StructTesto temp;
for(i=0; i<n; i++){
if(P[i].lunghezza < P[i+1].lunghezza){
temp = P[i];
P[i] = P[i+1];
P[i+1] = temp;
}
}
}
int main(int argc, char *argv[]) {
TESTO testo;
int n;
int dim;
int vara = 0;
int varb = 0;
StructTesto p[DIMMAX];
StructTesto d[DIMMAX];
n = ElaboraTesto(testo, DIMMAX);
Sdoppia(testo, n, p,&vara,d,&varb);
stampaStruttura(p, n);
ordinaPari(p,vara);
stampaStruttura(p, vara);
}
return 0;
}
In the Sdoppia function you have these four lines:
int j=0;
int k=0;
ld = &j;
lp = &k;
The problem with this is that the pointers to the variables in the main function you pass in will be overwritten with the pointers to the local variables j and k.
So when you later do
*ld = j;
*lp =k;
you are actually assigning j to itself and k to itself (i.e. you are simply doing j = j and k = k).
The solution is to not do the initial reassignments to ld and lp.
Related
how to output data into new files g1 g2 g3 for each sorting method in c language
This is the code that i have done .. Might be a little messy but i somehow managed to make it work i think. I was wondering how to separately print the sorting output in each of their different files. Any advice or suggestions on how to do it will be appreciated
edit: i dont know if the program works because the plan was to run the loop till the array size (which will be the total values in the file) but i didnt know how to run a loop through an array without knowing its size in c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <time.h>
void getRandomArray(int arr[], int n, int max); //initiate an array with random numbers
void cloneArray(int arrB[], int arrA[], int size); //copy an array to another
void printArray(int arr[], int size); //print all elements of an array
void swap(int *xp, int *yp);
void selectionSort(int arr[], int n); //selection sort
void insertionSort(int list[], int n); //insertion sort
int main(int argc, char *argv[]) {
FILE *myFile;
myFile = fopen("test_dat.txt", "r");
//read file into array
int i;
int SIZE=10000;
int arrA[SIZE], arrB[SIZE];
if (myFile == NULL){
printf("Error Reading File\n");
exit (0);
}
for (i = 0; i <SIZE; i++){
fscanf(myFile, "%d,", &arrA[i] );
}
cloneArray( arrB, arrA, SIZE);
printArray(arrA, SIZE);
clock_t start = clock();
cloneArray(arrB, arrA, SIZE);
start = clock();
selectionSort(arrB, SIZE);
printf("Time = %f ms\n", 1000.0*(clock()-start)/CLOCKS_PER_SEC);
printArray(arrB, SIZE);
cloneArray(arrB, arrA, SIZE);
start = clock();
insertionSort(arrB, SIZE);
printf("Time = %f ms\n", 1000.0*(clock()-start)/CLOCKS_PER_SEC);
printArray(arrB, SIZE);
free(arrA);
free(arrB);
fclose(myFile);
}
//=======================================================
void cloneArray(int arrB[], int arrA[], int size) {
for (int i = 0; i < size; i++)
arrB[i] = arrA[i];
}
void printArray(int arr[], int size) {
for (int i=0; i < size; i++)
printf("%d ", arr[i]);
printf("\n");
}
void swap(int *xp, int *yp) {
int temp = *xp;
*xp = *yp;
*yp = temp;
}
//=======================================================
void selectionSort(int arr[], int n) {
puts("\n==================== Selection Sort ==================== ");
int comp = 0, swp = 0;
int min_idx;
for (int i = 0; i < n-1; i++) {
min_idx = i;
for (int j = i+1; j < n; j++)
if (arr[j] < arr[min_idx]) {
min_idx = j;
comp++;
}
swap(&arr[min_idx], &arr[i]);
swp++;
}
printf("No. comparisons = %d; No. swaps = %d\n", comp, swp);
}
void insertionSort(int list[], int n) {
puts("\n==================== Insertion Sort ====================");
int comp = 0, assg = 0;
for (int h = 1; h < n; h++) {
int key = list[h];
int k = h - 1; //start comparing with previous item
while (k >= 0 && key < list[k]) {
list[k + 1] = list[k];
comp++;
assg++;
--k;
}
list[k + 1] = key;
}
printf("No. comparisons = %d; No. assignments = %d\n", comp, assg);
return 0;
} //end insertionSort
This is a sample implementation of KD-tree.
Where I first take number of dimensions, number of points, number of clusters to be formed. Bi-partition function calculates centroid, dimension which has max variance. Now based on the max dimensions mean I start splitting the points. This program works fine when input is (dimensions-2,points-20,clusters-4). But does not work for (dimensions-2,points-20,clusters-8). When I debug the program it gives proper output.But when I run the program it stops working.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <stdbool.h>
int *gendata(int num);
void bipartition_fn(int dimensions,int nodes,int i0, int im, int *data,int *cluster_size,int *cluster_start, int *cluster_bdry, int *cluster_centroid);
void kdtree_fn(int dimensions, int nodes, int k, int *data,int *k_cluster_size,int **k_cluster_centroid,int *k_cluster_start,int **k_cluster_bdry );
int main()
{
int dimensions,nodes,i,k,j;
printf("enter the number of dimensions");
scanf("%d",&dimensions);
printf("enter the total number of elements in multiples of dimensions");
scanf("%d", &nodes);
printf("enter number of clusters");
scanf("%d",&k);
int *data;
int *k_cluster_size;
int **k_cluster_centroid;
int *k_cluster_start;
int **k_cluster_bdry;
data = gendata(nodes); /*dynamic array generation for data points*/
k_cluster_bdry=(int **)malloc(k*sizeof(int *));
for(i=0;i<(2*k-2);i++)
*(k_cluster_bdry+i)=(int *)malloc(2*dimensions*sizeof(int));
k_cluster_centroid=(int **)malloc(k*sizeof(int *));
for(i=0;i<(2*k-2);i++)
*(k_cluster_centroid+i)=(int *)malloc(dimensions*sizeof(int));
k_cluster_size=malloc((2*k-2)*sizeof(int));
k_cluster_start = malloc((2*k-2)*sizeof(int));
/*calling the kdtree function*/
kdtree_fn(dimensions, nodes, k, data, k_cluster_size, k_cluster_centroid, k_cluster_start, k_cluster_bdry);
/*printing the cluster size */
printf("cluster size \n");
for(i=k-2; i<(2*k - 2); i++){
printf("%d ", k_cluster_size[i]);
}
free(data);
free(k_cluster_bdry);
free(k_cluster_centroid);
free(k_cluster_size);
free(k_cluster_start);
return 0;
}
void kdtree_fn(int dimensions, int nodes, int k, int *data,int *k_cluster_size,int **k_cluster_centroid,int *k_cluster_start,int **k_cluster_bdry){
int i,j,d0,dm,x,m=0,l,n=0,check=1,s,temp=0;
d0 = 0, dm =nodes ;
int *cluster_size, *cluster_start;
int *cluster_bdry;
int *cluster_centroid;
int *query;
int *res;
query = (int *)malloc(sizeof(int)*dimensions);
res = (int *)malloc(sizeof(int)*dimensions);
cluster_centroid = (int*)malloc(dimensions*sizeof(int));
cluster_bdry = (int*)malloc(4*dimensions*sizeof(int));
cluster_size=(int*)malloc(2*sizeof(int));
cluster_start = (int*)malloc(2*sizeof(int));
/* iterating k-1 times to form k clusters */
for(x=0 ; x<k-1; x++){
bipartition_fn(dimensions, nodes, d0, dm, data, cluster_size, cluster_start, cluster_bdry, cluster_centroid);
for( i=0;i<dimensions; i++){
k_cluster_centroid[x][i] = cluster_centroid[i];
}
for( i=0;i<2; i++){
k_cluster_size[m] = cluster_size[i];
k_cluster_start[m] = cluster_start[i];
m++;
}
int p=0,r=0;
while(p<2){
l=0;
i=0;
while(i<2*dimensions){
k_cluster_bdry[temp][l] = cluster_bdry[r];
l++;
i++;
r++;
}
temp++;
p++;
}
s = pow(2,check);
if(x == 0 ||(x%(s-2)) == 0){
d0 =0;
nodes = k_cluster_size[n];
check++;
n++;
}
else{
d0 = d0+k_cluster_size[n-1];
nodes = k_cluster_size[n];
n++;
}
}
free(cluster_bdry);
free(cluster_centroid);
free(cluster_size);
free(cluster_start);
}
/*Each bipartition function gives 2 clusters*/
void bipartition_fn(int dimensions,int nodes,int d0, int dm, int *data,int *cluster_size,int *cluster_start, int *cluster_bdry, int *cluster_centroid){
int i,j,x,k;
int node = nodes/dimensions;
int sum,min,max;
int *cluster_assign;
cluster_assign = malloc(nodes*sizeof(int));
int *assign;
assign= (int *)malloc(node*sizeof(int));
// printf("nodes: %d \n", nodes);
/*calculate centroid and boundaries*/
i=0;
j=d0;
while(i<dimensions){
sum=0;
while(j<(d0+nodes)){
sum = sum+data[j];
j = j+dimensions;
}
cluster_centroid[i] = sum/node;
i = i+1;
j=d0+i;
}
/* Calculate variance of each dimension and find dimension with maximum variance*/
int var[dimensions],g,h;
h=d0;
g=0;
while(g<dimensions){
sum = 0;
while(h<(d0+nodes)){
sum = sum +((cluster_centroid[g] - data[h])*(cluster_centroid[g] - data[h]));
h=h+dimensions;
}
var[g] = sum/node;
g=g+1;
h=(d0+g);
}
int large = var[0];
int max_dimension =0;
int p;
for(p=0; p<dimensions; p++){
if(var[p]>large){
large = var[p];
max_dimension = p;
}
}
/* find mean of maximum variance*/
int mean = cluster_centroid[max_dimension];
//printf("mean %d \n",mean);
i=d0+max_dimension;
x=0;
while(i<(d0+nodes)){
if(data[i] < mean){
assign[x]=0;
}
else{
assign[x]=1;
}
x++;
i= i+dimensions;
}
/* Rearranging the points based on mean points lesser than mean goes to left and greater than mean goes to right*/
x=0;
int count=0;
int y=0;
for(i=0; i<node; i++){
if(assign[y] == 0){
count++;
for(j=dimensions*i; j<dimensions*(i+1); j++){
cluster_assign[x] = data[d0+j];
x++;
}
}
y++;
}
cluster_size[0] = count*dimensions;
cluster_start[0]= d0;
count=0;
y=0;
for(i=0; i<node; i++){
if(assign[y]!=0){
count++;
for(j=dimensions*i; j<dimensions*(i+1); j++){
cluster_assign[x] = data[d0+j];
x++;
}
}
y++;
}
cluster_size[1] = count*dimensions;
cluster_start[1]= d0+cluster_size[0];
int temp1,temp2;
x=0;
p=0;
while(p<2){
j=cluster_start[p];
i=0;
while(i<dimensions){
min=data[j];
max=data[j];
temp1=cluster_start[p];
temp2=cluster_size[p];
while(j < temp1+temp2){
if(data[j]<min)
min = data[j];
if(data[j]>max)
max= data[j];
j = j+dimensions;
}
cluster_bdry[x]=min;
x=x+1;
cluster_bdry[x]=max;
x=x+1;
i = i+1;
j=temp1+i;
}
p++;
}
/*printf("bou");
for(i=0; i<4*dimensions; i++){
printf("%d ",cluster_bdry[i]);
} */
free(cluster_assign);
free(assign);
}
/*Initialize data array*/
int *gendata(int num)
{
int *ptr = (int *)malloc(sizeof(int)*num);
int j = 0;
if(ptr != NULL)
{
for(j = 0; j < num; j++)
{
ptr[j] = -50 + rand()%101;
}
}
return ptr;
}
I feel like I've attempted every combination I know of to get this to work and can't figure it out. How can I scanf() into an int** passed as a pointer to a function? I tried searching but couldn't find this, if it's a duplicate please let me know and I'll delete. It begins to run and after entering a few values it segfaults.
Here's my code, I think it's messing up on the scanf() line of the setMatrix() function:
#include <stdio.h>
#include <stdlib.h>
// create zero initialized matrix
int** callocMatrix(int rmax, int colmax) {
int **mat = calloc(rmax, sizeof(int*));
for(int i = 0; i < rmax; i++) mat[i] = calloc(colmax, sizeof(int));
return mat;
}
// fill matrix
void setMatrix(int ***mat, int r, int c){
printf("Insert the elements of your matrix:\n");
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
printf("Insert element [%d][%d]: ", i, j);
scanf("%d", mat[i][j]); // problem here??
printf("matrix[%d][%d]: %d\n", i, j, (*mat)[i][j]);
}
}
return;
}
// print matrix
void printMatrix(int ***mat, int r, int c){
for (int i=0; i<r;i++){
for (int j=0; j<c;j++) {
printf("%d ", (*mat)[i][j]);
}
printf("\n");
}
}
int main(int argc, char *argv[]) {
int r = 3, c = 3;
int **mat = callocMatrix(r, c);
setMatrix(&mat, r, c);
printMatrix(&mat, r, c);
}
There is no need to use triple pointer ***. Passing two-dimensional array will work as is. Here is the code:
#include <stdio.h>
#include <stdlib.h>
// create zero initialized matrix
int** callocMatrix(int rmax, int colmax) {
int **mat = calloc(rmax, sizeof(int*));
for(int i = 0; i < rmax; i++) mat[i] = calloc(colmax, sizeof(int));
return mat;
}
// fill matrix
void setMatrix(int **mat, int r, int c){
printf("Insert the elements of your matrix:\n");
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
printf("Insert element [%d][%d]: ", i, j);
scanf("%d", &mat[i][j]); // no problem here
printf("matrix[%d][%d]: %d\n", i, j, mat[i][j]);
}
}
}
// print matrix
void printMatrix(int **mat, int r, int c){
for (int i=0; i<r;i++){
for (int j=0; j<c;j++) {
printf("%d ", mat[i][j]);
}
printf("\n");
}
}
int main(int argc, char *argv[]) {
int r = 3, c = 3;
int **mat = callocMatrix(r, c);
setMatrix(mat, r, c);
printMatrix(mat, r, c);
}
Should be:
scanf("%d", &(*mat)[i][j]);
You're passing a pointer to you matrix object, so you need to dereference it (with *) just as you do with printf. scanf then needs the address of the element to write into, so you need the &
I need that vector_total dont have any repeated number.
Function for entry vector1 and vector2 that are declared in main().
void entrada_vectors(int vector1[], int vector2[], int vector_total[], int *n, int *m)
{
int i=0, j=0;
/*Entrarem els nombres del vector 1 primer */
for (i=0; i<*n; i++)
{
vector_total[i]=vector1[i];
}
/*Entrarem els nombres del vector 2 després */
for (i=*n; i<*n+*m; i++)
{
if (j<*m)
{
vector_total[i]=vector2[j];
j++;
}
}
}
Function 2. This is for order numbers in vector_total.
void ordena(int vector_total[], int *n, int *m)
{
int i=0, j=0;
int aux=0;
for (i=0; i<*n+*m-1; i++)
{
for (j=0; j<*n+*m-1; j++)
{
if (vector_total[j]>vector_total[j+1])
{
aux=vector_total[j];
vector_total[j]=vector_total[j+1];
vector_total[j+1]=aux;
aux=0;
}
}
}
}
Function 3. Print vector_total
void mostra(int vector_total[], int *n, int *m )
{ int i;
for (i=0; i<*n+*m; i++)
{
printf ("Pos %d del vector: %d\n", i, vector_total[i] );
}
}
Function 4. Here are the problem!! This function is for clean my vector_total and drop the repeated numbers.
void limpiar_repetidos(int vector_total[], int *n, int *m)
{
int x=0, i=0, j=0;
for (i=0; i<*n+*m-1; i++)
{
for (j=0; j<*n+*m-1; j++)
{
if (vector_total[j]==vector_total[j+1])
{
x=j+1;
for (i=*n+*m; i>x; i--)
{
vector_total[i-1]=vector_total[i];
}
}
}
}
}
And here is my main. And my declaration variables:
int vector1[]={7,1,5,3,4,2};
int vector2[]={3,7,3,0,9,10};
int n=sizeof(vector1)/sizeof(vector1[0]);
int m=sizeof(vector2)/sizeof(vector2[0]);
int vector_total[n+m];
main()
{
entrada_vectors(vector1, vector2, vector_total, &n, &m);
ordena(vector_total, &n, &m);
mostra(vector_total, &n, &m);
limpiar_repetidos(vector_total, &n, &m);
printf ("==================\n");
mostra(vector_total, &n, &m);
return 0;
}
Thanks everybody! :)
1) If function deal with only a vector_total , Length of the vector_total is better to pass by one argument. Also you do not need to pointer pass if it will not change.
void mostra(int vector_total[], int len){
int i;
for (i=0; i<len; i++) {
printf ("Pos %d del vector: %d\n", i, vector_total[i] );
}
}
2) function need a new length after the element has been removed. Also, deletion of adjacent same elements that can be like this.
int limpiar_repetidos(int vector_total[], int len){//int *n, int *m --> int len
int i, size, new_size;
size = len;
for(i = new_size = 1; i < size; ++i){
if(vector_total[new_size-1] != vector_total[i])
vector_total[new_size++] = vector_total[i];
}
return new_size;
}
Example of use
mostra(vector_total, m + n);
int l = limpiar_repetidos(vector_total, n + m);
mostra(vector_total, l);
I'm new here and this is my first question, i couldn't find anything like this in the search engine so my problem is basically a vector of vectors on C, here is what i have done until now but i keep getting a deadly warning, so i know that I'm not using well the structure with the vector and I'd really appreciate some help.
Thanks
PD: Sorry for my english.
#include<stdio.h>
#include<stdlib.h>
typedef struct
{
int n;
int *vector;
}Vector_T;
int inicializar_original(int *n,int dim)
{
int i,r,s,j,*k;
Vector_T *t;
Vector_T l;
srand(time(NULL));
r=rand()%10;
scanf("%d",&s);
t->vector=k;
l.n=s;
k=(int*)malloc(s*sizeof(int));
for(j=0;j<s;j++)
{
k[j]=r;
}
for(i=0;i<dim;i++)
{
n[i]=k;
}
}
int main()
{
int *v,dim;
scanf("%d",&dim);
v=(int*)malloc(dim*sizeof(int));
inicializar_original(v,dim);
}
Asumo que hablas español, así que aquí va: El problema más grande es que no estás inicializando la variable "k". Mi sugerencia es que intentes lo siguente:
int i,r,s,j;
int* k;
If English only: Your problem is probably that you're initializing K in the wrong way. Try to do:
int i,r,s,j;
int* k;
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct {
int n;
int *vector;
}Vector_T;
int inicializar_original(Vector_T *v, int dim){
int i, j, s, r = rand()%10;
scanf("%d", &s);
for(i=0; i<dim; i++){
int *k = malloc( s * sizeof(int));
for(j=0; j<s; j++){
k[j]=r;
}
v[i].n = s;
v[i].vector = k;
}
}
int main(void){
Vector_T *v;
int dim;
srand(time(NULL));
scanf("%d", &dim);
v = malloc(dim * sizeof(*v));
inicializar_original(v, dim);
{ //check print & release
int i, j;
for(i = 0; i < dim; ++i){
for(j = 0; j < v[i].n ; ++j){
printf("%d ", v[i].vector[j]);
}
puts("");
free(v[i].vector);
}
free(v);
}
return 0;
}