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

Τράβηγμα από αρχείο, εισαγωγή σε πίνακα struct


AfterForever

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

Δημοσ. (επεξεργασμένο)

Καλημέρα. 

Έστω ότι έχω ένα αρχείο με εναλλάξ ονόματα και νούμερα. Εχω και μια δομή με 2 πεδία (όνομα & νούμερο) και έχω δημιουργήσει με malloc ένα πίνακα τύπου αυτής της δομής.

typedef struct {
    char name[MAXSTRING];
    int id;
}student;

stArray=malloc(lines*sizeof(student)); 

(όπου lines είναι οι γραμμές που έχει το αρχείο κειμένου, τις έχω υπολογίσει πιο πρίν).

Προσπαθώ να κάνω το εξής: τραβάω με fgets γραμμή γραμμή και στις μονές γραμμές με strcpy τα βάζω στον πίνακα των δομών στο πεδίο με τα ονόματα (έχω δεσμεύσει χώρο κανονικά πιο πριν) και στις ζυγές τα μετατρέπω σε ακεραίους και τα βάζω στην ίδια θέση του πίνακα στο πεδίο με το id. 

	k=0;
	while(!feof(f)){
        k++;
        fgets(s,MAXSTRING,f);
        if(k%2!=0){
            strcpy(stArray[k].name,s);
        }
        else{
            stArray[k].id=atoi(s);
        }
        NUMBER_OF_STUDENTS+=1;
    }
	

Τα δεδομένα τραβιούνται κανονικά από το αρχείο γιατί κάθε φορά που χρησιμοποιώ τη fgets κάνω printf και φαίνονται κανονικότατα όλα. Καλά ως εδώ. Μάλλον κάποια κουταμάρα όταν πάω να τα βάλω στον πίνακα, γιατί μετά όταν θέλω να πάω να εκτυπώσω τον πίνακα με τη δομή μου και κάνω αυτό:

	for(i=0;i<k;i++){
        printf("%s\t",stArray[i].name);
        printf("%d\n",stArray[i].id);
    }
	

 

Βγαίνουν αλαμπουρνέζικα....

Καμιά ιδέα; Θεωρώ ότι εδώ έχει γίνει το λάθος γι' αυτό δεν κάνω παράθεση όλο τον κώδικα. Οποιαδήποτε βοήθεια ευπρόσδεκτη!

Ευχαριστώ.

Επεξ/σία από AfterForever
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημοσ. (επεξεργασμένο)
	#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
	
#define MAXSTRING 15
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
	int NUMBER_OF_STUDENTS=0;
	typedef struct {
    char name[MAXSTRING];
    int id;
}student;
	void printMenu();
void print(student st);
void printstudents(student *stArray);
student* load(char *filename); // anaktisi listas foititwn apo arxeio
void save(char *filename,student *stArray); //apothikeusi listas foititwn se arxeio
int addStudent(student st, student *stArray); //prosthiki neou student
student* findStudent(int id, student *stArray); //search vasei id
int deleteStudent(student st, student *stArray); // diagrafei vasei tou st.id
int updateStudent(student st, student *stArray); //ananeosi vasei id
	
int main(int argc, char *argv[]) {
    //srand(time(null); 
    
    char c,k;
    int lines,i,j,temp;
    char *s;
    
    lines=0;
    FILE *f;
    f=fopen("test.txt","r");
    while(!feof(f)){
        fscanf(f,"%c",&c);
        if(c=='\n'){
            lines++;
        }
    }
    printf("oi grammes einai:\t %d \n",lines);
    
    student *stArray;
    stArray=malloc(lines*sizeof(student));
    fseek(f,0,SEEK_SET);
    
    i=0;
    k=0;
    s=malloc(MAXSTRING*sizeof(char));
    while(!feof(f)){
        k++;
        fgets(s,MAXSTRING,f);
        if(k%2!=0){
            strcpy(stArray[k].name,s);
        }
        else{
            temp=atoi(s);
            //printf("%d\t",temp);
            stArray[k].id=temp;
        } 
        NUMBER_OF_STUDENTS+=1;
    }
    NUMBER_OF_STUDENTS/=2;
    printf("%d\n",NUMBER_OF_STUDENTS);
	
    for(i=0;i<k;i++){
        printf("%s\t",stArray[i].name);
        printf("%d\n",stArray[i].id);
    }

    free(s);
    free(stArray);
    fclose(f);
    
    return 0;
}
 
	

Το αρχείο μου έχει αυτό το περιεχόμενο και στην έξοδο μου εμφανίζονται τα παρακάτω:

aaaaa
1
bbbbb
2
ccccc
3
ddddd
4
	
	oi grammes einai:        7
4
ωx┤     1818321775
aaaaa
        1414222661
OP-3EKOPV0      1
bbbbb
        1769096293
ve=D:\OneDrive  2
ccccc
        1917085038
ive     3
ddddd
        285230626
	

Ενώ οι μονές γραμμές με τα ονόματα εμφανίζονται κανονικότατα, στα ids γίνεται μπάχαλο, εκεί δηλαδή που κάνω 

printf("%d\n",stArray[i].id);

 

 

Επεξ/σία από AfterForever
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημοσ. (επεξεργασμένο)

Δεν ξέρω, το αρχείο txt το έφτιαξα με το notepad....

Πως το βλέπω; Λες να φταίει η κωδικοποίηση;;

