PDA

View Full Version : [Dev c++] Link error: non capisco il motivo


sonique
28-09-2007, 14:02
Ciao a tutti,
ho creato questi file di libreria: (struttra.h e struttura.c), di cui posto qui il codice:


//Header file contenente la definizione delle strutture dati per
//rappresentare e gestire una rete neurale feed-forward, e le
//operazioni utili ai fini della lettura da file e della inizializzazione
//di tali strutture.
//La lettura di una rete neurale avviene da file .net, compatibile
//con lo standard Stuttgart JNNS.

#ifndef _STRUTTURA_H_
#define _STRUTTURA_H_
#include <stdio.h>

struct node{
int funzione_act; //Tipo di funzione di attivazione
int funzione_out; //Tipo di funzione di output
float valore_in; //Valore di input
float valore; //Valore di output
float soglia; //Valore del bias
};
typedef struct node info_nodo;

typedef struct {
char nome[30];
int N; //Numero totale dei nodi della rete
float *w; //Vettore dei pesi
int nodi_input;//Numero nodi di input
int nodi_out; //Numero nodi di output
info_nodo *nodo;
} rete_neurale;

//////////////////////////////////////////////////////



//Data una stringa ne estrae un numero convertendolo in float
float estract_float(char *, int);


//Restituisce il prossimo carattere speciale |
int next_only_tab(char *, int);



//Restituisce il prossimo carattere speciale '|' ':' o ','
int next_tab(char *, int);


//Estrae il prossimo carattere valido
void estract_str(char *, int , char *);



//Lagge dal file .net il tipo di algoritmo di apprendimento
void read_learning(FILE *, char *);

//Lagge dal file .net il tipo di algoritmo di aggiornamento
void read_update(FILE *, char *);


//Legge dal file .net il nome della rete
void read_nome(FILE *, char *);

//Legge la configurazione della rete
void read_unit(FILE *, rete_neurale, int *, int *, int *);

//Inizializza la struttura ai valori di default
void init(rete_neurale ,int ,int,int,char *,char *);

//Legge i pesi e le connessioni presenti nella rete
void read_weigth(FILE *, rete_neurale , int , int , int );

//Legge dal file .net i parametri di default della rete
void read_def(FILE *, float *, float *, char *, char *, char *);


rete_neurale leggiretefile (char *);

//Lagge dal file .net il numero di nodi della rete
int read_units(FILE *);


//Legge dal file .net il numero di connessioni della rete
int read_conness(FILE *);

//Controlla la fine di un rigo non delimitato da alcun carattere speciale
int contr_fine(char *, int);

//Calcola i valori di uscita dei nodi, dati gli ingressi
rete_neurale calcola_feed_forward (rete_neurale);

#endif




#include "struttura.h"
#include <string.h>
#include <stdlib.h>

float estract_float(char *buf, int index)
//Data una stringa ne estrae un numero convertendolo in float
{
int i, j=0;
float num;
char stringa[15];

i=index+1;
while ((buf[i]!='|')&&(buf[i]!=':') && (buf[i]!=','))
{
if (buf[i]!=' ')
{
stringa[j]=buf[i];
j++;
}
i++;
}
stringa[j]='\0';
num=atof(stringa);
return num;
}

int next_only_tab(char *buf, int index)
//Restituisce il prossimo carattere speciale |
{
index++;
while (buf[index]!='|')
index++;
return index;
}

int next_tab(char *buf, int index)
//Restituisce il prossimo carattere speciale '|' ':' o ','
{
index++;
while ((buf[index]!='|') && (buf[index]!=':') && (buf[index]!=','))
index++;
return index;
}

char estract_c(char *buf, int index)
//Estrae il prossimo carattere valido
{
char car;
int i;

i=index+1;
while (buf[i]!='|')
{
if (buf[i]!=' ')
{
car=buf[i];
break;
}
i++;
}
return car;
}

void read_learning(FILE *fd, char *learning)
//Lagge dal file .net il tipo di algoritmo di apprendimento
{
char stringa[25];

fscanf(fd,"%s",stringa);
while (1)
{
if (strcmp(stringa,"learning")==0)
{
fscanf(fd,"%s",stringa);
if (strcmp(stringa,"function")==0)
{
fscanf(fd,"%s",stringa);
fscanf(fd,"%s",stringa);
strcpy(learning,stringa);
break;
}
}
fscanf(fd,"%s",stringa);
}
}

