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

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

Δημοσ.

Ξανακοιταξα μια άσκηση που ειχα κανει πιο παλιά και έχει κάποια προβλήματα.

 

>
/* Αντιστροφή της σειράς των λεξεων μιας πρότασης
*  INPUT : Hello man. 
*  OUTPUT : man Hello.
* */
//---------------------------------------------------------------------

#include <stdio.h>
#include <ctype.h>

int main(void)
{
 char ch , array[100]={'\0'};
 int i=0 , count , j;
 
 printf("Enter a sentence: ");
 
 while((ch=getchar())!='.' && ch != '?' && ch != '!' )
 {
  array[i++]=ch;
  putchar(ch);
 }
  
 putchar(ch);  // print single character 
 
 printf("\n Reversal of the characters of the words of the sentence: ");
 
 for(count= i-1; count>= 0; count--)
 {
 
 if( array[count] == ' ' || count == 0 )
 {
  if(count == 0)
   j=0;

else

j=count+1;  

while(isalpha(array[j]))
{
     printf("%c" , array[j]);
     ++j;
   
   }
    
   printf(" ");
}

}
 
 putchar(ch);
  
   return 0;
}
//----------------------------------------------------------------------

 

Πχ η isalpha() αγνοει τις αποστροφους και αν δωσω εισοδο you can't

θα μου φάει και τoν ' και τον t. Eπισης η εμφανιση της δευτερης if δεν μ αρεσει και τοσο βεβαια αν την παραλειψω χάνω το να εκτυπώσω το στοιχειο 0 κάθε φορά λογω j=count + i ; οποτε θα πρεπει να λεω στο χρηστη να αρχισει την προταση με ενα κενο αναγκαστικα πραγμα που δεν μ αρεσει.

Επισης πριν την εκτύπωση του τελευταιου χαρακτηρα που θα ειναι σημειο στιξης παλι δινει ενα κενο

δεν ξερω κατα ποσο μπορω να το αποφυγω αυτο.

 

Η βασικη ιδεα ειναι οτι αν πχ έχω την προταση hello man.

Τοτε array[0]='h'

....

array[7]='n'

 

Ξεκινά ο κωδικας να διασχιζει τον πινακα προς τα πισω μολις φτασει στο κενο

δινεται στο j η τιμη του count (που ειναι στο κενο) +1 για να το ξεπερασει και να εκτυπωσει τους επομενους

χαρακτηρες... μετα χρησιμοποιω την isalpha για να πιάσω το κάτω άκρο μιας λέξης πχ.

 

> Hello | man | how | are | you ? 

 

Το man περιβάλλεται απο 2 κενα μεσα στην προταση το 1ο κενο το ελεγχω με την 1η if ενω το 2ο (τελος της λέξης) με την isalpha().

 

Επ ευκαιρια μηπως γνωριζει κανεις σε Linux ποιος ειναι ο μέγιστος αριθμος χαρακτήρων που σε αφήνει ο φλοιός να πληκτρολογήσεις???? Στα Windows θυμαμαι οτι ειναι 256.

  • Απαντ. 1,6k
  • Δημ.
  • Τελ. απάντηση

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

Δημοσ.

 

 

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

#define MAXINPUT	(256+1)

/*********************************************************//**
*
*************************************************************
*/
int main( void )
{
char 	c, input[ MAXINPUT ] = {'\0'};
int 	i = 0;
bool 	onspace = false;

/* read phrase */
for (i=0; i < MAXINPUT-1 && '\n' != (c = getchar()) && c != '.' && c != '?'; i++)
	input[i] = c;
input[i] = '\0';

/* reverse words, keep same spaces in between */
for (; i > -1; i--)
{
	if ( isspace(input[i]) && !onspace ) {		/* on space-area      	*/
		printf( "%s%c", &input[i+1], input[i] );
		input[i+1] = '\0';
		onspace = true;
	}
	else if ( isspace( input[i] ) )			/* space-area has >1 chars*/
		putchar( input[i] );
	else						/* on non-space area  	*/
		onspace = false;
}
puts( input );

exit( EXIT_SUCCESS );
}

 

ΥΓ. Μη μου ζητήσεις να σου εξηγήσω κάνα σημείο αν δεν το κάνεις πρώτα trace μόνος σου :P

Δημοσ.

 

 

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

#define MAXINPUT	(256+1)