Βλέπετε γενικώς κάποιο λογικό λάθος στην υλοποίηση;; 

Ευχαριστώ και για τις απαντήσεις παιδιά!

Επεξ/σία από AfterForever
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Είσαι σίγουρος? Είναι έτσι?
 

strcpy(stArray[k/2].name,s);

Επίσης, μάλλον πρέπει να κάνεις το "k++" στο τέλος της λούπας αντί για την αρχή, και να κάνεις "if (k%2 == 0)".

  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημοσ. (επεξεργασμένο)

Μερικά από τα προβλήματα που εντόπισα στον κώδικα

a) το k καλό είναι να δηλωθεί int και όχι char

b) Να αρχικοποιείς τις μεταβλητές, να καθαρίζεις τον χώρο που πιάνεις για τις δυναμικές μεταβλητές

π.χ. 

s[0]='\0';

memset(stArray, 0 , lines*sizeof(student));

c) μέσα στην while το k δηλώνει γραμμή αρχείου στον πίνακα όμως είναι μία γραμμή ανά δύο γραμμές αρχείου άρα θα πρέπει

όπου έχεις δείκτη στον πίνακα να είναι k/2

d) όταν κάνεις strcpy θα πρέπει να παίρνεις μόνο το μέγεθος του s (βγάζεις newline, βάζεις τελικό '\0')

strncpy(stArray[k/2].name, s,strlen(s)-2);

 

( το παρακάτω δεν χρειάζεται μιας και στην αρχή έχεις κάνει 0 όλο τον χώρο που έπισασες με την malloc

και θα πρέπει στο τέλος του να προσθέτεις και το '\0'

(stArray[k/2].name)[strlen(s)] = '\0';

)

 

ΥΓ. Μάθε να χρησιμοποιείς τον debugger. Θα σε βοηθήσει ΠΑΡΑ ΠΟΛΥ στο να γράφεις κώδικα

 

Επεξ/σία από newnick
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

3 ώρες πριν, AfterForever είπε

Βγαίνουν αλαμπουρνέζικα....

Καμιά ιδέα; Θεωρώ ότι εδώ έχει γίνει το λάθος γι' αυτό δεν κάνω παράθεση όλο τον κώδικα. Οποιαδήποτε βοήθεια ευπρόσδεκτη!

Κάνεις λάθος στο μέτρημα (number of students). 

Άλλαξε τα εξής (μέσα στη δεύτερη while(!feof(f)))

1.  strcpy(stArray[k].name,s); ----> strcpy(stArray[NUMBER_OF_STUDENTS].name,s);

2.  stArray[k].id=temp;  ----> stArray[NUMBER_OF_STUDENTS].id=temp;

3. Πρόσθεση την: if(k%2 == 0) πριν την NUMBER_OF_STUDENTS+=1;

δηλαδή να έχεις τα εξής:

    while(!feof(f)){
        k++;
        
        fgets(s,MAXSTRING,f);
        if(k%2!=0){
            strcpy(stArray[NUMBER_OF_STUDENTS].name,s);
        }
        else{
            temp=atoi(s);
            //printf("%d\t",temp);
            stArray[NUMBER_OF_STUDENTS].id=temp;
        } 
        if(k%2 == 0)
            NUMBER_OF_STUDENTS+=1;
    }

4. Βγάλε την NUMBER_OF_STUDENTS/=2;  μετά τη while

5. Στη for της print άλλαξε το k με NUMBER_OF_STUDENTS

δηλαδή να έχεις: 

    for(i=0;i<NUMBER_OF_STUDENTS;i++){
        printf("%s\t",stArray.name);
        printf("%d\n",stArray.id);
    }

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημοσ. (επεξεργασμένο)

Σας ευχαριστώ πολύ όλους. 

Τελικά τα κατάφερα με μικροδιορθώσεις χάρη στη βοήθεια σας.

Μια άλλη ερώτηση.

Μπορώ με τη realloc να δεσμεύσω ΕΠΙΠΛΕΟΝ χώρο στο τέλος της stArray; ή Ό,τι έχω δεσμεύσει από την αρχή;

δοκίμασα αυτό:

	int addStudent(student st, student *stArray){ //prosthiki neou student
	    stArray=realloc(stArray,(NUMBER_OF_STUDENTS+1)*sizeof(student));
    if(stArray){
        stArray[NUMBER_OF_STUDENTS].id=st.id;
        strcpy(stArray[NUMBER_OF_STUDENTS].name,st.name);
        NUMBER_OF_STUDENTS++;
        return 1;
    }
    return 0;
}
 
	

Η λογική μου είναι η εξής. Η stArray έχει NUMBER_OF_STUDENTS θέσεις. Οπότε της δεσμεύω άλλη μία επιπλέον και μετά στην τελευταία θέση (αυτή που μόλις δημιουργήσα) βάζω τα δεδομένα μου. Και στο τέλος αυξάνω την global μεταβλητή NUMBER_OF_STUDENTS.

Μετά όμως δε μου εκτυπώνει τον stArray σωστά, βλέπετε κάποιο λογικό λάθος;

Και πάλι 1000 ευχαριστώ!

 

 

Επεξ/σία από AfterForever
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

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

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

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

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

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

Σύνδεση

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

Συνδεθείτε τώρα
  • Δημιουργία νέου...