void read_update(FILE *fd, char *update)
//Lagge dal file .net il tipo di algoritmo di aggiornamento
{
char stringa[25];

fscanf(fd,"%s",stringa);
while (1)
{
if (strcmp(stringa,"update")==0)
{
fscanf(fd,"%s",stringa);
if (strcmp(stringa,"function")==0)
{
fscanf(fd,"%s",stringa);
fscanf(fd,"%s",stringa);
strcpy(update,stringa);
break;
}
}
fscanf(fd,"%s",stringa);
}
}

//Legge dal file .net il nome della rete
void read_nome(FILE *fd, char *nome)

{
char stringa[25];

fscanf(fd,"%s",stringa);
while (1)
{
if (strcmp(stringa,"network")==0)
{
fscanf(fd,"%s",stringa);
if (strcmp(stringa,"name")==0)
{
fscanf(fd,"%s",stringa);
fscanf(fd,"%s",stringa);
strcpy(nome,stringa);
break;
}
}
fscanf(fd,"%s",stringa);
}
}

void read_unit(FILE *fd, rete_neurale rete, int *in, int *hi, int *out)
//Legge la configurazione della rete
{
char *res, buf[200];
int index, num_input=0, num_hidden=0, num_output=0;
int i, act_d=0, out_d=0, actv_d=0, outv_d=0, type_d=0;
char nome[20], act_str[20], out_str[20], type;
float act, bias;


fscanf(fd,"%s",buf);
while (strcmp(buf,"sites")!=0)
fscanf(fd,"%s\n",buf);
fscanf(fd,"%s\n",buf);//Legge il rigo dei tab
for (index=1; index<=rete.N;index++)
{
act_d=0;
out_d=0;
actv_d=0;
outv_d=0;
type_d=0;
res=fgets(buf,200,fd);//Legge un rigo intero
if( res==NULL )
exit(1);
i=next_tab(buf,0);//Salta di due tab in avanti
i=next_tab(buf,i);
estract_str(buf,i,nome);//Estrae il nome del nodo
i=next_tab(buf,i);
if (buf[i+1]=='|')
actv_d=1; //Caso funzione di default
else{
rete.nodo[index].valore_in=estract_float(buf,i);//Estrae il valore di attivazione
rete.nodo[index].valore=rete.nodo[index].valore_in;
}
i=next_tab(buf,i);
if (buf[i+1]=='|')
outv_d=1; //Caso funzione di default
else
rete.nodo[index].soglia=estract_float(buf,i);//Estrae il valore del bias
i=next_tab(buf,i);
if (buf[i+1]=='|')
type_d=1; //Caso funzione di default
else
type=estract_c(buf,i);//Estrae il tipo del nodo
i=next_tab(buf,i);//Salta di due tab in avanti
i=next_only_tab(buf,i);
if (buf[i+1]=='|')
act_d=1; //Caso funzione di default
else
estract_str(buf,i,act_str);//Estrae la funzione di attiv.
i=next_tab(buf,i);
if (buf[i+1]=='|')
out_d=1; //Caso funzione di default
else
estract_str(buf,i,out_str);//Estrae la funzione di output
if (type=='i')
num_input++;
if (type=='h')
num_hidden++;
if (type=='o')
num_output++;
if (act_d==0)
rete.nodo[index].funzione_act=str2int(act_str);
if (out_d==0)
rete.nodo[index].funzione_out=str2int(out_str);
}
*in= num_input;
*hi= num_hidden;
*out= num_output;
}


void init(rete_neurale rete,int act_d,int bias_d,int tipo_d,char *act_fun_d,char *out_fun_d)
//Inizializza la struttura ai valori di default
{
int i, j, d, act, out, N;

N=rete.N+1;
act=str2int(act_fun_d);
out=str2int(out_fun_d);
for (i=1; i<=rete.N; i++)
{
rete.nodo[i].soglia=bias_d;
rete.nodo[i].valore_in=act_d;
rete.nodo[i].valore=act_d;
rete.nodo[i].funzione_act=act;
rete.nodo[i].funzione_out=out;
}
//Inizializzazione vettore dei pesi
for(j=0;j<=rete.N;j++)
{
for(d=0;d<=rete.N;d++)
rete.w[j*N+d]=-bias_d;
}
}

