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

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

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

Καλησπερα παιδια, εχω θεμα με τον κωδικα μου στην c. Η ασκηση σε γενικες γραμμες αποτελειται απο 6 κριτες οι οποιοι βαζουν βαθμο σε 20 διαγωνιζομενους και υπαρχουν καποιες προυποθεσεις για να περασουν στην επομενη φαση.Εχω δοκιμασει την fflush σε καποια σημεια αλλα τιποτα δεν δουλευει.Μια κρασαρει και μια εμφανιζει 6 φορες την εσωτερικη print διχως την scanf.Θα ηθελα την βοηθεια σας γιατι δεν μπορω να καταλαβω τι φταει.

 

Σας ευχαριστω εκ των προτερων 

 

Ο κωδικας :

  Αναφορά σε κείμενο

 

#include <stdio.h>

 
 
main()
{
    int orio,vathmos,max,min,ipopsifios,kritis,sunolo,mesosoros,i,pososto;
    char c1,c2;
 
    printf("Dwse orio epitropis:");
    scanf("%d",&orio);
    i=0;
    for (ipopsifios=1; ipopsifios<=20; ipopsifios++)
    {
        sunolo=0;
        printf("Dwse arxika onomatos kai epithetou\n");
        scanf("%c",&c1);
        scanf("%c\n",&c2);
        for (kritis=1; kritis<=6; kritis++)
        {
           max=1;
           min=100;
           printf("Dwse vathmo\n");
           scanf("%d\n",vathmos);
           if (vathmos<min)
           {
               min=vathmos;
               sunolo=sunolo+vathmos;
               continue;
           }
           if (vathmos>max)
           {
               max=vathmos;
               sunolo=sunolo+vathmos;
               continue;
           }
        }
         sunolo=sunolo-max-min;
         mesosoros=sunolo/6;
           if (mesosoros>=orio)
           {
               i=i+1;
               printf("Epilextike");
           }
 
    }
    pososto=(20-i)*0,1;
    printf("Ta atoma pou epilextikan itan %d\n",i);
    printf("To pososto twn atomwn pou den epilextikan einai %d%",pososto);
 
}
 

 

ΕDIT: Αλλαξα καποια πραγματα χωρις να εχω αποτελεσμα

 

http://prntscr.com/8z3n6b

Επεξ/σία από golto4
  • Moderators
Δημοσ.

 

pososto=(20-i)*0,1;

 

Μάλλον δεν ήθελες να γράψεις αυτό. Το κόμμα δεν είναι υποδιαστολή, η τελεία είναι η υποδιαστολή.

Δημοσ.

Ναι ξεχαστηκα ευχαριστω :) Περα απο αυτο βλεπεις πουθενα αλλου προβλημα?

  Στις 4/11/2015 στις 8:19 ΜΜ, Kercyn είπε
pososto=(20-i)*0,1;

Μάλλον δεν ήθελες να γράψεις αυτό. Το κόμμα δεν είναι υποδιαστολή, η τελεία είναι η υποδιαστολή.

 