/*********************************************************//**
*
*************************************************************
*/
int main( void )
{
char 	c, input[ MAXINPUT ] = {'\0'};
int 	i = 0;
bool 	onspace = false;

/* read phrase */
for (i=0; i < MAXINPUT-1 && '\n' != (c = getchar()) && c != '.' && c != '?'; i++)
	input[i] = c;
input[i] = '\0';

/* reverse words, keep same spaces in between */
for (; i > -1; i--)
{
	if ( isspace(input[i]) && !onspace ) {		/* on space-area      	*/
		printf( "%s%c", &input[i+1], input[i] );
		input[i+1] = '\0';
		onspace = true;
	}
	else if ( isspace( input[i] ) )			/* space-area has >1 chars*/
		putchar( input[i] );
	else						/* on non-space area  	*/
		onspace = false;
}
puts( input );

exit( EXIT_SUCCESS );
}

 

ΥΓ. Μη μου ζητήσεις να σου εξηγήσω κάνα σημείο αν δεν το κάνεις πρώτα trace μόνος σου :P

 

> printf("Thank you migf1!  "); 

 

Oσο κάποιος δεν χρησιμοποιει την δυναμικη δεσμευση μνημης στα προγραμματα του μπορει να ποντάρει στο γεγονος οτι ο φλοιος θα κοψει τον χρήστη απο το να εισάγει περισσοτερους απο τους στανταρ χαρακτηρες (τους μεγιστους που επιτρεπει ο φλοιος πχ) αποτρεποντας ετσι το overflow/segmentation fault?

 

Προ λιγου ειδα οτι έχω τον στανταρ Bash φλοιο .

 

> ps -ef | grep $$ 

Δημοσ.

Όχι, δεν μπορεί να ποντάρει πουθενά παρά μόνο στον κώδικά του (τι πρόβλημα έχεις με τη χρήση μετρητή ή με όλες τις άλλες μεθόδους που έχουμε χιλιο-συζητήσει; )

Δημοσ.

Όχι, δεν μπορεί να ποντάρει πουθενά παρά μόνο στον κώδικά του (τι πρόβλημα έχεις με τη χρήση μετρητή ή με όλες τις άλλες μεθόδους που έχουμε χιλιο-συζητήσει; )

 

Και γιατι οριζεις 256+1 σαν MAXINPUT στο macros τοτε?

εννοεις 256 ωφέλιμους + 1 ο κενός? μαλλον δεν εχει να κανει

με το length στον φλοιο αυτο :D

 

Ποιο μετρητη λες τωρα??? χαθηκα :S

στον αναγραμματισμο δεν χρειαζοταν εισοδος απο τον χρηστη

δουλευες πανω σε εναν στανταρ πινακα 26 θεσεων.

 

Αν λες για τον κωδικα που μολις ποσταρισες θα τον δω πιο βραδακι

γιατι πρεπει να την κανω τωρα.

Δημοσ.

Και γιατι οριζεις 256+1 σαν MAXIPNUT στο macros τοτε?

εννοεις 256 ωφέλιμους + 1 ο κενός? μαλλον δεν εχει να κανει

με το length στον φλοιο αυτο :D

 

Ποιο μετρητη λες τωρα??? χαθηκα :S

 

Εννοώ τον μετρητή που και πάλι δεν έχεις βάλει στον κώδικα που παρέθεσες, με αποτέλεσμα να κρασάρει για είσοδο μεγαλύτερη των 99 χαρακτήρων. Ακριβώς το ίδιο πράγμα δηλαδή για το οποίο φάγαμε μια σελίδα προχτές.

 

Αντί να λες στους χρήστες να βάζουν λιγότερους από τόσους χαρακτήρες ή αντί να τους ρωτάς για τα όρια για να τα δεσμεύσεις δυναμικά ή αντί να ψάχνεις να ποντάρεις σε φλοιούς και περιβάλλοντα για να σε προστατεύσουν από overflow, βάλε έναν ρημαδο-μετρητή στο loop που διαβάζεις το string σου... τόσο δύσκολο είναι; Απορώ πραγματικά!

Δημοσ.

Εννοώ τον μετρητή που και πάλι δεν έχεις βάλει στον κώδικα που παρέθεσες, με αποτέλεσμα να κρασάρει για είσοδο μεγαλύτερη των 99 χαρακτήρων. Ακριβώς το ίδιο πράγμα δηλαδή για το οποίο φάγαμε μια σελίδα προχτές.

 

Αντί να λες στους χρήστες να βάζουν λιγότερους από τόσους χαρακτήρες ή αντί να τους ρωτάς για τα όρια για να τα δεσμεύσεις δυναμικά ή αντί να ψάχνεις να ποντάρεις σε φλοιούς και περιβάλλοντα για να σε προστατεύσουν από overflow, βάλε έναν ρημαδο-μετρητή στο loop που διαβάζεις το string σου... τόσο δύσκολο είναι; Απορώ πραγματικά!

 