void read_weigth(FILE *fd, rete_neurale rete, int in, int hi, int out)
//Legge i pesi e le connessioni presenti nella rete
{
char buf[200], *res;
int N, num, index, i=0, j=0, numero_nodi=0 ,max, flag=0;
float peso;

max=in;
N=rete.N+1;
fscanf(fd,"%s",buf);
while (strcmp(buf,"source:weight")!=0)
fscanf(fd,"%s\n",buf);
fscanf(fd,"%s\n",buf);//Legge il rigo dei tab
res=fgets(buf,200,fd);//Legge un rigo intero
if( res==NULL )
exit(1);
//Per tutti i nodi non di input
for (j=in+1;j<=in+hi+out;j++){
index=(int)estract_float(buf,-1);//Estrae l'indice del nodo ricevente
i=next_tab(buf,0);//Salta due tab
i=next_tab(buf,i);
numero_nodi=0;//Inizializzazione
flag=0;
if (j==in+hi+1)
max=hi;
while (flag==0){
while ((buf[i+2]!='\0')&& (flag==0))
{
num=(int)estract_float(buf,i);//Estrae l'indice del nodo collegato
numero_nodi++;
i=next_tab(buf,i);//Salta i due punti
peso=estract_float(buf,i);
if (numero_nodi<max)
i=next_tab(buf,i);//Salta la virgola
else
flag=1;
//Inserisce l'indice del nodo afferente ed il peso
rete.w[index*N+num]=peso;
}
i=0;
res=fgets(buf,200,fd);//Legge un rigo intero
if( res==NULL )
break;
//printf("%s\n",buf);
}
}
}

void read_def(FILE *fd, float *act_d, float *bias_d, char *tipo_d, char *act_fun_d, char *out_fun_d)
//Legge dal file .net i parametri di default della rete
{
char stringa[25], *res, buf[200];
char car;
float layer, subnet;
int index;

fscanf(fd,"%s",stringa);
while (strcmp(stringa,"out")!=0)
fscanf(fd,"%s",stringa);
fscanf(fd,"%s\n",stringa);
if (strcmp(stringa,"func")==0)
fscanf(fd,"%s\n",buf);//Legge una riga intera
res=fgets(buf,200,fd);
if( res==NULL )
exit(1);
*act_d=estract_float(buf,-1);
index=next_tab(buf,0);//aggiorna il nuovo indice di tabulazione
*bias_d=estract_float(buf,index);
index=next_tab(buf,index);
*tipo_d=estract_c(buf,index);
index=next_tab(buf,index);
subnet=estract_float(buf,index);
index=next_tab(buf,index);
layer=estract_float(buf,index);
index=next_tab(buf,index);
estract_str(buf,index,act_fun_d);
index=next_tab(buf,index);
estract_str(buf,index,out_fun_d);
}

rete_neurale leggiretefile (char *nomefile)
{
char nome[30];
char *delim;
char *last;
char check[30];
int N, conness, in, hi, out;
int i, j, d;
float act_d, bias_d;
char tipo_d, act_fun_d[25], out_fun_d[25], learning[25], update[25];
FILE *fd;
int conta=0;
int num_afferenti=0;
rete_neurale rete;

// Controlla che l'estensione del file sia .net
strcpy(check, nomefile);
delim = strtok(check, ".");
while (delim != NULL){
last = delim;
delim = strtok(NULL, ".");
}
if(strcmp(last, "net") != 0){
printf("\nWarning: Stai aprendo un file con estensione diversa da .net\n");
getch();
}
//---------------------------------------------- END CHECK


fd=fopen(nomefile,"r");
if(fd == NULL){
printf("\nImpossibile aprire il file %s \n\n",nomefile);
system("pause");
exit(0);
}
//Lettura del nome della rete
read_nome(fd,nome);
strcpy(rete.nome,nome);
//Lettura del numero totale di nodi
rete.N=read_units(fd);
N=rete.N+1;
//Lettura del numero di connessioni
conness=read_conness(fd);
//Lettura del tipo di apprendimento e dell'ordine di aggiornamento
read_learning(fd,learning);
read_update(fd,update);
//Lettura dei valori di default
read_def(fd,&act_d,&bias_d,&tipo_d,act_fun_d,out_fun_d);
//Inizializzazione alla dimensione letta
rete.w=(float *)malloc(N*N*sizeof(float));
rete.nodo=(info_nodo *)malloc(N*sizeof(info_nodo));
//Inizializzazione delle strutture
init(rete,act_d,bias_d,tipo_d,act_fun_d,out_fun_d);
//Per tutti i nodi di input
read_unit(fd,rete,&in,&hi,&out);
//Aggiornamento del numero di nodi input e output nella rete
rete.nodi_input=in;
rete.nodi_out=out;
//Aggiorna i valori dei pesi ai bias
for(i=1;i<=rete.N;i++)
rete.w[i*N]=-rete.nodo[i].soglia;
//Inserisce il valore dei pesi nelle connessioni
read_weigth(fd,rete,in,hi,out);
fclose(fd);
return(rete);
}

