Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

γεια σασ! προσπαθω εδω και μερες να κανω μια ασκηση στη C και εχω κολλησει στο πως γεμιζουμε εναν πινακα απο struct μεσω FILES .. :(

εχω κανει και ενα μερος του προγραμματος..

 

το προγραμμα μου ειναι το εξης :

 

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

 

typedef struct statisticalData{

char name[30];

int num_years;

int *years;

float *inflation, *aep, *investments;

float avg_infl, min_infl, max_infl;

float avg_aep, min_aep, max_aep;

float avg_inve, min_inve, max_inve;

}statData;

 

FILE *in_infl, *in_aep, *in_inve;

 

int loadData(statData *allData, int N, int M)

{

int i , j;

 

if((in_infl=fopen("inflation.ascii","r"))==NULL){

printf("to arxeio den uparxei \n");

exit(EXIT_FAILURE);

}

if((in_aep=fopen("aep.ascii","r"))==NULL){

printf("to arxeio den uparxei \n");

exit(EXIT_FAILURE);

}

if((in_inve=fopen("investments.ascii","r"))==NULL){

printf("to arxeio den uparxei \n");

exit(EXIT_FAILURE);

}

 

fclose(in_infl);

fclose(in_aep);

fclose(in_inve);

return 0;

}

 

 

main()

{

statData *allData;

int q, x,i, y, N=5,M=13;

 

 

allData=(statData*)malloc(N*sizeof(statData));

if(allData==NULL){

printf("MAlloc failed!\n");

exit(EXIT_FAILURE);

}

for(i=0; i<N; i++){

allData.inflation=(float*)malloc(M*sizeof(float));

allData.aep=(float*)malloc(M*sizeof(float));

allData.investments=(float*)malloc(M*sizeof(float));

allData.years=(int*)malloc(M*sizeof(int));

}

 

 

loadData(allData, N, M);

 

}

 

 

οποιαδηποτε βοηθεια επιθυμητη :-D :mrgreen:

  • Απαντ. 30
  • Δημ.
  • Τελ. απάντηση

Συχνή συμμετοχή στο θέμα

Συχνή συμμετοχή στο θέμα

Δημοσιευμένες Εικόνες

Δημοσ.

>#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct statisticalData{
char name[30];
int num_years;
int *years;
float *inflation, *aep, *investments;
float avg_infl, min_infl, max_infl;
float avg_aep, min_aep, max_aep;
float avg_inve, min_inve, max_inve;
}statData;

FILE *in_infl, *in_aep, *in_inve;

int loadData(statData *allData, int N, int M)
{
int i , j;

if((in_infl=fopen("inflation.ascii","r"))==NULL){
	printf("to arxeio den uparxei \n");
	exit(EXIT_FAILURE);
}
if((in_aep=fopen("aep.ascii","r"))==NULL){
	printf("to arxeio den uparxei \n");
	exit(EXIT_FAILURE);
}
if((in_inve=fopen("investments.ascii","r"))==NULL){
	printf("to arxeio den uparxei \n");
	exit(EXIT_FAILURE);
}

/* εδώ πρέπει να κάνεις την ανάγνωση από το αρχείο */


fclose(in_infl);
fclose(in_aep);
fclose(in_inve);
return 0;
}


main()
{
statData *allData;
int q, x,i, y, N=5,M=13;


allData=(statData*)malloc(N*sizeof(statData));
if(allData==NULL){
	printf("MAlloc failed!\n");
	exit(EXIT_FAILURE);
}
for(i=0; i<N; i++){
	allData[i].inflation=(float*)malloc(M*sizeof(float));	
	allData[i].aep=(float*)malloc(M*sizeof(float));
	allData[i].investments=(float*)malloc(M*sizeof(float));	
	allData[i].years=(int*)malloc(M*sizeof(int));
}


loadData(allData, N, M);

}

 

Στη σημείωση βλέπεις σε ποιό σημείο πρέπει να γίνει η ανάγνωση από το αρχείο σου.

Οι τρόποι που μπορείς να το κάνεις είναι διάφοροι (γραμμή - γραμμή, με διαχωρισμένα κομμάτια αν χρησιμοποιείς κάποιον delimiter, γράμμα-γράμμα κτλ...), ανάλογα με το πως είναι δομημένα τα αρχεία σου και με πόση λεπτομέρεια και ασφάλεια έλεις να δέχεσαι τα δεδομένα τους...

