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

C first Program


Επισκέπτης

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

Δημοσ.

χτες αρχισα να ασχολουμε για αρχη με την c

 

βλεπωντας μερικα βιντεο απο το υτ

 

ι μαδε δις προγγραμ φορ ιου /* GreekLish */

 

 

>www.megaupload.com/?d=J2MUPBK4

 

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

 

πειτε μου λαθη που εκανα :rolleyes:

 

 

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

 

 

θανκ ιου

Δημοσ.

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

 

Δηλαδή η μεταβλητή να περιέχει μια πρόταση πχ? Μπορείς δηλώσεις ένα μονοδιάστατο πίνακα τύπου χαρακτήρων.

 

char name[];

 

ή

 

char name[15]; αν θέλεις να έχει συγκεκριμένο μέγεθος πχ 15 χαρακτήρων. Στην πραγματικότητα ομαδικοποιείς πολλές μεταβλητές χαρακτήρων.

 

Ψάξε στο google για arrays.

Δημοσ.

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

 

πειτε μου λαθη που εκανα :rolleyes:

Το βασικότερο είναι πως επιτρέπεις να γίνεται διαίρεση με το 0 (π.χ. 10/0), πράγμα που οδηγεί σε κρασάρισμα του προγράμματός σου.

 

Επίσης, δεν είναι λάθος αλλά το getch() δεν είναι στάνταρ C... ούτε το conio.h header file ( http://c-faq.com/osdep/cbreak.html ). Αν δεν σε ενδιαφέρει η συμβατότητα και είσαι σε Windows, μπορείς να χρησιμοποιήσεις το...

 

>
#include <stdlib.h>
...
system("pause");

Αν σε ενδιαφέρει η συμβατότητα, μπορείς να φτιάξεις δικιά σου συνάρτηση η οποία θα περιμένει να πατηθεί ENTER (για τον λόγο που εξηγεί το link που σου έδωσα παραπάνω). Αυτό όμως προϋποθέτει πως θα έχεις εξοικειωθεί πρώτα με τα strings και τη διαχείρισή τους, διότι το διάβασμα ενός μόνο χαρακτήρα με στάνταρ συναρτήσεις της C υπόκειται και αυτό στο γενικότερο line-buffering input που χρησιμοποιούν ως default οι γραμμές εντολών.

 

Οπότε καλύτερα να έχεις μια γενική συνάρτηση που θα περιμένει να διαβάσει σε ένα string όσους χαρακτήρες της πεις και θα καθαρίζει και το input buffer σε περίπτωση που ο χρήστης πληκτρολογήσει περισσότερους (ENTER θα πρέπει να πατηθεί έτσι κι αλλιώς).

 

Μια έτοιμη συνάρτηση που το κάνει (χωρίς όμως να καθαρίζει τους έξτρα χαρακτήρες από το input buffer) είναι η fgets(), η οποία διαβάζει από το πληκτρολόγιο αν το 3ο της όρισμα είναι το: stdin, με τη διαφορά πως κρατάει μέσα στο string και το ENTER που πατάει ο χρήστης.

 

Οπότε, ένας γρήγορος & βρώμικος (quick & dirty) τρόπος είναι να βάλεις στην αρχή του προγράμματός σου ένα macro σαν αυτό...

 

>
#include <stdio.h>

#define pressENTER()				\
do {					\
	char sLn__[256] = {'\0'};	\
	printf("\npress ENTER...");	\
	fgets(sLn__, 256, stdin);	\
	putchar('\n');			\
} while(0)

κι όταν θες να ζητάς από τον χρήστη να πατήσει ENTER για να συνεχίσει, να γράφεις...

 

>
pressENTER();

 

Με την προϋπόθεση πως ο χρήστης θα πατήσει ENTER πριν πληκτρολογήσει 254 χαρακτήρες, το παραπάνω δουλεύει μια χαρά. Αν πληκτρολογήσει όμως παραπάνω από 254 χαρακτήρες πριν πατήσει ENTER, τότε επανέρχεται το πρόβλημα του input-buffering για τους έξτρα χαρακτήρες.

 

Για να δεις το πρόβλημα, αντικατέστησε παραπάνω το 256 π.χ. με 3 και στο πρόγραμμά σου γράψε 3-4 συνεχόμενα: pressENTER()...

 

>
#include <stdio.h>

#define pressENTER()				\
do {					\
	char sLn__[3] = {'\0'};		\
	printf("\npress ENTER...");	\
	fgets(sLn__, 3, stdin);		\
	putchar('\n');			\
} while(0)

int main( void )
{
   pressENTER();
   pressENTER();
   pressENTER();

   return 0;
}

Όταν τρέξει το πρόγραμμα και σου ζητήσει να πατήσεις ENTER την 1η φορά, πριν πατήσεις το ENTER πληκτρολόγησε καμιά 10αριά χαρακτήρες. Θα διαπιστώσεις πως οι έξτρα χαρακτήρες που πληκτρολόγησες την 1η φορά θα χρησιμοποιηθούν "αυτόματα" ως input στα επόμενα pressENTER();

 

Ο λόγος είναι πως το input στη γραμμή εντολών γίνεται ανά γραμμή (line buffering) και οι έξτρα χαρακτήρες δεν καθαρίζονται αυτόματα! Οπότε ότι περισσεύει από αυτό που περιμένεις να διαβάσεις (2 χαρακτήρες δλδ στο παραπάνω παράδειγμα) παραμένει στο input buffer και διαβάζεται από την επόμενη εντολή διαβάσματος "αυτόματα"!

 

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

 

Παρόλο που στα Windows η έτοιμη συνάρτηση: fflush( stdin ) καθαρίζει το input buffer, δυστυχώς ούτε αυτή είναι στάνταρ σε όλες τις πλατφόρμες (συγκεκριμένα το στάνταρ της γλώσσας ορίζει ως undefined ή ως implementation dependent τη συμπεριφορά της fflush() όταν καλείται με όρισμα ένα input stream).

 

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

 

Μια πιθανή εκδοχή τέτοιας συνάρτησης, η οποία μάλιστα αντίθετα με την fgets(..., ..., stdin) διαγράφει και το ENTER από το τέλος του διαβασμένου string, είναι η παρακάτω:

 

>
/* -----------------------------------------------------------------------------------
* ΣΥΝΑΡΤΗΣΗ: s_getflushed
*	βελτιωμένη παραλλαγή της fgets για την κύρια είσοδο (σβήνει το '\n' + fflush)
*
*	Διαβάζει από την κύρια είσοδο έως len-1 χαρακτήρες ή μέχρι να πατηθεί ENTER,
*	τους καταχωρεί στο s και το επιστρέφει με μηδενισμένο τον τελικό χαρακτήρα.
*	Αν πληκτρολογήθηκαν len-1 χαρακτήρες πριν πατηθεί το ENTER, τότε οι περιττοί
*	χαρακτήρες αφαιρούνται από το buffer της εισόδου (stdin).
*/
char *s_getflushed(char *s, size_t len)
{
char *cp;
for (cp=s; (*cp=getc(stdin)) != '\n' && (cp-s) < len-1; cp++ )
	;

if ( *cp != '\n') {				/* len reached withoutn '\n' */
	*cp = '\0';				/* null terminate s and      */
	while (getchar() != '\n')		/* flush remaining chars     */
		;
}
else						/* '\n' found                */
	*cp = '\0';				/* null-terminate            */

return s;
}

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

 

>
#include <stdio.h>

#define pressENTER()				\
do {					\
	char sLn__[1] = {'\0'};		\
	printf("\npress ENTER...");	\
	s_getflushed(sLn__, 1);		\
	putchar('\n');			\
} while(0)


/* -----------------------------------------------------------------------------------
*
* -----------------------------------------------------------------------------------
*/
char *s_getflushed(char *s, size_t len)
{
       char *cp;
       for (cp=s; (*cp=getc(stdin)) != '\n' && (cp-s) < len-1; cp++ )
               ;

       if ( *cp != '\n') {                             /* len reached withoutn '\n' */
               *cp = '\0';                             /* null terminate s and      */
               while (getchar() != '\n')               /* flush remaining chars     */
                       ;
       }
       else                                            /* '\n' found                */
               *cp = '\0';                             /* null-terminate            */

       return s;
}

/* -----------------------------------------------------------------------------------
*
* -----------------------------------------------------------------------------------
*/
int main( void )
{
   pressENTER();
   pressENTER();
   pressENTER();

   return 0;
}

 

Όλα τα παραπάνω είναι απολύτως φυσιολογικό να σου φαίνονται... κινέζικα, μιας και τώρα ξεκινάς.

 

Βασικά δεν χρειάζεται καν να χρησιμοποιήσεις string για να ζητήσεις ένα απλό ENTER από τον χρήστη (δες παρακάτω). Τα έγραψα όμως διότι μπορεί να αποδειχτούν ιδιαιτέρως ωφέλιμα όταν αρχίσεις να ασχολείσαι με strings, ιδιαίτερα η συνάρτηση: s_getflushed()

 

Σε γενικές γραμμές πρέπει να ξέρεις πως όλες οι στάνταρ συναρτήσεις διαβάσματος στη C υποφέρουν από το πρόβλημα των έξτρα "σκουπιδιών" στο input buffer.

 

Επίσης, τώρα που είσαι στην αρχή, μάθε όσο μπορείς ταχύτερα τα βασικά των strings και ΣΤΑΜΑΤΑ να χρησιμοποιείς την scanf() για το διάβασμα της κύριας εισόδου! Αντί αυτής, μάθε να χρησιμοποιείς την fgets() σε συνδυασμό με την sscanf() ή με τις atoi(), atol(), atof(). Είναι πολύ σημαντικό να απεμπλακείς όσο το δυνατόν νωρίτερα από την scanf(), η οποία είναι πηγή πολλών προβλημάτων! Σε όλα τα GUI αλλά και σε όλα τα σοβαρά προγράμματα, το input και το output γίνεται υπό μορφή string.

 

Δηλαδή...

α) διαβάζουμε το input ως string (με fgets(), s_getflushed(), κλπ)

