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

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

Δημοσ.

Καλημέρα, θέλω να διαβασω απο το πληκτολογιο μια λεξη και να την βάλω δυναμικα σε έναν πινακα.Με εντερ να σταματαει η επαναληψη.Γίνεται να δουλέψω με malloc,strlen(ονομα πινακα) και για συνθήκη για το enter  να βαλω "\n"?

Ευχαριστω.

 

Δημοσ.

ναι, περίπου, γιατί μάλλον αυτό που δεν έχεις πιάσει καλά είναι ότι με τις συναρτήσεις εισόδου (πχ getchar) περιμένει \n για να συνεχίσει η εκτέλεση, για να πάρεις ολόκληρη λέξη πιο απλά κάνε το εξής:

char * buffer[255], * str;

fgets(buffer, 254, stdin);

str = mallon((strlen(buffer) + 1) * sizeof(char)) ;
strcpy(str, buffer);

στην ουσία διαβάζεις μια γραμμή (μέχρι αλλαγή της) το πολύ 254 χαρακτήρες. Ο "πίνακας" - συμβολοσειρά str (το ίδιο πράγμα είναι) έχει το μήκος της λέξης σου.

 

http://www.cplusplus.com/reference/cstdio/fgets/

  • Like 1
Δημοσ.

Μπορώ να σκεφτώ δύο to-the-point τρόπους:

 α) Χρήση scanf με format identifier %(LENOFWORD-1)s, όπου LENOFWORD το μέγεθος της λέξης μαζί με το nul.

 β) Χρήση επαναληπτικής κλήσης getchar, μέχρι ο χαρακτήρας που θα λάβεις να είναι whitespace.

 

Για την αποθήκευση της λέξης, θα μπορούσες να είχες έναν μεγαλούτσικο πίνακα με malloc και στη συνέχεια να τον κάνεις realloc.


ναι, περίπου, γιατί μάλλον αυτό που δεν έχεις πιάσει καλά είναι ότι με τις συναρτήσεις εισόδου (πχ getchar) περιμένει \n για να συνεχίσει η εκτέλεση, για να πάρεις ολόκληρη λέξη πιο απλά κάνε το εξής:

char * buffer[255], * str;

fgets(buffer, 254, stdin);

str = mallon((strlen(buffer) + 1) * sizeof(char)) ;
strcpy(str, buffer);

στην ουσία διαβάζεις μια γραμμή (μέχρι αλλαγή της) το πολύ 254 χαρακτήρες. Ο "πίνακας" - συμβολοσειρά str (το ίδιο πράγμα είναι) έχει το μήκος της λέξης σου.

 

http://www.cplusplus.com/reference/cstdio/fgets/

Πρέπει όμως να πατάει enter μετά από κάθε λέξη. Εκτός και αν παίξει με strtok.

Δημοσ.

 

Πρέπει όμως να πατάει enter μετά από κάθε λέξη. Εκτός και αν παίξει με strtok.

εγώ κατάλαβα ότι θα εισάγει μόνο μία λέξη με το enter.

  • Like 1
Δημοσ.

Αν έχω καταλάβει σωστά, το ερώτημα αφορά δυναμικό διάβασμα της εισόδου (stdin) μέσα σε ένα c-string, χωρίς να γνωρίζουμε εκ των προτέρων το μέγιστο μήκος. Αν ναι, τότε σε αυτές τις περιπτώσεις, η συνήθης προσέγγιση είναι να κάνουμε allocate-ahead το c-string, είτε κατά fixed πλήθος από bytes είτε διπλασιάζοντας το μέγεθός του, κάθε φορά που πάει να εξαντληθεί το buffer.

 

Ο παρακάτω κώδικας, σε spoiler, δείχνει μια τέτοια υλοποίηση:

 

 

 

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

#define AHEAD (size_t) 16  // alloc-ahead size, in bytes (MUST be non-zero positive)

/**********************************//**
 *
 **************************************
 */
int main( void )
{
	// initially, alloc AHEAD bytes for input (sz)
	size_t sz = AHEAD;
	char *input = malloc(sz);
	if ( 0 == sz || NULL == input ) {
		goto alloc_failed;
	}

	// read chars from stdin into input,
	// realloc AHEAD every time sz gets exhausted
	int c;
	size_t len = 0;
	while ('\n' != (c=getchar()) && EOF != c) {
		// realloc ahead if needed
		if ( len == sz-1 ) {
			sz += AHEAD;
			char *temp = realloc( input, sz );
			if ( 0 == sz || NULL == temp ) {
				goto alloc_failed;
			}
			input = temp;
		}
		// update input and len
		input[len++] = c;
	}
	// NUL terminate input
	input[len] = '\0';

	puts( input );
	printf( "sz = %zu, len = %zu\n", sz, len );

	free( input );
	return EXIT_SUCCESS;

alloc_failed:
	free( input );
	fprintf( stderr, "mem allocation failed, bye...\n" );
	return EXIT_FAILURE;
}

 

 