Δημοσ.

Το βασικότερο σου πρόβλημα είναι ότι είσαι σε λάθος section... μεταφέρεται στη ενότητα "προγραμματισμός"

Δημοσ.

σε αυχαριστω πολυ!

ναι ξερω που πρεπει να γινει και νομιζω οτι πρεπει να το κανω με fscanf..

εχω δοκιμασει πολλα αλλα δεν μου λειτουργουν σωστα..

οπως πχ αυτο.. εκει ακριβως που μου λες και εσυ! αλλα δεν μ εμφανιζει σωστα αποτελεσματα.. :( :mad:

 

συγγνωμη και ολας αλλα ειμαι καινουργια.. :P θα μαθω να στελνω με "χρωματα"... :D και ολα τα υπολοιπα..!

 

for(i=0; i<N; i++){

while(fscanf(in_infl,"%f",allData.inflation)!=EOF){

for(j=0; j<M; j++){

printf("%f ",allData.inflation[j]);

}

}

}

 

for(i=0; i<N; i++){

fscanf(in_infl,"%f",allData.inflation);

fscanf(in_aep,"%f",allData.aep);

fscanf(in_inve,"%f",allData.investments);

}

for(i=0; i<N; i++){

for(j=0; j<M; j++){

printf("%f",allData.inflation[j]);

}

}

Δημοσ.
  Στις 10/6/2012 στις 11:00 ΜΜ, alexcsk είπε

...

θα μαθω να στελνω με "χρωματα"... :D και ολα τα υπολοιπα..!

Απλά όταν είναι να αντιγράψεις κώδικα από το μηχάνημά σου εδώ στο φόρουμ, περιστοίχισέ τον μέσα σε code tags.

 

Δηλαδή...

 

[code ]

εδώ ο κώδικάς σου

[/code ]

 

(χωρίς κενό πριν τις δεξιές αγκύλες)

 

ΥΓ. Είμαι πολύ κομμάτια τώρα για να δω τον κώδικά σου. Αν δεν με προλάβει άλλος, θα του ρίξω μια ματιά αύριο.

Δημοσ.
  Στις 10/6/2012 στις 11:00 ΜΜ, alexcsk είπε

>for(i=0; i<N; i++){ /* ξεκινάς μια επανάληψη με δεδομένο ότι θα τρέξει Ν φορές, 
θεωρώ ότι το κάνεις για να διατρέξεις τον πίνακα */
	while(fscanf(in_infl,"%f",allData[i].inflation)!=EOF){ /* αυτή η επανάληψη θα τρέξει και θα διαβάσει όσα μπορεί
από το πρώτο loop της παραπάνω for */
	for(j=0; j<M; j++){
	printf("%f  ",allData[i].inflation[j]);
}
}
}

for(i=0; i<N; i++){
	fscanf(in_infl,"%f",allData[i].inflation);
	fscanf(in_aep,"%f",allData[i].aep); 
	fscanf(in_inve,"%f",allData[i].investments);			
}
for(i=0; i<N; i++){
        for(j=0; j<M; j++){
	        printf("%f",allData[i].inflation[j]);
        }
}

 

>
char buff[255];
for(int i=0; i < N; i++)
{
    fgets( buff, 254, in_infl );
    allData[i].inflation = (float) atof(buff); /* μετατρέπω τη σημβολοσειρά σε αριθμό */
}
...

 

ενδεικτικά θα μπορούσες να δοκιμάσεις κάτι τέτοιο...

Δώσε μας ένα δείγμα από το αρχειο που διαβάζεις. Με κενά χωρίζονται τα δεδομένα στο αρχείο;

Δημοσ.

ναι εχεις δικαιο.. να ενα αρχειο! με tab χωριζονται

  Αναφορά σε κείμενο

2.812 2.877 3.425 3.9933 2.0943 1.221 0.539 1.079 2.076 0.35 1.849 2.027 1.85

22.46 22.44 12.89 11.75 13.731 10.42 2.727 4.27 1.926 2.432 4.56 3.793 4.168

20.69 19.79 14.8 14.429 11.182 9.792 7.341 6.776 5.197 3.029 3.397 3.118 3.401

2.406 2.938 1.63 0.5298 0.0922 -0.5 -0.57 0.599 0.03 -1.29 -1.73 -1.23 -1.55

106.4 92.65 165.5 143.66 65.409 38.04 22.91 25.97 19.49 21.35 30.04 24.31 21.17

 

 

το εχω δοκιμασει τον πρωτο τροπο αλλα μου βγαζει πολλα μηδενικα στις θεσεις καποιων τιμων..

ο δευτερος μου βγαζει: hw3.c:39:27: σφάλμα: incompatible types when assigning to type ‘float *’ from type ‘float’

γι αυτη τη σειρα : allData.inflation = (float) atof(buff); .. :cry:

Δημοσ.
  Στις 11/6/2012 στις 12:19 ΜΜ, alexcsk είπε

ναι εχεις δικαιο.. να ενα αρχειο! με tab χωριζονται

 

 

το εχω δοκιμασει τον πρωτο τροπο αλλα μου βγαζει πολλα μηδενικα στις θεσεις καποιων τιμων..

ο δευτερος μου βγαζει: hw3.c:39:27: σφάλμα: incompatible types when assigning to type ‘float *’ from type ‘float’

γι αυτη τη σειρα : allData.inflation = (float) atof(buff); .. :cry:

Καλησπέρα, όντως χρειαζόταν να μας πεις σε τι μορφή είναι το αρχείο σου.

 

Από ότι μας δείχνεις, δεν χωρίζονται μόνο με tabs αλλά και με αλλαγή γραμμής κάθε 13 αριθμούς. Σε αυτές τις περίπτωση βολεύει να διαβάζεις το αρχείο σου γραμμή-γραμμή (με την fgets() ) και κατόπιν να "τραβάς" τα 13 νούμερα που περιέχει μέσα στον πίνακα inflation, φροντίζοντας ταυτόχρονα να λαμβάνεις υπόψη σου περιπτώσεις όπου το αρχείο περιέχει μη έγκυρα δεδομένα. Υποθέτω δεν θέλεις να "σκάει" το πρόγραμμά σου ;)

 