β) το σπάμε στις μεταβλητές που μας ενδιαφέρουν (συνήθως με sscanf(), atoi(), atol(), atof(), ενίοτε και σε συνδυασμό με την strtok() )

γ) υπολογίζουμε ότι μεταβλητές είναι να υπολογίσουμε και για το αποτέλεσμα δημιουργούμε ένα string (συνήθως με την sprintf(), σε συνδυασμό με τις strncpy(), strncat(), κλπ)

δ) τυπώνουμε το τελικό string του αποτελέσματος (συνήθως με puts() ).

 

Το παραπάνω mentality, είναι αυτό που χρησιμοποιείται στην συντριπτική πλειοψηφία των GUI και των σοβαρών εφαρμογών, frameworks, κλπ.

 

Επιστρέφοντας τώρα στο θέμα με το pressENTER(), όπως σου έγραψα κάποια στιγμή πιο πάνω δεν χρειάζεσαι καν string. Βάλε στην αρχή του προγράμματός σου το εξής macro:

 

>
#include <stdio.h>

#define pressENTER()				\
do {					\
	printf("\npress ENTER...");	\
	while ( getchar() != '\n' )	\
		;			\
} while (0)

και όποτε θες να περιμένεις να σου πατήσει ENTER ο χρήστης, γράφε:

 