Μια σκέψη ηταν οι VLA's δεν έγραψα κωδικα που να τους ορίζει με μεταβλητό μήκος , ο χρηστης δεν μπορει να ειναι σιγουρος αν αυτο που πληκτρολογησε ειναι οντως το οριο που έδωσε αρχικα. Μου κανε εντυπωση που οριζεις συνεχεια 256+1 και σκεφτηκα μηπως εχει σχεση με κάποιον περιορισμο απο τον φλοιο. Δεν εχω γραψει ακομη κανενα τετοιο προγραμμα . Δεν μπορω να καταλαβω σε τι θα σε βοηθησει ο μετρητης που λες ακομη και αν εχεις ορισει εξαρχης πριν μπεις στην main το μήκος στο 256+1 αν ο χρηστης δωσει 300 χαρακτηρες τι γινεται? και μετα πατησει ENTER.

 

Αν μπορεις δωσε ενα παραδειγμα 10 γραμμων. Αν οχι θα ξαναδιαβασω τα υπαρχοντα αν και το χθεσινο που ποσταρισες δεν θελω να το διαβασω ακομη για να λεω την αληθεια. Η βιβλιοθηκη που εβαλες. :shock:

Δημοσ.

...

Δεν μπορω να καταλαβω σε τι θα σε βοηθησει ο μετρητης που λες ακομη και αν εχεις ορισει εξαρχης πριν μπεις στην main το μήκος στο 256+1 αν ο χρηστης δωσει 300 χαρακτηρες τι γινεται? και μετα πατησει ENTER.

 

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

Συνέκρινε αυτό που κάνεις συνέχεια εσύ...

 

>
char array[100] = {'\0'};
int i = 0;

while ( (c=getchar()) != '\n' )
array[i++] = c;

με αυτό που κάνω συνέχεια εγώ...

 

>
char input[100+1] = {'\0'};
int i;
for ( i=0; i < 100 && '\n' != (c=getchar()); i++ )
input[i] = c;
input[i] = '\0';

Βάλε όπου 100 ας πούμε 3, και δώσε στην κύρια είσοδο 30 χαρακτήρες. Τι νομίζεις θα κάνει ο δικός σου κώδικας και τι ο δικός μου;

 

Η βιβλιοθηκη που εβαλες. :shock:

Ποια βιβλιοθήκη;

Δημοσ.

Συνέκρινε αυτό που κάνεις συνέχεια εσύ...

 

>
char array[100] = {'\0'};
int i = 0;

while ( (c=getchar()) != '\n' )
array[i++] = c;

με αυτό που κάνω συνέχεια εγώ...

 

>
char input[100+1] = {'\0'};
int i;
for ( i=0; i < 100 && '\n' != (c=getchar()); i++ )
input[i] = c;
input[i] = '\0';

Βάλε όπου 100 ας πούμε 3, και δώσε στην κύρια είσοδο 30 χαρακτήρες. Τι νομίζεις θα κάνει ο δικός σου κώδικας και τι ο δικός μου;

 

 

Ποια βιβλιοθήκη;

 

Ο δικος μου θα συνεχισει να εκχωρει χαρακτηρες μεχρι να βρει ENTER (το οποιο μπορει να βρει και αφοτου θα χει ξεπερασει το μεγιστο μηκος) ενω εσενα σταματα αν μια απο τις συνθηκες ελεγχου βγει ψευδης (ειτε δηλαδη παει πανω απο 100) ειτε βρει ENTER (κατω απο 100) ... πολυ ωραια πατεντα γιατι δεν το αφηνεις να φυγει απο τα ορια του αλλα δεν υπαρχει στον χθεσινο σου κωδικα με τον αναγραμματισμο και αυτο διοτι δεν χρειαζοταν επειδη οπως σου ειπα δουλευες πανω σε ενα στανταρ array που ειχε στανταρ τα 26 γραμματα του αλφαβητου ετσι δεν ειναι? Εγω παντως δεν βλεπω τετοια for ή και while ελπιζω παλι.... να μην με βγαλεις offside δες το και εσυ απο περιεργεια. :D

 

Η βιβλιοθηκη βρισκεται εδω ->

 

http://www.insomnia.gr/topic/437533-%CE%B5%CF%81%CF%89%CF%84%CE%AE%CF%83%CE%B5%CE%B9%CF%82-%CE%B3%CE%B9%CE%B1-c/page__st__190

 

5ο post απο την αρχη.

Δημοσ.