Σου παραθέτω μια τέτοια συνάρτηση. Διαβάζει κάθε γραμμή με fgets(), και κατόπιν "τραβάει" τα νούμερα στον πίνακα inflation χρησιμοποιώντας την strok (για να σπάσει τη γραμμή σε tokens) και την atof() που μετατρέπει strings σε floats.

 

Για μεγαλύτερο έλεγχο στην μετατροπή, αντί για atof() μπορείς να χρησιμοποιήσεις την strtod()

 

 

  Εμφάνιση κρυμμένου περιεχομένου

 

Αν το αρχείο σου δεν περιείχε αλλαγές γραμμών, αλλά είχε όλα τα νούμερα συνεχόμενα, τότε θα μπορούσες να χρησιμοποιήσεις μόνο την fscanf(), π.χ. κάπως έτσι...

 

 

  Εμφάνιση κρυμμένου περιεχομένου

 

Πέρα από τα παραπάνω, η δομή statData (που εγώ την λέω Data) που παρουσίασες, σε συνδυασμό με τον υπόλοιπο κώδικα που μας έδειξες, κρύβει πάρα πολλές παγίδες. Κυρίως στην δυναμική διαχείριση των δυναμικών πινάκων inflation, aep & investments, αλλά και του ίδιου του allData (που εγώ το ονομάζω σκέτο data).

 

Δεν ξέρω σε τι επίπεδο βρίσκεσαι, αλλά ο συγκεκριμένος κώδικας δεν θα έλεγα πως είναι για αρχάριους. Περισσότερο μου κάνει για επιπέδου αρχάριος προς μέσος. Όπως και να έχει, σου έγραψα ένα πρόγραμμα που δείχνει έναν τρόπο να διαχειρίζεσαι με σχετική ασφάλεια την δομή statData που μας παρουσίασες. Περιέχει τις 2 παραπάνω συναρτήσεις, και 2 ακόμα: μια που απελευθερώνει τη μνήμη όλου του data struct και μια που εκτυπώνει τα περιεχόμενα του πίνακα inflation.

 

