Errors while creating a graph in C - c

I'm trying to generate a graph from a matrix but I'm having some problems, here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_N 10
#define MAX_P 20
//Declaracion del TDA cola
typedef struct Node {
int rafaga;
int id;
struct Node *dret;
struct Node *esq;
int fiscals;
int funcionaris;
int advocats;
} tipoNodo;
typedef tipoNodo *pNodo; // tipo para declarar nodos a un entero
int nodes = 0, funcionarisTotals = 0, advocatsTotals = 0, fiscalsTotals = 0;
Node llista[MAX_N];
int graf[MAX_N*2][3];
void crearGraf(int graf[MAX_N*2][3]) {
FILE *pf;
char caracter; // variable de tipo caracter que va a servir para almacenar los caracteres leidos del archivo
int valor, o, d;
pf = fopen ("graf.txt","r"); // se abre el archivo en forma de lectura
if (!pf) { //en el caso que no se pueda abrir el archivo se manda un mensaje de error
printf ("ERROR: el fichero no existe o no se puede abrir\n");
exit(-1); //mensaje "presiona una tecla para continuar"
}
else {
int arestes = 0;
while (!feof (pf)) {
int j = 0;
nodes = int ((caracter=fgetc(pf))-'0');
printf ("El graf te %d\n nodes", nodes);
for(int i = 0 ; i < nodes ; i++) {
llista->[i].id = i;
llista.[i].rafaga = 1;
}
caracter = fgetc(pf);
o = int ((caracter = fgetc(pf))-'0'); //nodo origen
caracter = fgetc(pf);
d = int ((caracter = fgetc(pf))-'0');//nodo destino
caracter = fgetc(pf);
valor = int ((caracter =fgetc(pf))-'0');//pes de l'aresta
if (o < 0 || d < 0 || valor < 0) break;
printf ("%d %d %d\n",o,d,valor);
graf[o][d] = valor; // es guarda el pes de l'aresta que va de X -> Y a la matriu
arestes++;
}
fclose (pf);//se cierra el fichero
for(int j = 0; j<arestes ; j++) {
if(j == 0) {
llista[graf[j][0]]->dret = llista[graf[j][1]]; // enllacem l'aresta primera
}
if(j != 0 && (graf[j-1][0] == graf[j][0])) {
llista[graf[j][0]]->esq = llista[graf[j][1]]; // enllacem l'aresta esquerra
}
else {
llista[graf[j][0]]->dret = llista[graf[j][1]]; // enllacem l'aresta dreta
}
}
}
}
int main (void)
{
int graf[MAX_N][MAX_N];
crearGraf(graf);
return 0;
}
The error I'm getting is:
SC.c:57: error: expected unqualified-id before ‘[’ token
SC.c:58: error: expected unqualified-id before ‘[’ token
Which are these two lines in the for loop:
for(int i = 0 ; i < nodes ; i++) {
llista->[i].id = i;
llista.[i].rafaga = 1;
}
I think I don't understand really the TYPE of variable I'mworking with here.
Could someone give me a hand? I've been trying to look for similar problems but I couldn't fix mine.
Thanks!

Change these 2 lines to
llista[i].id = i;
llista[i].rafaga = 1;
and you will be accessing the things that you appear to be trying to access.
Using the -> operator dereferences a pointer while it appears that you just want to access array elements which is done as above. I cannot speak for the correctness of the remainder of your code but these changes at the least should remove your compiler errors.

Related

fprintf in c erase th firs character char of the next line

i have a function, it write in file but when i update my file, i can see the line i have updated erase the first char of the next line. I saw thiw proceed when the number is >= 10...
`
void addPieceToFile(Piece* p, char* file){
FILE* f = fopen(file, "rw+");
int nbrSalles = 0;
int id = 0;
int test;
if(f != NULL) {
fseek(f,0, SEEK_END);
if(ftell(f) == 0){ //Premier passage ici si le fichier est vide
fprintf(f,"{%d}\n",nbrSalles += 1);
fprintf(f,"[%d|%d]%d\n",p->height, p->width, p->id);
for(int i = 0; i < p->height; i +=1 ){
for(int j = 0; j < p->width; j +=1 ){
fprintf(f,"%c ",p->piece[i][j]);
}
fprintf(f,"\n");
}
}else{ //Si le fichier contient déja une ou plusieur pieces on rentre ici
rewind(f); // On remonte au début du fichier
fscanf(f,"{%d}\n",&nbrSalles); // On récupère le nombre de salles
fscanf(f,"[%d|%d]%d\n",&p->height, &p->width, &id); // On récupère le nombre de salles
fseek(f,0,SEEK_END); // On revient a la fin du fichier ppour ecrire la nouvelle salle
test = testeChaine(TEMP_FILE,file);
if(test==1){
fprintf(f,"[%d|%d]%d\n",p->height, p->width, p->id); // On garde l'id actuelle en cas de modification
}else{
fprintf(f,"[%d|%d]%d\n",p->height, p->width, p->id+nbrSalles); // On met à jour l'id
}
for(int i = 0; i < p->height; i +=1 ){
for(int j = 0; j < p->width; j +=1 ){
fprintf(f,"%c ",p->piece[i][j]);
}
fprintf(f,"\n");
}
rewind(f); // On revient en haut du fichier
nbrSalles = nbrSalles + 1;
fprintf(f,"{%d}",nbrSalles); // Et on met à jour le nombre de salles I THINK THE PROBLEM IS HERE
}
system("clear");
result("Piece ajoutée.");
}else{
system("clear");
printf("Error. %s\n",file);
}
fclose(f);
}
`
I want to avoid this bug.
Thank you for your help.

Is there any way to make the scanf() function ignore invalid characters?

So, I've made this code, and it works wonderfully, but the problem is that I've got some scanf functions only accepting numbers, and some others only accepting characters, but for example, when I input a character on a scanf that requires an int value, the program behaves really unexpectedly, doing stuff such as repeating the same printf all over the command prompt, or repeating it thrice.
Here's the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int descuento(int num, int descuento);
int rangoValido(int Rangomin, int Rangomax, int i);
int numeroRandom();
int sino(char sino);
int main(void){
int productoid[1000][1];
int idprompt;
int descuento25[14] = {398, 309, 281, 948, 19, 67, 187, 80, 889, 482, 566, 24, 87, 98};
int descuento15[14] = {992, 788, 987, 90, 155, 596, 27, 587, 98, 273, 344, 69, 89, 234};
char respuesta;
int listacompra[100][1];
int precio;
int colector = 0;
int comprobante = 0;
int total;
int monto;
//Si la id del producto no esta dentro del rango valido, el bloque se repite
do{
do{
do{
printf("Escriba la ID del producto: ");
scanf("%d", &idprompt);
}
while(0==rangoValido(1,1000,idprompt));
//Una vez comprobada la validez del numero ingresado, se crea un numero aleatorio que se le
asigna para el precio, idprompt es la misma id
comprobante = 0;
srand(idprompt);
productoid[idprompt][1]=numeroRandom();
printf("ID del producto: %d\n", idprompt);
printf("Precio del producto: %d\n", productoid[idprompt][1]);
precio = productoid[idprompt][1];
//Comprobacion de descuentos
for(int i=0; i<=14; i++){
if(descuento25[i]==idprompt){
productoid[idprompt][1] = descuento(productoid[idprompt][1],25);
printf("Descuento del producto: 25\n");
}else{
if(descuento15[i]==idprompt){
productoid[idprompt][1] = descuento(productoid[idprompt][1],15);
printf("Descuento del producto: 15\n");
}
}
}
//Anadiendo el producto al carro de compras y comprobando la respuesta
do{
printf("Quieres anadir este producto a tu carrito de compras? (Y/N) ");
scanf(" %c", &respuesta);
}while(2 == sino(respuesta));
}while(respuesta == 'n' || respuesta == 'N');
if(respuesta == 'y' || respuesta == 'Y'){
listacompra[colector][0] = idprompt;
listacompra[colector][1] = precio;
colector = colector + 1;
}
do{
printf("Quieres seguir comprando? (Y/N) ");
scanf(" %c", &respuesta);
printf("\n");
if(0 == sino(respuesta)){
for(int i=0; i<colector; i++){
printf("\nID del producto %d: %d\n", i+1, listacompra[i][0]);
printf("Precio del producto %d: %d\n", i+1, listacompra[i][1]);
}
}
if(1==sino(respuesta)){
comprobante = 1;
}
}while(2==sino(respuesta));
}while(comprobante==1);
for(int i=0; i<colector; i++){
total = total + listacompra[i][1];
}
printf("\n\nTotal a pagar: %d\n", total);
printf("Ingrese monto recibido: ");
scanf("%d", &monto);
printf("\n");
if(monto<total){
printf("%d faltantes.", total-monto);
}
if(monto>=total){
printf("Vuelto: %d", monto-total);
}
return 0;
}
int numeroRandom(){
int random;
random = rand();
if(random>3000 && random<10000){
random = random / 5;
}
if(random<100){
random = random * 3;
}
if(random>10000){
random = random / 13;
}
return random;
}
int rangoValido(int Rangomin, int Rangomax, int i){
if(i>=Rangomin && i<=Rangomax){
return 1;
}else{return 0;}
}
int descuento(int num, int descuento){
num = num * (descuento / 100);
return num;
}
//Si la funcion sino() regresa 0, entonces la respuesta fue no. Si es 1, la respuesta es si. Y si
es 2, la respuesta es invalida.
int sino(char sino){
if(sino=='y' || sino=='Y'){
return 1;
}
if(sino=='n' || sino=='N'){
return 0;
}
else{return 2;}
}

why does this break the program? (i am running in c) tablero = (int *)malloc( sizeof(int)*fil*col );

so... i am working in a hanoi towers program and this breaks the whole thing... may you help me please? This is my first question, and i don't really know how does this work :( it breaks when declaring "tablero" in the main function
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void imprime(int *tab, int fil, int col, int ultNum, char name[64], char caso, int count, int filOrig, int filDest) {
/*
Precondición:
*tab Puntero a una matriz de tipo entero.
fil Entero que indica el numero de filas de la matriz.
col Entero que indica el numero de columnas de la matriz.
disc Parámetro de tipo entero que indica el numero de discos usados.
ultNum Entero que indica el numero que esta usando el disco mas grande.
*/FILE *f;
switch (caso) {
case 119:
f = fopen(name, "w");
break;
case 97:
f = fopen(name, "a");
break;
default:
printf("no file");
break;
};
int j, c;
int i, esp;
printf("Move %d to %d, movement number %d \n", filOrig, filDest, count);
for (c = col - 1; c >= 0; c--) {
for (j = 0; j < fil; j++) {
esp = (ultNum - tab[col * j + c]) / 2;
// Espacios a la izquierda
for (i = 0; i < esp; i++) {
fprintf(f, " ");
printf(" ");
};
// Imprime los comodines
for (i = 0; i < tab[col * j + c]; i++) {
fprintf(f, "*");
printf("*");
};
// Espacios a la derecha
for (i = 0; i < esp; i++) {
fprintf(f, " ");
printf(" ");
}
fprintf(f, "\t");
printf("\t");
};
fprintf(f, "\r\n");
printf("\n");
};
printf("\n \n \n \n \n");
fprintf(f, " \r\n \r\n \r\n \r\n \r\n ");
fclose(f);
count++;
};
void mueveDisco(int *tab, int fil, int col, int ultNum, int filOrig, int filDest, char name[64], char caso, int count) {
/*
Precondición:
*tab Puntero a una matriz de tipo entero.
fil Entero que indica el numero de filas de la matriz.
col Entero que indica el numero de columnas de la matriz.
disc Parámetro de tipo entero que indica el numero de discos usados.
ultNum Entero que indica el numero que esta usando el disco mas grande.
filOrig Entero que indica el numero de fila de la matriz en la cual hay que coger el numero/disco
filDest Entero que indica el numero de fila de la matriz en la cual hay que dejar el numero/disco.
Poscondición:
Se mueve el disco y se llama a la función que imprime el tablero.
*/
int cO = col - 1, cD = col - 1;
// Se busca el disco que se encuentre mas arriba y por lo tanto el mas pequeño de la fila de origen.
while (cO >= 0 && tab[col * filOrig + cO] == 0) {
cO--;
};
if (cO < 0)
cO = 0;
// Ahora se calcula cual es la posición libre mas arriba de la fila de destino
while (cD >= 0 && tab[col * filDest + cD] == 0) {
cD--;
};
// Se mueve el disco de la fila de origen a la de destino:
tab[col * filDest + cD + 1] = tab[col * filOrig + cO];
tab[col * filOrig + cO] = 0;
// Se imprime el tablero:
imprime(tab, fil, col, ultNum, name, caso, count, filOrig, filDest);
};
void hanoi(int *tab, int fil, int col, int disc, int ultNum, int O, int A, int D, char name[64], char caso, int count) {
/*
Precondición:
*tab Puntero a una matriz de tipo entero.
fil Entero que indica el numero de filas de la matriz.
col Entero que indica el numero de columnas de la matriz.
disc Parámetro de tipo entero que indica el numero de discos usados.
ultNum Entero que indica el numero que esta usando el disco mas grande.
O,A,D Tres enteros que indican la fila desde donde se ha de coger el disco y a donde se ha de traspasar. La primera vez que se llama a hanoi tienen los valores de: 0 ,1 y 2 respectivamente.
Poscondición:
Se llama recursivamente a hanoi hasta resolver el tablero.
*/
if (disc == 1) {
// Se borra la pantalla, se imprime la tabla y se hace una pausa que varia dependiendo del numero de discos:
mueveDisco(tab, fil, col, ultNum, O, D, name, caso, count);
if (col <= 5) system("sleep 0.8");
else if (col <= 10) system("sleep 0.3");
else if (col <= 15) system("sleep 0.06");
else if (col > 15) system("sleep 0.02");
} else {
hanoi(tab, fil, col, disc - 1, ultNum, O, D, A, name, caso, count);
mueveDisco(tab, fil, col, ultNum, O, D, name, caso, count);
if (col <= 5) system("sleep 0.8");
else if (col <= 10) system("sleep 0.3");
else if (col <= 15) system("sleep 0.06");
else if (col > 15) system("sleep 0.02");
hanoi(tab, fil, col, disc - 1, ultNum, A, O, D, name, caso, count);
};
};
int main(int argc, char *argv[]) {
int k; /* Value for the "-q" optional argument. */
time_t t = time(NULL);
struct tm *tm = localtime(&t);
char s[64];
strftime(s, sizeof (s), "%c", tm);
printf("%s\n", s);
char name[64];
int fil = 3, col = 3, *tablero = NULL;
int j, c, disc = 1, ultNum;
int count = 0;
char caso;
int i;
/*
printf("Escoja nombre del fichero :");
scanf("%s", &name);
printf( "Indique el numero de discos: " );
scanf( "%i", &col );
printf("Seleccione operacion en fichero: \n1. Añadir texto al archivo\n2. Reescribir archivo si existe\n3. No imprimir en archivo\n");
scanf ("%d", &caso);
*/
for (i = 0; i < argc; i++) {
if (strcmp(argv[i], "-d") == 0) {
col = atoi(argv[i + 1]);
}
if (strcmp(argv[i], "-f") == 0) {
sprintf(name, "%s.txt", argv[i + 1]);
}
if (strcmp(argv[i], "-o") == 0) {
caso = argv[i + 1];
}
}
printf("hace el for\n");
FILE *f;
printf("hace el file\n");
switch (caso) {
case 119:
f = fopen(name, "w");
printf("escribí la w\n");
break;
case 97:
f = fopen(name, "a");
printf("escribi la a\n");
break;
default:
printf("no file\n");
break;
};
printf("hace el switch\n");
tablero = (int *) malloc(sizeof (int)*fil * col); //peta aqui
printf("hice el sizeof");
// Resetea las torres poniendo "los discos" en una de ellas y 0 en el resto.
for (j = 0; j < fil; j++)
for (c = col - 1; c >= 0; c--)
if (j == 0) {
tablero[col * j + c] = disc;
disc += 2;
} else
tablero[col * j + c] = 0;
ultNum = disc;
fprintf(f, " Comand line entered: \r\n Number of towers : %d \n\n Number of discs: : %d \n\n Output filename : %s \r\n \r\n Init time : %s \r\n \r\n \r\n", fil, col, name, s);
fclose(f);
printf(" \n \n Comand line entered: \n Number of towers : %d \n Number of discs: : %d \n Output filename : %s \n \n Init time : %s \n \n \n", fil, col, name, s);
// Se imprime el tablero antes de iniciar ningún movimiento:
system("clear");
imprime(tablero, fil, col, ultNum, name, caso, count, 0, 0);
system("sleep 1");
// Se llama a hanoi para comenzar "la partida":
hanoi(tablero, fil, col, col, ultNum, 0, 1, 2, name, caso, count);
f = fopen(name, "a");
fprintf(f, " \r\n \r\n Fin Time : %s", s);
fclose(f);
return (0);
};
It's very unclear what you mean, if it's a compilation error then that doesn't make sense connected to that particular line, since there are other errors that already prevent the code from building.
If it's a run-time error (it crashes when run), that makes no sense either since the code doesn't build.
A better way to write that particular line is:
tablero = malloc(fil * col * sizeof *tablero);
This
Avoids the cast of malloc()'s return value
Uses sizeof on the target pointer, avoiding repeating the type

Rewriting JPEG images from RGB to HSL : how can i optimize this?

i'm on a project where i have to make a program that will draw an ASCII from a JPEG.
The program will chose a char according to the HSL value of a pixel : Hue, Saturation, Lightness
So, as a JPEG file is in RGB, i convert it into HSL.
But i find my program pretty slow and it slows my whole virtual machine lel
Do you know how i could improve it for making it a little bit faster ?
it's in my write i call the function that converts RGB into HSL
here it is :
main.c :
#include <stdio.h>
#include <stdlib.h>
#include <jpeglib.h>
#include "fonctions.h"
int main (int argc, char** argv){
int H;
int W;
int C;
FILE *fichier = NULL; //file pour l'image entrée
FILE *image = NULL; //file pou l'image à la sortie
unsigned char **buffer; //buffer où sera contenue l'image
buffer = malloc(256*(sizeof(unsigned char*)));
if (argv[1] == NULL)
fichier = fopen("cara.jpg", "r");
else
fichier = fopen(argv[1], "r");
image = fopen("cara_image_cree.jpg", "wb");
if (fichier == NULL)
printf("Probleme lecture");
printf("Cara Delevingne\n");
buffer = lire(fichier, &H, &W, &C);
/* afficher 3 sous-pixels :
printf("\nBuffer case 1 : %d", buffer[0][0]);
printf("\nBuffer case 1 : %d", buffer[0][0+1]);
printf("\nBuffer case 1 : %d\n", buffer[0][0+2]);*/
ecrire(&H, &W, &C, buffer, image);
fclose(fichier);
fclose(image);
return 0;
}
read.c :
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <jpeglib.h>
#include <jerror.h>
unsigned char** lire (FILE* file, int *H, int *W, int *C){
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
int n = 0;
unsigned char** buffer; // buffer qui va contenir l'image
/*printf("SHITSHITSHITSHITDEBUG\n");
fflush(stdout);*/
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo); // Initialisation de la structure
jpeg_stdio_src(&cinfo,file); // file est de type FILE * (descripteur de fichier
// sur le fichier jpega decompresser)
jpeg_read_header(&cinfo,TRUE);// lecture des infos sur l'image jpeg
jpeg_start_decompress(&cinfo);// lancement du processus de decompression
*H = cinfo.output_height; // on récupère la hauteur
*W = cinfo.output_width; // on récupère la largeur
*C = cinfo.output_components; // on regarde si l'image est en couleurs ou N&B
buffer=malloc( (*H) *sizeof(unsigned char*) ); // on alloue de la mémoire au buffer selon le nb de lignes de pixels qu'il va devoir prendre
while (n < *H) // tant que le compteur n'a pas dépassé l'image
{
buffer[n] = (unsigned char*) malloc( (*W) * (*C) *sizeof(unsigned char *) ); // on alloue à chaque ligne, la taille de la largeur
jpeg_read_scanlines(&cinfo,buffer+n,1); // lecture des n lignes suivantes de l'image
// dans le buffer (de type unsigned char *)
n++;
}
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
return buffer;
}
write.c :
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <jpeglib.h>
#include <jerror.h>
void ecrire (int *H, int *W, int *C, unsigned char **buffer, FILE *file){
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
float** bufferHSL;
int n = 0; // parcoureurs pour écrire l'image
int i = 0; // parcoureurs pour transformer en HSL
int j = 0;
float h = 0; // variables pour stocker le résultat HSL
float s = 0;
float l = 0;
int r, g, b;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo); // Initialisation de la structure
jpeg_stdio_dest(&cinfo,file); // file est de type FILE * (descripteur de fichier
// sur le fichier jpeg compressé final)
cinfo.image_width= *W; // nombre de ligne de l'image
cinfo.image_height= *H; // nombre de pixel par ligne
cinfo.input_components = *C; // 3 pour une image couleur, 1 pour une N&B
cinfo.in_color_space= JCS_RGB;
// JCS_GRAYSCALE pour une image N&B
jpeg_set_defaults(&cinfo); // initialisation des paramètres de compression
jpeg_start_compress(&cinfo,TRUE); // lancement du processus de decompression
bufferHSL = (float **) malloc( (*H) *sizeof(long int*) );
while (i < *H){ // lecture des lignes pour transformation HSL
j = 0;
while (j < *W){
/*printf("i : %d /t j : %d \n",i , j);
fflush(stdout);*/
bufferHSL[i] = (float*)malloc( (*W) *sizeof(long int*) );
r = buffer[i][j];
g = buffer[i][j+1];
b = buffer[i][j+2];
rgbToHsl(r, g, b, &h, &s, &l);
bufferHSL[i][j] = h;
bufferHSL[i][j+1] = s;
bufferHSL[i][j+2] = l;
j++;
/*printf("TESTTEST\n");
fflush(stdout);*/
}
i++;
}
while (n < *H)
{
jpeg_write_scanlines(&cinfo,buffer+n,1);// écriture des n lignes suivantes de l'image
// stockées dans le buffer (de type unsigned char *)
n++;
}
jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo);
}
RGB_to_HSL.c :
void rgbToHsl(int r, int g, int b, int *h, int *s, int *l){
r/=255; g /= 255; b/=255;
int max = maximum(r, g, b);
int min = minimum(r, g, b);
*l = (max + min)/2;
if (max == min)
*h = *s = 0; // achromatique
else{
int d = max - min;
*s = *l > 0.5 ? d / (2 - max - min) : d / (max + min);
if (max == r)
*h = (g-b) / d + (g < b ? 6 : 0);
if (max == g)
*h = (b-r) / d + 2;
if (max == b)
*h = (r-g) / d + 4;
/*case r: *h = r;
case g: *h = g;
case b: *h = b; */
}
*h /= 6;
}
int maximum (int a, int b, int c){
if (a > b){
if (a > c)
return a;
else
return c;
}
else{
if (b > c)
return b;
if (c > b)
return c;
}
}
int minimum (int a, int b, int c){
if (a < b){
if (a < c)
return a;
else
return c;
}
else{
if (b < c)
return b;
if (c < b)
return c;
}
}
You should run some profiling tool to see exactly which parts take how long to execute and optimize that.
Without that, a quick look shows you are calling malloc a lot in an inner loop, here:
bufferHSL = (float **) malloc( (*H) *sizeof(long int*) );
while (i < *H){ // lecture des lignes pour transformation HSL
j = 0;
while (j < *W){
bufferHSL[i] = (float*)malloc( (*W) *sizeof(long int*) );
Actually, that seems just wrong - You are calling it for every j < *W iteration, but you only need it once per i. You are leaking the allocation, and only doing anything on it in the last iteration - are you sure your output is correct?
As a first step, I recommend moving that line out of the inner while loop.
There is room for several other microoptimizations, but I don't think you need to do them. Just make sure the code is first correct, and then find the part that is slow (usually it is the innermost loop), and focus just on that.

Trouble assigning pointers from a table in C

I'm trying to create a graph from a file, I manage to read the file and save all the info in a matrix, however, when I try to read from the matrix and link the different nodes between them I get the segmentation fault error.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_N 10
#define MAX_P 20
//Declaracion del TDA cola
typedef struct Node {
int rafaga;
int id;
struct Node *dret;
struct Node *esq;
int fiscals;
int funcionaris;
int advocats;
} tipoNodo;
typedef tipoNodo *pNodo; // tipo para declarar nodos a un entero
int nodes = 0, funcionarisTotals = 0, advocatsTotals = 0, fiscalsTotals = 0;
Node llista[MAX_N];
int graf[MAX_N*2][3];
void crearGraf(int graf[MAX_N*2][3]) {
FILE *pf;
char caracter; // variable de tipo caracter que va a servir para almacenar los caracteres leidos del archivo
int valor, o, d;
pf = fopen ("graf.txt","r"); // se abre el archivo en forma de lectura
if (!pf) { //en el caso que no se pueda abrir el archivo se manda un mensaje de error
printf ("ERROR: el fichero no existe o no se puede abrir\n");
exit(-1); //mensaje "presiona una tecla para continuar"
}
else {
int arestes = 0;
nodes = int ((caracter=fgetc(pf))-'0');
printf ("El graf te %d nodes\n", nodes);
printf("abans del for de les rafagues\n");
for(int i = 0 ; i < nodes ; i++) {
printf("abans de posar la id\n");
llista[i].id = i;
printf("abans de posar la rafaga\n");
llista[i].rafaga = 1;
}
printf("despres del for de les rafagues\n");
while (!feof (pf)) {
int j = 0;
caracter = fgetc(pf);
o = int ((caracter = fgetc(pf))-'0'); //nodo origen
caracter = fgetc(pf);
d = int ((caracter = fgetc(pf))-'0');//nodo destino
caracter = fgetc(pf);
valor = int ((caracter =fgetc(pf))-'0');//pes de l'aresta
if (o < 0 || d < 0 || valor < 0) break;
printf ("%d %d %d\n",o,d,valor);
graf[arestes][0] = o; // es guarda el pes de l'aresta que va de X -> Y a la matriu
graf[arestes][1] = d;
graf[arestes][2] = valor;
printf("He llegit l'aresta %d\n", arestes);
arestes++;
}
printf("Fora del while de llegir fitxer\n");
fclose (pf);//se cierra el fichero
printf("Abans del for de les arestes, fare %d voltes\n",arestes);
for(int j = 0; j<arestes ; j++) {
printf("Posant l'aresta del node %d al %d\n", graf[j][0],graf[j][1]);
if(j == 0) {
printf("posant la primera aresta de pes %d\n",graf[j][2]);
*llista[graf[j][0]].dret = llista[graf[j][1]]; // enllacem l'aresta primera
printf("primera aresta posada\n");
}
if(j != 0 && (graf[j-1][0] == graf[j][0])) {
printf("posant l'aresta del node %d and node %d com a fill esquerra\n",graf[j][0],graf[j][1]);
*llista[graf[j][0]].esq = llista[graf[j][1]]; // enllacem l'aresta esquerra
}
else {
printf("posant l'aresta del node %d and node %d com a fill dret\n",graf[j][0],graf[j][1]);
*llista[graf[j][0]].dret = llista[graf[j][1]]; // enllacem l'aresta dreta
}
}
}
}
int main (void)
{
crearGraf(graf);
return 0;
}
The error I'm getting is when I try to link the first edge of the graph, in this line:
*llista[graf[j][0]].dret = llista[graf[j][1]]; // enllacem l'aresta primera
I think I'm messing up the type of the different variables. Also, all the printfs you see are to confirm that everything works just fine untill this point.
What am I missing again?
Thanks guys!
You are de-referencing a null pointer when you *llista[graf[j][0]].dret (because dret is a pointer that is not set yet..)
i think what you meant to do is:
llista[graf[j][0]].dret = &llista[graf[j][1]];

Resources