>
pressENTER();

 

Θα λειτουργεί απροβλημάτιστα για οποιοδήποτε input, εγγυημένα, σε οποιαδήποτε πλατφόρμα, σε οποιονδήποτε compiler (όπως και η παραλλαγή με τη s_getflushed() ) με την προϋπόθεση πως θα διαβάζεις χαρακτήρες 7-μπιτων ή 8-μπιτων γραμματοσειρών (όχι Unicode δηλαδή).

 

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

 

θανκ ιου

http://www.tutorialspoint.com/ansi_c/c_play_with_strings.htm

 

ΠΡΟΣΟΧΗ:

Στα παραδείγματα του link διαβάζει τα strings με την gets()... ΜΗΝ τη χρησιμοποιήσεις, προτίμησε την fgets()... η gets() έχει καταργηθεί γιατί δεν ελέγχει το μέγιστο μήκος του string που διαβάζει, ευνοώντας έτσι τη δημιουργία κρασαρισμάτων! Υπάρχει στους compilers απλά για λόγους συμβατότητας με τις αρχικές εκδόσεις της γλώσσας.

Δημοσ.

κατι αλλο:

 

#include <stdio.h>

#include <conio.h>

 

 

 

 

int main(void)

{

 

 

 

int dollar;

int euro;

 

 

 

 

 

 

 

 

printf("Please Enter Euro's: \n");

scanf("%d$", &euro);

dollar= euro * 1.394 ;

 

 

printf("%d"),dollar;

 

 

getch();

 

 

 

 

 

}

 

 

 