... πολυ ωραια πατεντα γιατι δεν το αφηνεις να φυγει απο τα ορια του αλλα δεν υπαρχει στον χθεσινο σου κωδικα με τον αναγραμματισμο και αυτο διοτι δεν χρειαζοταν επειδη οπως σου ειπα δουλευες πανω σε ενα στανταρ array που ειχε στανταρ τα 26 γραμματα του αλφαβητου ετσι δεν ειναι? Εγω παντως δεν βλεπω τετοια for ή και while ελπιζω παλι.... να μην με βγαλεις offside δες το και εσυ απο περιεργεια. :D

Πως γίνεται να ΜΗΝ σε βγάλω off-side, αφού ακριβώς για αυτό το πράγμα (ακριβώς όμως) έκανα πόστ όπου επισήμανα πως δεν χρησιμοποιώ μετρητή στον κώδικα γιατί δεν αποθηκεύω τις λέξεις που διαβάζω σε strings, και ακριβώς από κάτω μου απάντησες πως το ξέρεις αλλά με πειράζεις.

 

Δηλαδή είναι να τρελαίνεται κανείς μαζί σου Κώστα!

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

@migf1 ωραιος ο κωδικας σου με την αντιστροφή των λέξεων σε μια πρόταση

 

ωστοσο εκτύπωνε 2 κενά αναμεσα στις λέξεις (ακομη και αν ο χρηστης ειχε δωσει ενα)

 

>
kostas@kostas-SSL:~/PROGRAMS$ ./tests3
Give a sentence: a b c d
The reversal of the sentence: d c  b  a 
------------------------------------
// Mετά την πιο κάτω αλλαγή 
------------------------------------

kostas@kostas-SSL:~$ cd /home/kostas/PROGRAMS
kostas@kostas-SSL:~/PROGRAMS$ ./tests3
Give a sentence: a b c d
The reversal of the sentence: d c b a
 

 

 

επειδη έβαζες το string να τελειώνει στον i+1 οποτε έπαιρνε και το κενό + το κενό που εκτυπωνει

ετσι και αλλιως μεσα στην printf . Btw ωραιο το %s μεσα στην printf επισης που χειριζεσαι με την μια

την λεξη σαν string γλιτωνοντας ετσι απο πρόσθετο loop . Άλλαξα το

 

> input[i+1]='\0' σε input[i]='\0' 

 

για να μην εκτυπώνει 2 κενά.

 

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

 

http://ideone.com/vOced

Επεξ/σία από Star_Light
Δημοσ.

Έχω κάποιες απορίες σχετικά με τις μετατροπές τύπου σε εκφράσεις.

 

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

 

2.Ο short int "προάγεται" σε int κατα την αποτίμηση της έκφρασης.Ο int δεν είναι ας πούμε μία γενική κατηγορία που χωρίζεται σε short και long;Άρα,ο short int δεν θα έπρεπε να "προάγεται" σε long;

 

3.Όταν μετατρέπουμε για παράδειγμα έναν float σε double,το βιβλίο(οδηγός της C του Herbert Schildt)λέει ότι δεν αυξάνεται η ακρίβεια,απλά αλλάζει ο τρόπος με τον οποίο εμφανίζεται η τιμή.Ο double όμως έχει ακρίβεια δέκα ψηφίων και ο float έξι.Εννοεί ότι μόνο κατα την αποτίμηση της έκφρασης θα εμφανιστεί ως double και σ'όλο το υπόλοιπο πρόγραμμα θα λειτουργεί ως float;

 

4.Αν μετατρέψουμε ένα μεγάλο τύπο δεδομένων σε έναν μικρότερο,θα χαθούν κάποια bit.Αν μετατρέψουμε έναν long int π.χ. σε short όμως,μπορεί να παραχθεί μία "άχρηστη" τιμή.Δεδομένου όμως ότι εμείς προκαλέσαμε αυτή την μετατροπή,μπορούμε να πούμε ότι στην πραγματικότητα δεν υπάρχουν "άχρηστες" τιμές,σωστά(η ερώτηση είναι απλά ρητορική);

Δημοσ.

Έχω κάποιες απορίες σχετικά με τις μετατροπές τύπου σε εκφράσεις.

 

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

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

 

2.Ο short int "προάγεται" σε int κατα την αποτίμηση της έκφρασης.Ο int δεν είναι ας πούμε μία γενική κατηγορία που χωρίζεται σε short και long;Άρα,ο short int δεν θα έπρεπε να "προάγεται" σε long;

Ο int είναι τύπος όχι κατηγορία τύπων. Ο short είναι διαφορετικός τύπος από τον int και ομοίως και ο long int. Όπως αναφέρθηκε σε προηγούμενα μηνύματα, η προαγωγή των μικρότερων-από-int τύπων σε int γίνεται για να αποφευχθούν άσκοπες υπερχειλήσεις.

 

