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

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

Δημοσ.

Καλησπέρα,

Επειδή είμαι καινούργιος στο προγραμματισμό πως εαν έχω ενα αρχείο arxeio.dat

 

20

Onoma Epitheto

50

60

Onoma Epitheto

40

20

.

.

.

 

 

κ έχω

 

>  FILE *fp;


 if((fp=fopen("arxeio.dat","r"))==NULL)
 {
   printf("error");
   system("pause");
   
  }

θελω να διαβάζει ξεχωριστά το πρώτο στοιχείο τ αρχείου δλδ το 20

κ μετά

γίνεται με μια for

for(j=1;j<=4;j++)

{

fscanf(fp"%c %c %i %i",&b,&c,&d,&e); //b thelw na vazei onoma , c epitheto

}

 

ξέρω οτι το παραπάνω είναι λάθος αλλά θέλω να διαβάζει τ πρώτα 3 τ αρχείου να τ εκχωρεί κ μετά στ επόμενα 3!πως γίνεται αυτο?ή μήπως δεν ειναι εφικτό?

 

ο δείκτης fp δείχνει το στοιχείο 20 κ εαν κάνω fp++ πάει στο επόμενο στοιχείο του αρχείο?

 

Μας έβαλαν ένα project κ δεν μας έχουν μάθει αυτά αλλά δυστυχώς χρειάζεται κατι τέτοιο!

Δημοσ.

Αυτό θα κάνει τη δουλειά σου:

 

>   int i, num1, num2, j;
  char first_name[20];
  char last_name[20];
  
  fscanf(fp, "%i", &i);
  
  for(j=1;j<=4;j++){
   fscanf(fp, "%s %s %i %i", first_name, last_name, &num1, &num2);
   printf("%s %s %i %i \n", first_name, last_name, num1, num2);
  }
  fclose(fp);

 

Διαβάζεις τον πρώτο αριθμό i, και μετά διαβάζεις μέσα στο loop τα επόμενα 2 strings και 2 integers σε κάθε επανάληψη!

Δημοσ.

Για αυτές τις δουλειές είναι προτιμότερη η χρήση της fgets() για διάβασμα της κάθε γραμμής του αρχείου, ώστε να έχουμε κατόπιν πλήρη έλεγχο στα δεδομένα που θα "τραβήξουμε" μέσα από την κάθε γραμμή.

 

Για παράδειγμα, ο προηγούμενος κώδικας προκαλεί segmentation fault (κρασάρισμα) αν κάποια γραμμή περιέχει περιέχει περισσότερους από 19 χαρακτήρες... με τη fscanf() δεν υπάρχει έλεγχος για το μήκος του string, επίσης αφήνει τον file-pointer σε απροσδιόριστη θέση αν αποτύχει.

 

Σου έγραψα πρόχειρα κώδικα με χρήση της fgets()... διαβάζει κάθε γραμμή, "τραβάει" τα δεδομένα που θέλει (linedata) και τα τυπώνει για επιβεβαίωση...

 

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

#define LINE_MAXSIZE			(1023+1)
#define FULLNAME_MAXSIZE		(25+1)

int main( void )
{
struct linedata {				/* to store parsed data	*/
	char 	fullname[ FULLNAME_MAXSIZE ];
	int	fld1, fld2;
} linedata;

int n = 0;
char line[ LINE_MAXSIZE] = {'\0'};		/* to read a file line */
FILE *fp = fopen("main.dat", "r");		/* open the file */

if ( !fp ) {
	fputs( "*** read error: cannot open file\n", stderr );
	exit( EXIT_FAILURE );
}

/* read 1st line and convert it to inetger (n) */
if ( !fgets(line, LINE_MAXSIZE, fp) ) {
	fputs( "*** read error: cannot read 1st line\n", stderr );
	goto exit_failure;
}
n = atoi( line );

/* read n groups of lines, each consisting of 3 lines */
while ( n-- )
{						/* read a group of 3 lines...*/
	int i = 0;				/* store & print their data  */
	for (i=0; i < 3 && fgets(line, LINE_MAXSIZE, fp); i++ )
	{
		if ( i == 0 ) {
			line[ strlen(line)-1 ] = '\0';
			strncpy( linedata.fullname, line, FULLNAME_MAXSIZE-1 );
			printf( "%s ", linedata.fullname );
		}
		else if ( i  == 1 ) {
			linedata.fld1 = atoi( line );
			printf("%d ", linedata.fld1 );
		}
		else if ( i == 2 ) {
			linedata.fld2 = atoi( line );
			printf("%d\n", linedata.fld2 );
		}
	}
}

fclose( fp );

exit( EXIT_SUCCESS );

exit_failure:

fclose( fp );

exit( EXIT_FAILURE );
}

Δημοσ.

Για αυτές τις δουλειές είναι προτιμότερη η χρήση της fgets() για διάβασμα της κάθε γραμμής του αρχείου, ώστε να έχουμε κατόπιν πλήρη έλεγχο στα δεδομένα που θα "τραβήξουμε" μέσα από την κάθε γραμμή.

 