int read_units(FILE *fd)
//Lagge dal file .net il numero di nodi della rete
{
char stringa[25];
int units=0;

fscanf(fd,"%s",stringa);
while (1)
{
if (strcmp(stringa,"no.")==0)
{
fscanf(fd,"%s",stringa);
if (strcmp(stringa,"of")==0)
{
fscanf(fd,"%s",stringa);
if (strcmp(stringa,"units")==0)
{
fscanf(fd,"%s",stringa);
fscanf(fd,"%d",&units);
break;
}
}
}
fscanf(fd,"%s",stringa);
}
return units;
}

int read_conness(FILE *fd)
//Legge dal file .net il numero di connessioni della rete
{
char stringa[25];
int conness=0;

fscanf(fd,"%s",stringa);
while (1)
{
if (strcmp(stringa,"no.")==0)
{
fscanf(fd,"%s",stringa);
if (strcmp(stringa,"of")==0)
{
fscanf(fd,"%s",stringa);
if (strcmp(stringa,"connections")==0)
{
fscanf(fd,"%s",stringa);
fscanf(fd,"%d",&conness);
break;
}
}
}
fscanf(fd,"%s",stringa);
}
return conness;
}

int contr_fine(char *buf, int index)
//Controlla la fine di un rigo non delimitato da alcun carattere speciale
{
int i;

i=index;
while (buf[i]!='\0')
i++;
if (buf[i-1]==',')
return 1;
else
return 0;
}

rete_neurale calcola_feed_forward (rete_neurale rete)
//Calcola i valori di uscita dei nodi, dati gli ingressi
{
int N=rete.N+1;
int i,j,s,k;

//Per tutti i nodi di input Calcola il valore di uscita
//tramite la funzione teta di attivazione
for (j=1; j<=rete.nodi_input; j++)
{
// rete.nodo[j].valore_in=rete.nodo[j].valore_in-rete.nodo[j].soglia;
rete.nodo[j].valore=teta(rete.nodo[j].valore_in,rete.nodo[j].funzione_out);
}
//Per tutti i nodi Hidden
for(k=rete.nodi_input+1;k<=rete.N-rete.nodi_out;k++)
{
rete.nodo[k].valore_in=rete.nodo[k].soglia;
//Per tutti i nodi di input
for (i=1;i<=rete.nodi_input;i++)
rete.nodo[k].valore_in+=rete.nodo[i].valore*rete.w[k*N+i];
rete.nodo[k].valore=teta(rete.nodo[k].valore_in,rete.nodo[k].funzione_act);
}
//Per tutti i nodi di output
for(k=rete.N-rete.nodi_out+1;k<=rete.N;k++)
{
rete.nodo[k].valore_in=rete.nodo[k].soglia;
//Per tutti i nodi Hidden
for (i=rete.nodi_input+1;i<=rete.N-rete.nodi_out;i++)
rete.nodo[k].valore_in+=rete.nodo[i].valore*rete.w[k*N+i];
rete.nodo[k].valore=teta(rete.nodo[k].valore_in,rete.nodo[k].funzione_act);
}
return rete;
}





Ora il problema è il seguente:

Ho scritto questo banale codice main cercado di richiamare una funzione di struttura.c, ma all'atto della compilazione, il compilatore mi da il seguente errore:

LINKER ERROR: undefinied reference to next_tab

Dove sbaglio????

Questo è il codice main:

#include "struttura.h"
#include <stdio.h>
#include <stdlib.h>



main()

{

char buf[] = "ciao pirla;";
int ind;

printf("\n\nProva utilizzo libreria:\n\n");

ind = next_tab(buf, 0);
getch();
return 0;
}

Tengo a precisare che: Ho provato sia a creare un progetto che non, ma nulla di fatto. Tutti i file .h e .c stanno nella stessa cartella.

Torav
28-09-2007, 19:05
nelle opzioni del progetto devi linkare la libreria .c precompilata oppure aggiungere struttura.c nel progetto. ora sto su linux e non posso dirti esattamente come fare, non mi ricordo :p

sonique
28-09-2007, 20:52
Grazie un milione TORAV..
appena hai finito mi dici con Dev come linkare la libreria .c?

Grazie ancoea