Περιέχει και μερικά πραγματάκια ακόμα, όπως π.χ. το macro FREE() ως πιο ασφαλή εκδοχή της στάνταρ συνάρτησης: free(). Ελπίζω να σε βοηθήσει να ολοκληρώσεις το πρόγραμμά σου, μιας και αυτό που σου δίνω διαχειρίζεται μονάχα το πεδίο inflation της δομής Data...

 

 

  Εμφάνιση κρυμμένου περιεχομένου

 

 

Σημείωση: Ενδεχομένως να έχει bugs, δεν το έχω τεστάρει εκτενώς!

 

EDIT:

 

Άλλαξα την επιστροφή της load_data_inflation_raw() σε ...

>	return (n == i) && (0 == j);

Δημοσ.
  Στις 10/6/2012 στις 10:41 ΜΜ, lion2486 είπε

>
typedef struct statisticalData{
int *years;
float *inflation, *aep, *investments;
float avg_infl, min_infl, max_infl;
float avg_aep, min_aep, max_aep;
float avg_inve, min_inve, max_inve;
}statData;

Υπάρχει κάποιος λόγος που τα 4 πεδία είναι δείκτες και τα κάνεις malloc αντί να είναι απλά float/int όπως τα υπόλοιπα ?

 

  Στις 11/6/2012 στις 12:56 ΜΜ, migf1 είπε

Από ότι μας δείχνεις, δεν χωρίζονται μόνο με tabs αλλά και με αλλαγή γραμμής κάθε 13 αριθμούς. Σε αυτές τις περίπτωση βολεύει να διαβάζεις το αρχείο σου γραμμή-γραμμή (με την fgets() ) και κατόπιν να "τραβάς" τα 13 νούμερα που περιέχει μέσα στον πίνακα inflation, φροντίζοντας ταυτόχρονα να λαμβάνεις υπόψη σου περιπτώσεις όπου το αρχείο περιέχει μη έγκυρα δεδομένα. Υποθέτω δεν θέλεις να "σκάει" το πρόγραμμά σου ;)

 

Σου παραθέτω μια τέτοια συνάρτηση. Διαβάζει κάθε γραμμή με fgets(), και κατόπιν "τραβάει" τα νούμερα στον πίνακα inflation χρησιμοποιώντας την strok (για να σπάσει τη γραμμή σε tokens) και την atof() που μετατρέπει strings σε floats.

 

Για μεγαλύτερο έλεγχο στην μετατροπή, αντί για atof() μπορείς να χρησιμοποιήσεις την strtod()

Με πρόλαβε ο migf1. Και εγώ fgets+strtof θα πρότεινα. Επίσης για μεγαλύτερη ευκολία μπορείς αντί να έχεις όλες τις float μεταβλητές, να έχεις ένα πίνακα οπότε με ένα for να πετάς κατευθείαν τις τιμές στην ανάλογη θέση του πίνακα. Το κακό με αυτή την τεχνική είναι ότι μειώνεται η αναγνωσιμότητα γιατί δεν θα φαίνεται άμεσα αν η Χ θέση του πίνακα είναι πχ το aep ή κάτι άλλο.

 

 

 

 

[offtopic]

  Στις 11/6/2012 στις 12:56 ΜΜ, migf1 είπε

Περιέχει και μερικά πραγματάκια ακόμα, όπως π.χ. το macro FREE() ως πιο ασφαλή εκδοχή της στάνταρ συνάρτησης: free().

>
// macro for safer version of the function free() ... it saves us some typing too
#define FREE( p )			\
do {					\
if ( (p) ) {			\
	free( (p) );		\
	(p) = NULL;		\
}				\
}while(0)

 

Πιθανώς να μου διαφεύγει κάτι αλλά δεν είναι εγγυημένο ότι η free δεν θα κάνει τίποτα αν δεχτεί NULL ? Χρειάζεται if εδώ ?

[/offtopic]

Δημοσ.
  Στις 11/6/2012 στις 1:09 ΜΜ, imitheos είπε

...

[offtopic]