με βγαζει παντα αποτελεσμα 2293616

 

εκει που εβαλα

dollar= euro * 1.394 ;

αλλαξα το 1.394 με εναν ακεραιο αλλα παλι το ιδιο με βγαζει... γιατι??

Δημοσ.

κατι αλλο:

 

>#include <stdio.h>
#include <conio.h>




int main(void)
{

 
 
 int dollar;
 int euro;

 
 
 
 
 
 
 
  printf("Please Enter Euro's:   \n");
  scanf("%d", &euro);
  dollar= euro * 1.394 ;
         
 
   printf("%d"),dollar;
                             

 getch();
 
   
   
  	
   
 }


με βγαζει παντα αποτελεσμα 2293616

 

εκει που εβαλα

dollar= euro * 1.394 ;

αλλαξα το 1.394 με εναν ακεραιο αλλα παλι το ιδιο με βγαζει... γιατι??

> code..

Δημοσ.

printf("%d"),dollar;

 

Κανονικά πρέπει να σου βγάζει warning εδώ για τα ορίσματα της printf.

 

Από τυπογραφικό το ,dollar είναι έξω απ'την παρένθεση.

 

Δηλαδή εκτελείται η εντολή: printf("%d") αντί της printf("%d",dollar)

 

προσωπική άποψη: ζόρικη υπόθεση η εκμάθηση προγραμματισμού σε windows με IDE.

με τερματικό και gcc είναι πιο απλά τα πράγματα.

Δημοσ.

ναι ναι το dollar δεν ηταν στν παρενθεση .. αλλα πως να δειξω δεκαδικους??

Δημοσ.

ναι ναι το dollar δεν ηταν στν παρενθεση .. αλλα πως να δειξω δεκαδικους??

 

δανείσου ή αγόρασε ένα καλό βιβλίο.

Δημοσ.

Αυτο ειναι το δευτερο μου προγγραμα στην δευτερη μερα...

 

θημαμε στο Cmd ,,, στο .bat υπηρχε κατι σαν

 

:A

εβαζα κωδικους

 

και μετα παταγες goto A

 

κατι σαν loop υπαρχει κατι αναλογο στο C???

 

 

 

 

 

 

 

#include <stdio.h>

#include <conio.h>

 

 

/*

Name: Romario Hystuna

Copyright: 2011

Author: Hastounis

Date: 30/09/11 20:14

Description: First Program With C Language Created By Hastounis With Love For U...

*/

 

int main(void)

{

/*Variables*/

 

 

 

float dollar;

 

float euro;

int choose;

 

 

printf("Choose : Dollar To Euro. \n Press 1 \n");

printf("Choose : Euro To Dollar.\n Press 2 \n");

 

scanf("%d", &choose);

 

if(choose==1){

printf("Please Enter Euro's: ");

scanf("%f", &euro);

 

 

 

dollar= euro * 1.3424;

 

 

printf("Dollar = : %0.3f", dollar);

 

 

getch();

}

else if(choose==2){ printf("Please Enter Euro's: ");

scanf("%f", &euro);

dollar= euro / 1.3424;

 

printf("%0.3f",dollar);

 

 

 

 

getch();

}

}