Για παράδειγμα, ο προηγούμενος κώδικας προκαλεί segmentation fault (κρασάρισμα) αν κάποια γραμμή περιέχει περιέχει περισσότερους από 19 χαρακτήρες... με τη fscanf() δεν υπάρχει έλεγχος για το μήκος του string, επίσης αφήνει τον file-pointer σε απροσδιόριστη θέση αν αποτύχει.

 

Σου έγραψα πρόχειρα κώδικα με χρήση της fgets()... διαβάζει κάθε γραμμή, "τραβάει" τα δεδομένα που θέλει (linedata) και τα τυπώνει για επιβεβαίωση...

 

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

#define LINE_MAXSIZE			(1023+1)
#define FULLNAME_MAXSIZE		(25+1)

int main( void )
{
struct linedata {				/* to store parsed data	*/
	char 	fullname[ FULLNAME_MAXSIZE ];
	int	fld1, fld2;
} linedata;

int n = 0;
char line[ LINE_MAXSIZE] = {'\0'};		/* to read a file line */
FILE *fp = fopen("main.dat", "r");		/* open the file */

if ( !fp ) {
	fputs( "*** read error: cannot open file\n", stderr );
	exit( EXIT_FAILURE );
}

/* read 1st line and convert it to inetger (n) */
if ( !fgets(line, LINE_MAXSIZE, fp) ) {
	fputs( "*** read error: cannot read 1st line\n", stderr );
	goto exit_failure;
}
n = atoi( line );

/* read n groups of lines, each consisting of 3 lines */
while ( n-- )
{						/* read a group of 3 lines...*/
	int i = 0;				/* store & print their data  */
	for (i=0; i < 3 && fgets(line, LINE_MAXSIZE, fp); i++ )
	{
		if ( i == 0 ) {
			line[ strlen(line)-1 ] = '\0';
			strncpy( linedata.fullname, line, FULLNAME_MAXSIZE-1 );
			printf( "%s ", linedata.fullname );
		}
		else if ( i  == 1 ) {
			linedata.fld1 = atoi( line );
			printf("%d ", linedata.fld1 );
		}
		else if ( i == 2 ) {
			linedata.fld2 = atoi( line );
			printf("%d\n", linedata.fld2 );
		}
	}
}

fclose( fp );

exit( EXIT_SUCCESS );

exit_failure:

fclose( fp );

exit( EXIT_FAILURE );
}

 

 

 

 

Ευχαριστώ πάρα πολύ κάτι τέτοιο έψαχνα.Αλλά γίνεται να σπάσω μετά το fullName σε firstName και lastName?

Δημοσ.

Αυτό θα κάνει τη δουλειά σου:

 

>   int i, num1, num2, j;
  char first_name[20];
  char last_name[20];
  
  fscanf(fp, "%i", &i);
  
  for(j=1;j<=4;j++){
   fscanf(fp, "%s %s %i %i", first_name, last_name, &num1, &num2);
   printf("%s %s %i %i \n", first_name, last_name, num1, num2);
  }
  fclose(fp);

 

Διαβάζεις τον πρώτο αριθμό i, και μετά διαβάζεις μέσα στο loop τα επόμενα 2 strings και 2 integers σε κάθε επανάληψη!

 

 

Ευχαριστώ ;)

Δημοσ.

Ευχαριστώ πάρα πολύ κάτι τέτοιο έψαχνα.Αλλά γίνεται να σπάσω μετά το fullName σε firstName και lastName?

 

Παρακαλώ :)

 

Θα χρειαστεί να το προσαρμόσεις στις ανάγκες σου όμως.

 

ΥΓ. Ο κώδικας του φίλου totel_lost έχει το πρόβλημα που ανέφερα στο προηγούμενο ποστ (που είναι γενικότερο πρόβλημα της fscanf() )

Δημοσ.

Παρακαλώ :)

 

Θα χρειαστεί να το προσαρμόσεις στις ανάγκες σου όμως.

 

ΥΓ. Ο κώδικας του φίλου totel_lost έχει το πρόβλημα που ανέφερα στο προηγούμενο ποστ (που είναι γενικότερο πρόβλημα της fscanf() )

 

Η fgets εξασφαλίζει μέρος της μνήμης?ή πρεπει να κάνω κ malloc?

Δημοσ.

Η fgets εξασφαλίζει μέρος της μνήμης?ή πρεπει να κάνω κ malloc?

 

Όχι, δεν έχει σχέση με δυναμική διαχείριση μνήμης η fgets()... αυτή απλά χρησιμοποιεί το string που θα της περάσεις, καθώς και το μέγιστο μήκος που θα της περάσεις για το string αυτό. Το πως θα το έχεις δημιουργήσει εσύ το string αυτό και με τι μέγιστο μήκος, δεν την απασχολεί ούτε εξετάζει κάτι τέτοιο.

 

ΥΓ. Μάλλον έχεις αρκετά κενά στα c-strings, ρίξε μια ματιά στο link της υπογραφής μου ( το γράφω πολύ συχνά αυτό, αλλά πραγματικά με γλιτώνει από πολύ διπλο-γράψιμο ;) )

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

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

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

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

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

Σύνδεση

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

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