Δημοσ.

 sunolo=0;
        printf("Dwse arxiko onomatos\n");
        scanf(" %c",&c1);
        printf("Dwse arxiko epithetou\n");
        scanf(" %c",&c2);
        for (kritis=1; kritis<=6; kritis++)
        {
           vathmos = 0;
           max=1;
           min=100;
           printf("Dwse vathmo:\n");
           scanf(" %d",&vathmos);

Λοιπόν αν και εγώ αρχάριος στην C. Με λίγο Google βρήκα ότι το scanf() διαβάζει το newline του προηγούμενου Input ως αποτέλεσμα οπότε δεν παίρνει καμία τιμή από τον χρήστη και συνεχίζει κανονικά.

Ο τρόπος να δουλέψει κανονικά είναι να βάλεις αυτό το κενό που έχω χρησιμοποιήσει πχ( " %d"...) γιατί δεν διαβάζει τα whitespace,newline etc. Επίσης ακομα και αυτό να μην υπήρχε σαν πρόβλημα δεν έχεις βάλει το &vathmos οπότε απλά θα χανόταν η εισαγωγή ακόμα και αν την διάβαζε.

 

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

 

Επίσης στο mesosoros = sum /6 να ξέρεις ότι το αποτέλεσμα χάνει το δεκαδικό του μερος επειδή έχεις δηλώσει το mesosoros ως int(=ακέραια) και όχι float ή double(πραγματική και αναλόγως την ακρίβεια που θες χρησιμοποιείς ένα από τα δυο με την double να πέρνει περισσοτερα ψηφία μετά την υποδιαστολη!)

 

Ελπίζω να βοήθησα!

Δημοσ.

Και γω αρχαριος (2 μαθηματα μολις γαρ). Μια παρατηρηση στο απο πανω σχολιο. Αν το κανει mesosoros = sum / 6.0 θα του εμφανισει το αποτελεσμα με ενα δεκαδικο. Αν βαλει αλλο ενα 0 στο 6 με 2 κ.ο.κ

 

Αποστολή από το Lenovo A820 με τη χρήση Insomnia App

Δημοσ.
  Στις 5/11/2015 στις 3:20 ΠΜ, manos89 είπε

Και γω αρχαριος (2 μαθηματα μολις γαρ). Μια παρατηρηση στο απο πανω σχολιο. Αν το κανει mesosoros = sum / 6.0 θα του εμφανισει το αποτελεσμα με ενα δεκαδικο. Αν βαλει αλλο ενα 0 στο 6 με 2 κ.ο.κ

Δεν ισχύει αυτό. Το δεκαδικό το χάνει επειδή ακριβώς είναι int όπως είπε ο kaliakmana. Ίσως το είδες στην περίπτωση που το mesosoros είναι float ή σε κάποιο printf και το παρεξήγησες.

 

#include <stdio.h>

int main(void)
{
	int sunolo, mo1;
	float mo2;

	sunolo = 50;
	mo1 = sunolo / 6;
	printf("mo1=%d\n", mo1);
	mo1 = sunolo / 6.0;
	printf("mo1=%d\n", mo1);
	mo1 = sunolo / 6.00;
	printf("mo1=%d\n", mo1);

	mo2 = sunolo / 6;
	printf("mo2=%f\n", mo2);
	mo2 = sunolo / 6.0;
	printf("mo2=%f\n", mo2);
	mo2 = sunolo / 6.00;
	printf("mo2=%f\n", mo2);
	printf("printf=%f\n", sunolo / 6.0);
	printf("printf=%3.9f\n", sunolo / 6.0);

	return 0;
}
Έξοδος:
mo1=8
mo1=8
mo1=8
mo2=8.000000
mo2=8.333333
mo2=8.333333
printf=8.333333
printf=8.333333333
Το τι είδους πράξη γίνεται εξαρτάται από τους τελεστέους. Όταν διαιρείς το sunolo που είναι ακέραιος με το 6 που είναι επίσης ακέραιος, τότε γίνεται ακέραια διαίρεση και χάνεται το δεκαδικό. Αν γράψεις 6.0 (με οσαδήποτε μηδενικά στο τέλος) τότε όντως θα γίνει διαίρεση πραγματικών αριθμών αλλά επειδή η μεταβλητή mo1 στην οποία αποθηκεύεται το αποτέλεσμα είναι ακέραια, και πάλι χάνεται το δεκαδικό.

 

Αν η μεταβλητή mesosoros έχει πραγματικό τύπο (η mo2 στο δικό μου παράδειγμα), τότε ισχύει αυτό που είπες στο περίπου. Το sunolo / 6 είναι και πάλι ακέραια διαίρεση οπότε παίρνεις 8.0 αποτέλεσμα άσχετα που αποθηκεύεται σε float. Αν έχεις διαίρεση πραγματικών αριθμών, τότε παίρνεις το σωστό αποτέλεσμα χωρίς όμως να παίζουν ρόλο τα μηδενικά που βάζεις στο 6.

 

Αν αυτό που είδες ήταν μέσα σε κάποιο printf, τότε έχουμε την ίδια περίπτωση αλλά αντί το αποτέλεσμα να αποθηκεύεται σε κάποια μεταβλητή, έχουμε το format της printf που κρίνει το πώς θα εμφανιστεί το αποτέλεσμα. Στο δικό μου παράδειγμα έχω βάλει το 6.0 για να θεωρηθεί πραγματικός και έχω επιλέξει %f οπότε εμφανίζεται σωστά. Και πάλι όμως δεν παίζει ρόλο πόσα μηδενικά θα βάλω στο 6.0. Το πόσα μηδενικά (ή πιο σωστά πόσα δεκαδικά ψηφία) θα εμφανιστούν εξαρτάται από το πόσα ζητάς στο printf όπως φαίνεται από το 2ο printf που έχω βάλει.

  • Like 1
Δημοσ.

Σας ευχαριστω ολους για τις απαντησεις σας.Λοιπον εγω προσθεσα το & στην scanf (το οποιο κρασαρε το exe συνεχεια) και εκανα float το mesosoros επομένως το αποτέλεσμα θα είναι ακέραιος άσχετα με το ακέραιο 6?

Δημοσ.

Το κενό το έβαλες όμως για να δέχεται βαθμούς και να μην τα προσπερναει;

 

 

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

Δημοσ.

golto4

Πρέπει να διαβάσεις με τη σειρά τα εξής topics:
 

  1. Τύποι μεταβλητών (γνωστό και ως types of variables)
  2. Αλλαγή τύπων μεταβλητών (γνωστό και ως casting)
  3. Πεδίο ζωής και ισχύς μεταβλητών (γνωστό και ως scope)
  4. Πέρασμα μεταβλητών σε συναρτήσεις (δύο τρόποι: pass by value και pass by reference.. στην ουσία είναι ένας, αλλά άσε το αυτό προς το παρόν)
  5. Δείκτες (γνωστοί και ως pointers)

Με τόσα videos στο youtube και με τόσα εργαλεία και tutorials στο internet γενικότερα, εάν συνεχίσεις να ρωτάς για τέτοια θέματα τότε απλά βαριέσαι να κάνεις κάτι μόνος σου και περιμένεις έτοιμο/μασημένο φαγητό. 

Δημοσ.
  Στις 5/11/2015 στις 2:46 ΜΜ, groot είπε

golto4

 

Πρέπει να διαβάσεις με τη σειρά τα εξής topics:

 

  • Τύποι μεταβλητών (γνωστό και ως types of variables)
  • Αλλαγή τύπων μεταβλητών (γνωστό και ως casting)
  • Πεδίο ζωής και ισχύς μεταβλητών (γνωστό και ως scope)
  • Πέρασμα μεταβλητών σε συναρτήσεις (δύο τρόποι: pass by value και pass by reference.. στην ουσία είναι ένας, αλλά άσε το αυτό προς το παρόν)
  • Δείκτες (γνωστοί και ως pointers)
Με τόσα videos στο youtube και με τόσα εργαλεία και tutorials στο internet γενικότερα, εάν συνεχίσεις να ρωτάς για τέτοια θέματα τότε απλά βαριέσαι να κάνεις κάτι μόνος σου και περιμένεις έτοιμο/μασημένο φαγητό.
Μαλλον το παιδί είναι σε σχολή (όπως και εγω)και αυτή είναι άσκηση οπότε καλό θα ήταν κάποια από αυτά που γράφεις να μάθει από τον καθηγητή και όχι μόνος του καθώς κάτι pointers και λοιπά δεν είναι τόσο εύκολα. Λογικά μέχρι cast θα έχουνε μάθει μέχρι αυτό το σημείο.. Το θέμα εδώ είναι ότι η scanf είναι πολύ περίεργη και μάλιστα πολλοί καθηγητές την αφήνουν για ποιο μετά που εξηγουν διεύθυνση μεταβλητων κτλ
Δημοσ.
  Στις 5/11/2015 στις 2:53 ΜΜ, kaliakman είπε

Μαλλον το παιδί είναι σε σχολή (όπως και εγω)και αυτή είναι άσκηση οπότε καλό θα ήταν κάποια από αυτά που γράφεις να μάθει από τον καθηγητή και όχι μόνος του καθώς κάτι pointers και λοιπά δεν είναι τόσο εύκολα. Λογικά μέχρι cast θα έχουνε μάθει μέχρι αυτό το σημείο.. Το θέμα εδώ είναι ότι η scanf είναι πολύ περίεργη και μάλιστα πολλοί καθηγητές την αφήνουν για ποιο μετά που εξηγουν διεύθυνση μεταβλητων κτλ

 

 

Οπότε, θα πρέπει να πω στο "παιδί" τι ακριβώς να διαβάσει σχετικά με το επίπεδό του; Μήπως να του γράψω να παίρνει και αναπνοές καθώς διαβάζει για να μην το ξεχάσει και πάθει ανακοπή; 

 

Από εκεί και πέρα, το type casting θα πρέπει να το έχει πει ο καθηγητής. Εάν δεν το κατάλαβε, υπάρχουν τόσα tutorials και γενικά ό,τι έγραψα πριν στο post μου. 

  • Like 1
Δημοσ.

Το "παιδί" το χρησιμοποίησα εν τη ρημη του λόγου... Δεν είπα κάτι τέτοιο απλά προφανώς είναι (και είμαι εννοείται) αρχάριος ειδικά αν η μόνη του επαφή ήταν η γλώσσα της 3ης λυκείου όπου υπάρχει χαωτικη διάφορα με την C οπότε για πρώτη γλώσσα νομίζω είναι καλύτερο να υπάρχει κάποιος να τον καθοδήγησει για να μην μάθει μισά πράγματα..

 

Και γενικά είναι απλα η άποψη μου ως κάποιος που βρίσκεται στην "αρχη"...δεν χρειάζεται το εχθρικο ύφος (δεν είναι η πρώτη φορά)

  • Like 1
Δημοσ.
  Στις 5/11/2015 στις 12:19 ΠΜ, kaliakman είπε
 sunolo=0;
        printf("Dwse arxiko onomatos\n");
        scanf(" %c",&c1);
        printf("Dwse arxiko epithetou\n");
        scanf(" %c",&c2);
        for (kritis=1; kritis<=6; kritis++)
        {
           vathmos = 0;
           max=1;
           min=100;
           printf("Dwse vathmo:\n");
           scanf(" %d",&vathmos);

Λοιπόν αν και εγώ αρχάριος στην C. Με λίγο Google βρήκα ότι το scanf() διαβάζει το newline του προηγούμενου Input ως αποτέλεσμα οπότε δεν παίρνει καμία τιμή από τον χρήστη και συνεχίζει κανονικά.

Ο τρόπος να δουλέψει κανονικά είναι να βάλεις αυτό το κενό που έχω χρησιμοποιήσει πχ( " %d"...) γιατί δεν διαβάζει τα whitespace,newline etc. Επίσης ακομα και αυτό να μην υπήρχε σαν πρόβλημα δεν έχεις βάλει το &vathmos οπότε απλά θα χανόταν η εισαγωγή ακόμα και αν την διάβαζε.

 

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

 

Επίσης στο mesosoros = sum /6 να ξέρεις ότι το αποτέλεσμα χάνει το δεκαδικό του μερος επειδή έχεις δηλώσει το mesosoros ως int(=ακέραια) και όχι float ή double(πραγματική και αναλόγως την ακρίβεια που θες χρησιμοποιείς ένα από τα δυο με την double να πέρνει περισσοτερα ψηφία μετά την υποδιαστολη!)

 

Ελπίζω να βοήθησα!

 

 

 

Βασικά όχι πως είναι και τρελά σημαντικο αλλα αν πχ δώσεις στην scanf το vathmos σκέτο χωρις το & απλα θα πάει να βάλει την εισοδο σε μια θέση μνημης η οποια προσδιορίζεται από το vathmos :

 
int vathmos;  // estw oti se auto o xrhsths tha dwsei to 5
 
scanf("%d" , vathmos);  // Tha apothikeusei to 5 sti thesi mnimis 5 trexa gureue
 

Θα φάς ισως ένα seg fault αλλιως μπορει να πηγαινε να το αποθηκευσει σε σημειο που υπάρχει κατι άλλο στη μνήμη δεν θα χανοταν απλώς εκεινο που θα υπηρχε εκει στην μνημη θα χανοταν αλλα το λειτουργικο έχει δικλειδες ασφαλειες και όταν πας να κανεις μλκια τρως ακυρο.

Δημοσ.

Σας ευχαριστω ολους παιδια! Θα ηθελα να ξερετε οτι δεν περιμενα καποια ετοιμη λυση οπως αναφερθηκε και πραγματικα δεν προσεξα οτι ελειπε το &.Σας ευχαριστω και παλι για τον χρονο σας ! :)

Δημοσ.

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

 

Θέλω να σταθώ λίγο στην σειρά #37

 

Ελέγχεις λοιπόν στην σειρά #24 αν η εισαγωγή βαθμολογίας από τον χ-οστό κριτή είναι εντός ορίων. 

if (vathmos<min) {
...
continue;
}
if (vathmos>max) {
..
continue;
}
 

Αν δεν είναι προχωράς στον επόμενο κριτή.

Αφού τελειώσεις με τους κριτές αφαιρείς από το σύνολο του βαθμού τα όρια (τον μέγιστο και τον ελάχιστο) τα οποία έχεις προσθέσει νωρίτερα;

Είναι λίγο άτοπο αυτό γιατί δεν ξέρεις ούτε πόσες φορές έχει εισαχθεί ο μέγιστος ή/και ο ελάχιστος σε κάθε κριτή ούτε ποιος από τους δυο (μέγιστος ή ελάχιστος) έχει εισαχθεί στο κάτω-κάτω.

 

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

Δηλαδή να κάνεις μια μικρή αξιολόγηση των δεδομένων που εισάγει ο χρήστης.

(Είναι μικρότερος του ελάχιστου? Εκτός ορίων, άρα δεν μου κάνει. άρα ας το ξανά εισάγει.

Είναι μεγαλύτερος του μέγιστου? Εκτός ορίων, άρα δεν μου κάνει. άρα ας το ξανά εισάγει.)

 

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

 

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

#include <stdio.h>

int main(void)	{

    int ipopsifios, kritis, max=100, min=1, epitixontes;
    float grade, orio, sum, m_v=0, pososto;
    char c1,c2;

    printf("Dwse orio epitropis:\n");
    scanf("%f",&orio);

    for (ipopsifios=1; ipopsifios<=3; ipopsifios++)	{
        sum=0;
        printf("Dwse arxika onomatos kai epithetou %dou ipopsifiou:\n",ipopsifios);
        fflush(stdin);
		scanf("%c%c",&c1,&c2);

        for (kritis=1; kritis<=2; kritis++)	{
			printf("Dwse vathmo %dou kriti:\n",kritis);
			scanf("%f",&grade);

	 	    while (grade < min || grade > max)	{
	 	    	printf("Edwses lathos vathmo %dou kriti. Prospathise ksana.\n",kritis);
           		scanf("%f",&grade);
			}

		sum += grade;
        }

        m_v = sum/2;

		if (m_v >= orio)	{
            epitixontes++;
        	printf("\n O %c.%c. epilextike me vathmo %.1f !\n", c1,c2,m_v);
        }

    }

	pososto = ((3-epitixontes)/3.)*100;
    printf("Ta atoma pou epilextikan itan %d.\n",epitixontes);
    printf("To pososto twn atomwn pou den epilextikan einai %.2f%%",pososto);

 return 0;
}
Το εσωτερικό loop που έτρεχε, το'κανε γιατί είχες το '\n' σε δυο scanf και το διάβαζε από τον buffer του πληκτρολογίου. Στα επόμενα μαθήματα πιστεύω θα καταλάβεις τι εννοώ.

 

Να σου πω κάνα δυο μικρά tips:

 

Το

x = x + y;
(στο παράδειγμά σου sunolo=sunolo+vathmos;)
 μπορείς για συντομία να το γράψεις:  

x+=y;
(στο παράδειγμά σου sunolo+=vathmos;)
Επίσης όταν αυξάνεις έναν μετρητή κατά 1, αντί να το γράψεις

i=i+1;
 όπως το γράφεις, να το γράψεις 

i++;
ή όπως ανέφερα παραπάνω:
i+=1;
(ακριβώς όπως και στο τελευταίο όρισμα της for δηλαδή).

 

Ελπίζω να σε βοήθησα έστω και λίγο.

Αν χρειαστείς κάποια περαιτέρω επεξήγηση, εδώ είμαστε!  :-D

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

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

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

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

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

Σύνδεση

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

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