Πιθανώς να μου διαφεύγει κάτι αλλά δεν είναι εγγυημένο ότι η free δεν θα κάνει τίποτα αν δεχτεί NULL ? Χρειάζεται if εδώ ?

[/offtopic]

Το 'χαμε ξανασυζητήσει παλιότερα, αλλά ούτε εγώ θυμάμαι. Νομίζω χρειαζόταν στην προ-ANSI εποχή ή στην προ-C99 εποχή; Πάντως ακριβώς επειδή δεν θυμάμαι ακριβώς, το βάζω για να μαι καλυμμένος.

Δημοσ.

μπορεσα και την τελειωσα :-D :shifty: :shifty:

 

η βοηθεια σας πραγματικα με βοηθησε απιστευτα!!

 

:D σας αυχαριστω παρα πολυ!!

Δημοσ.
  Στις 11/6/2012 στις 1:09 ΜΜ, imitheos είπε
[..][offtopic]

Πιθανώς να μου διαφεύγει κάτι αλλά δεν είναι εγγυημένο ότι η free δεν θα κάνει τίποτα αν δεχτεί NULL ? Χρειάζεται if εδώ ?

[/offtopic]

 

  Στις 11/6/2012 στις 1:13 ΜΜ, migf1 είπε

Το 'χαμε ξανασυζητήσει παλιότερα, αλλά ούτε εγώ θυμάμαι. Νομίζω χρειαζόταν στην προ-ANSI εποχή ή στην προ-C99 εποχή; Πάντως ακριβώς επειδή δεν θυμάμαι ακριβώς, το βάζω για να μαι καλυμμένος.

Αν θυμάμαι καλά, η σύμβαση ότι το free αγνοούσε δείκτες σε NULL πήγαινε ως και την Microsoft-C 6.0 για DOS (!) δίχως προβλήματα για το σύστημα (μιλάμε για compiler c. '89-'90). Το ίδιο ισχύει και για την Turbo C++ 3 (c. '91 - '92). Φυσικά μπορεί να πηγαίνει ακόμα πιο πίσω (θα ήθελα πολύ να το δοκίμαζα με την Lattice-C για Amiga αλλά που τέτοια τύχη πια :D)

Δημοσ.
  Στις 11/6/2012 στις 2:13 ΜΜ, alexcsk είπε

μπορεσα και την τελειωσα :-D :shifty: :shifty:

 

η βοηθεια σας πραγματικα με βοηθησε απιστευτα!!

 

:D σας αυχαριστω παρα πολυ!!

Αν πρόκειται για άσκηση (το οποίο και υποθέτω, από το "την" που χρησιμοποίησης) ίσως να μη σε ενδιαφέρει και τόσο. Αν πρόκειται όμως για δουλειά, βεβαιώσου πως δεν έχεις memory-leaks ή αναπάντεχες εξόδους που ίσως να μην είναι ορατές στο run-time (π.χ. στον κώδικα που κάνει cleanup, πριν τερματίσει το πρόγραμμα).

 

Ένας γρήγορος τρόπος για το 2ο είναι να δεις τι τιμή επιστρέφει το πρόγραμμά σου στο λειτουργικό... αν είναι διάφορη του 0 κάπου υπάρχει πρόβλημα στον κώδικα (μιας και είδα πως χρησιμοποιείς exit(τιμή_επιστροφής) στον κώδικά σου). Πολλά IDE την αναφέρουν από μόνα τους, άλλα όχι.

 

Αν όχι, δοκίμασε να τρέξεις το πρόγραμμά σου μέσα από κάποιον debugger, οι περισσότεροι από αυτούς αναγράφουν την τιμή επιστροφής μόλις τερματίσεις το πρόγραμμά σου ή σου δείχνουν σε ποιο σημείο σκάει, αν δεν καταφέρει να τερματίσει.

 

Για τα memory leaks είναι πιο δύσκολο... χρειάζονται ειδικά εργαλεία.

.

Δημοσ.

ναι ειναι ασκηση! και αυτα που ηταν να ελενξω ειναι σωστα ^_^

 

δυστυχως ακομα δεν γνωριζω αυτα που μου ειπες.. :-( αλλα ευχαριστω για την συμβουλη B)

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα

  • Δημιουργία νέου...