3.Όταν μετατρέπουμε για παράδειγμα έναν float σε double,το βιβλίο(οδηγός της C του Herbert Schildt)λέει ότι δεν αυξάνεται η ακρίβεια,απλά αλλάζει ο τρόπος με τον οποίο εμφανίζεται η τιμή.Ο double όμως έχει ακρίβεια δέκα ψηφίων και ο float έξι.Εννοεί ότι μόνο κατα την αποτίμηση της έκφρασης θα εμφανιστεί ως double και σ'όλο το υπόλοιπο πρόγραμμα θα λειτουργεί ως float;

Ο double έχει μεγαλύτερη ακρίβεια από τον float όπως είπες. Αυτή όμως είναι η μέγιστη ακρίβεια που παρέχει ο τύπος. Όταν εσύ αναθέτεις έναν float σε ένα double, τότε δεν μπορείς να εκμεταλλευτείς την παραπάνω ακρίβεια που παρέχει ο double γιατί πώς θα ξέρει το σύστημα τι τιμή θέλεις να αποθηκεύσεις ? Για παράδειγμα σκέψου ότι εγώ γράφω float f = 3.14. Άσχετα αν ο float έχει ακρίβεια έξι ή τριάντα ψηφίων, εγώ του έδωσα 2 δεκαδικά. Που να ξέρει ότι εγώ θέλω να γράψω 3.14159κτλ ?

Δημοσ.

Σκέψου το ως εξής :

 

Έστω ο float αποθηκεύει 4 δεκαδικά :

 

float a = 3.14;

 

3.|1|4|0|0|

 

και ο double 8

double b = a;

 

3.|1|4|0|0|0|0|0|0|

 

πλέον ο b έχει περισσότερο χώρο για μεγαλύτερη ακρίβεια, αλλά θα πρέπει να του ανατεθεί τιμή με μεγαλύτερη ακρίβεια.

 

Υ.Γ. οι τύποι κινητής υποδιαστολής δεν έχουν σταθερό χώρο για δεκαδικά ψηφία.

Δημοσ.

Καλησπέρα. Βασικα εχω το εξης θεματάκι (το οποιο δεν έχω προλαβει να το ψάξω πολυ μονος μου)

 

το θεμα ειναι συντακτικο... γιατι ρε σεις μου πεταει σφαλμα στο παρακατω? :S

 

> 

#include<stdio.h>
#define len 10

int array_max(int array[len] , int len)
{
int max , i ;

for(i=0; i<len; i++)
{
	if(array[i]> array[i+1])
	max= array[i];
	
	else
		max=array[i+1];
	}
		
	return max;
	
}

int main(void)
{
int array[len] , i , result;

printf(" Give the numbers of array: ");

for(i=0; i<len; i++)
scanf("%d" , &array[i]);

result= array_max(array,len);

printf(" The maximum element in the array is : %d " , result);

return 0;
}

 

> tests2.c:57: error: expected ‘;’, ‘,’ or ‘)’ before numeric constant 
tests2.c:83: warning: implicit declaration of function ‘array_max’

 

Και οταν πάω να κάνω ενα compound literal στο πιο κάτω (για να μην έχω την δηλωση του πινακα και στην main)

μου πεταει και εδω σφαλμα πχ

 

>

#include <stdio.h>
//#define  LEN  3

int sum_array(int a[] , int LEN )
{
int sum=0 , i;

for(i=0; i<LEN; i++)
sum += a[i];

return sum;
}	

int main( void )
{
//int a[]={0,1,2};
int result ;

result = sum_array((int a[]) {0,1,2} , 3);

printf("%d" , result);
   
      return 0;
}

 

> tests.c:19: error: expected ‘)’ before ‘a’
tests.c:19: warning: excess elements in scalar initializer
tests.c:19: warning: (near initialization for ‘(anonymous)’)
tests.c:19: warning: excess elements in scalar initializer
tests.c:19: warning: (near initialization for ‘(anonymous)’)
tests.c:19: warning: passing argument 1 of ‘sum_array’ makes pointer from integer without a cast
tests.c:4: note: expected ‘int *’ but argument is of type ‘int’

 

Στον πρωτο - πρωτο κωδικα πως θα μπορουσα να μην ξαναδηλωσω το i που χρησιμοποιω μεσα στο loop της συνάρτησης?

Μονο αν το δηλωνα σαν global μεταβλητη πχ το γλιτωνω? :P

Επισκέπτης
Αυτό το θέμα είναι πλέον κλειστό για περαιτέρω απαντήσεις.

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