Δημοσ.

κατι αλλο:

 

#include <stdio.h>

#include <conio.h>

 

int main(void)

{

int dollar;

int euro;

 

.........

 

dollar= euro * 1.394 ;

.........

 

 

}

 

με βγαζει παντα αποτελεσμα 2293616

 

εκει που εβαλα

dollar= euro * 1.394 ;

αλλαξα το 1.394 με εναν ακεραιο αλλα παλι το ιδιο με βγαζει... γιατι??

 

 

Εφόσον οι μεταβλητές dollar και euro είναι πραγματικοί αριθμοί τις δηλώνεις σαν float ή σαν double.

Επίσης αντί για int main(void) { να γράφεις μόνο main() {

Δημοσ.

...

Επίσης αντί για int main(void) { να γράφεις μόνο main() {

Αυτό είναι depreciated, έτσι ήταν στην 1η έκδοση της γλώσσας (K&R). Μια χαρά το γράφει: int main( void )... έτσι επιτάσσει το στάνταρ από το 1989 και μετά. Και μάλιστα πρέπει να βάζει κι ένα return 0; στο τέλος του προγράμματος. Οποιοσδήποτε σύγχρονος compiler θα του βγάλει warning αν δεν κάνει κάποιο από τα παραπάνω.

 

Όσο για τα loops, και το goto υπάρχει αλλά πρέπει να αποφεύγεται γιατί οδηγεί σε δυσνόητο κώδικα κι επιρρεπή σε bugs. Η γλώσσα παρέχει 3 loops: for, while και do-while.

Δημοσ.

Btw, ο κώδικας του 2ου πρόγραμματός σου, σύμφωνα με αυτά που είπαμε και στην 1η σελίδα και με χρήση ενός loop όταν ζητάει από τον χρήστη να διαλέξει, μπορεί να γίνει κάπως έτσι (για να έχεις κι ένα παράδειγμα να βλέπεις :) ):

 

>
#include <stdio.h>				/* για puts(), printf(), fgets(), ...   */
#include <stdlib.h>				/* για atoi(), atof(), system(), ...   */

/*
Name: Romario Hystuna
Copyright: 2011
Author: Hastounis
Date: 30/09/11 20:14
Description: First Program With C Language Created By Hastounis With Love For U...
*/

int main( void )
{
/* Variables (είναι πάντα σοφό να τις αρχικοποιούμε σε default τιμές )          */

char input[255+1] = {'\0'};		/* για διάβασμα input ως string         */
float dollar = 0.0, euro = 0.0;
int choose = 1;				/* επιλογή χρήστη                       */

do {
	puts("Choose :");
	printf("\t1. Dollar To Euro\n\t2. Euro to Dollar\n\t");
	fgets(input, 255+1, stdin);	/* διάβασμα του input ως string         */
	choose = atoi( input );		/* μετατροπή σε int & ανάθεση σε choose */
} while ( choose != 1 && choose != 2);

if ( choose == 1 )
{
	printf("Please Enter Euro(s): ");
	fgets(input, 255+1, stdin);	/* διάβασμα του input ως string         */
	euro = atof( input );		/* μετατροπή σε float & ανάθεση σε euro */

	dollar = euro * 1.3424;
	printf("Dollar = %.3f\n", dollar);
}
else	/* το loop παραπάνω εγγυάται πως το else εδώ αναφέρεται στην επιλογή 2  */
{
	printf("Please Enter Euro(s): ");
	fgets( input, 255+1, stdin );	/* διάβασμα του input ως string         */
	euro = atof( input );		/* μετατροπή σε float & ανάθεση σε euro */

	dollar = euro / 1.3424;
	printf("%.3f\n", dollar);
}

system("pause");		/* αναμονή οποιουδήποτε πλήκτρου (μόνο Windows) */

return 0;			/* σηματοδότηση επιτυχούς τερματισμού           */
}

Αρχειοθετημένο

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

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