Μερικές διευκρινήσεις:

 

1. Το allocation-ahead γίνεται κατά fixed πλήθος bytes (AHEAD στον κώδικα) κάθε φορά που πάει να εξαντληθεί το buffer (και πιο συγκεκριμένα, 1 byte πριν εξαντληθει). Αν αντί αυτού θέλεις να διπλασιάζεις το buffer, μπορείς να αλλάξεις τη γραμμή:

sz += AHEAD
σε

sz += sz
2. Επειδή οι malloc(), calloc() και realloc() δεν επιστρέφουν NULL όταν τους περνάμε μηδενικό size, έχω βάλει τον πρόσθετο έλεγχο το sz να μην είναι 0 στις συνθήκες ελέγχου μετά το malloc() και το realloc(). Για τον ίδιο λόγο έχω βάλει και σχετικό σχόλιο στον ορισμό του AHEAD.

 

3. Αν χρησιμοποιείς gcc, παρέχει έτοιμη την συνάρτηση getline() που κάνει το ίδιο πράγμα. Μόνο που η getline() κρατάει και το ENTER, ενώ εγώ στον κώδικα το σβήνω (με '\0').

 

4. Αν όλα έχουν πάει καλά, ο κώδικας τυπώνει το c-string που διάβασε, και κατόπιν τυπώνει το μέγιστο και το τρέχον μήκος του (sz και len, αντίστοιχα).

 

5. Για ρεαλιστική χρήση, ο κώδικας πρέπει να μετατραπεί σε συνάρτηση, κατά προτίμηση με το AHEAD είτε να ορίζεται μέσα της "εφάπαξ" είτε να περνιέται ως παράμετρος.

Δημοσ.

ναι, περίπου, γιατί μάλλον αυτό που δεν έχεις πιάσει καλά είναι ότι με τις συναρτήσεις εισόδου (πχ getchar) περιμένει \n για να συνεχίσει η εκτέλεση, για να πάρεις ολόκληρη λέξη πιο απλά κάνε το εξής:

char * buffer[255], * str;

fgets(buffer, 254, stdin);

str = mallon((strlen(buffer) + 1) * sizeof(char)) ;
strcpy(str, buffer);

στην ουσία διαβάζεις μια γραμμή (μέχρι αλλαγή της) το πολύ 254 χαρακτήρες. Ο "πίνακας" - συμβολοσειρά str (το ίδιο πράγμα είναι) έχει το μήκος της λέξης σου.

 

http://www.cplusplus.com/reference/cstdio/fgets/

επειδη δεν κανω copypaste:το stdin αποτι καταλαβα ειναι "σαν" το keyboard να τον κανει φακελο, αντι για mallon γραφω  malloc, γραφω char buffer[225], *str.

Αν έχω καταλάβει σωστά, το ερώτημα αφορά δυναμικό διάβασμα της εισόδου (stdin) μέσα σε ένα c-string, χωρίς να γνωρίζουμε εκ των προτέρων το μέγιστο μήκος. Αν ναι, τότε σε αυτές τις περιπτώσεις, η συνήθης προσέγγιση είναι να κάνουμε allocate-ahead το c-string, είτε κατά fixed πλήθος από bytes είτε διπλασιάζοντας το μέγεθός του, κάθε φορά που πάει να εξαντληθεί το buffer.

 

Ο παρακάτω κώδικας, σε spoiler, δείχνει μια τέτοια υλοποίηση:

 

 

 

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

#define AHEAD (size_t) 16  // alloc-ahead size, in bytes (MUST be non-zero positive)

/**********************************//**
 *
 **************************************
 */
int main( void )
{
	// initially, alloc AHEAD bytes for input (sz)
	size_t sz = AHEAD;
	char *input = malloc(sz);
	if ( 0 == sz || NULL == input ) {
		goto alloc_failed;
	}

	// read chars from stdin into input,
	// realloc AHEAD every time sz gets exhausted
	int c;
	size_t len = 0;
	while ('\n' != (c=getchar()) && EOF != c) {
		// realloc ahead if needed
		if ( len == sz-1 ) {
			sz += AHEAD;
			char *temp = realloc( input, sz );
			if ( 0 == sz || NULL == temp ) {
				goto alloc_failed;
			}
			input = temp;
		}
		// update input and len
		input[len++] = c;
	}
	// NUL terminate input
	input[len] = '\0';

	puts( input );
	printf( "sz = %zu, len = %zu\n", sz, len );

	free( input );
	return EXIT_SUCCESS;

alloc_failed:
	free( input );
	fprintf( stderr, "mem allocation failed, bye...\n" );
	return EXIT_FAILURE;
}

 

 

Μερικές διευκρινήσεις:

 

1. Το allocation-ahead γίνεται κατά fixed πλήθος bytes (AHEAD στον κώδικα) κάθε φορά που πάει να εξαντληθεί το buffer (και πιο συγκεκριμένα, 1 byte πριν εξαντληθει). Αν αντί αυτού θέλεις να διπλασιάζεις το buffer, μπορείς να αλλάξεις τη γραμμή:

sz += AHEAD
σε

sz += sz
2. Επειδή οι malloc(), calloc() και realloc() δεν επιστρέφουν NULL όταν τους περνάμε μηδενικό size, έχω βάλει τον πρόσθετο έλεγχο το sz να μην είναι 0 στις συνθήκες ελέγχου μετά το malloc() και το realloc(). Για τον ίδιο λόγο έχω βάλει και σχετικό σχόλιο στον ορισμό του AHEAD.

 

3. Αν χρησιμοποιείς gcc, παρέχει έτοιμη την συνάρτηση getline() που κάνει το ίδιο πράγμα. Μόνο που η getline() κρατάει και το ENTER, ενώ εγώ στον κώδικα το σβήνω (με '\0').

 

4. Αν όλα έχουν πάει καλά, ο κώδικας τυπώνει το c-string που διάβασε, και κατόπιν τυπώνει το μέγιστο και το τρέχον μήκος του (sz και len, αντίστοιχα).

 

5. Για ρεαλιστική χρήση, ο κώδικας πρέπει να μετατραπεί σε συνάρτηση, κατά προτίμηση με το AHEAD είτε να ορίζεται μέσα της "εφάπαξ" είτε να περνιέται ως παράμετρος.

 

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

 

 

!!!!Θέλω να φτιαξω κρεμαλα οποτε θελω την λεξη σε πινακα για να δουλεψω.

Δημοσ.

επειδη δεν κανω copypaste:το stdin αποτι καταλαβα ειναι "σαν" το keyboard να τον κανει φακελο, αντι για mallon γραφω  malloc.

 

ναι malloc εννοούσα, στην ουσία "διαβάζεις" από την είσοδο σε έναν μεγάλο πίνακα από χαρακτήρες, και μετά δεσμεύεις μνήμη και αντιγράφεις όσους χαρακτέρες έχεις χτησιμοποιήσεις, μέχρι και το '\0'. Το char * a; είναι ίδιο με το char a[];, δηλαδή πίνακα αλλά χωρίς ακόμα ορισμένο μέγεθος. Όλοι οι χαρακτήρες είναι char , στην getchar χρησιμοποιούμε συνήθως Int για το λόγω ότι μπορεί και να μην επιστρέψει χαρακτήρα, π.χ. EOF.

  • Like 1
Δημοσ.

Αυτο που θελω είναι να μπορω να βλεπω τον καθε χαρακτηρα του πινακα για να κανω τα απαραιτητα για την κρεμαλα.

Δηλ. for(i=0;i<strlen(B)-1;i++){

              printf("%s",str);

Δημοσ.

επειδη δεν κανω copypaste:το stdin αποτι καταλαβα ειναι "σαν" το keyboard να τον κανει φακελο, αντι για mallon γραφω  malloc, γραφω char buffer[225], *str.

Το stdin είναι ένας δείκτης σε FILE (FILE *stdin), το οποίο FILE είναι ένα struct που περιγράφει αρχεία.

Περιέχει διάφορα πεδία τα οποία είναι σημαντικά για το buffering του stdio. Επιπλέον, το πιο σημαντικό

πεδίο που περιέχει είναι ο file descriptor.

 

Ο file descriptor είναι ένας ακέραιος που συμβολίζει τη θέση σε έναν πίνακα ο οποίος αποτελείται από

δείκτες σε δομές προσβασης. Για κάθε ανοικτό αρχείο* υπάρχουν τόσες δομές πρόσβασης, όσοι file

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

Οι δομές πρόσβασεις περιέχουν πεδία που έχουν σχέση με την πρόσβαση σε διάφορα αρχεία. Η stdio

δεσμεύει τις τρεις πρώτες θέσεις του πίνακα αυτού (0, 1 και 2) για την καθιερομένη είσοδο, έξοδο και έξο-

δο λάθους αντίστοιχα. Ή καλύτερα STDIN_FILENO, STDOUT_FILENO και STDERR_FILENO αντίστοιχα.

Αυτά τα τρία που ανέφερα είναι οι file descriptors για το πληκτρολόγιο, τερματικό και τερματικό. Αυτά περι-

έχονται όπως είπαμε ως πεδία στο structrure FILE. Οπότε και προκύπτουν τα "μαγικά" stdin, stdout και stderr.

Ο καθένας μπορεί να μπερδέψει την stdio και χωρίς να το γνωρίζει, ενώ εκτελεί μία printf, η οποία βγάζει

στο stdout, να βγάζει σε ένα αρχείο που ανοίξαμε με fopen.

 

*Για κάθε ανοικτό αρχείο, υπάρχει μόνο ένα *μοναδικό*(redundancy) i-node structure που το χαρακτηρίζει.

  • Like 1

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

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

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

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

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

Σύνδεση

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

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