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

Πρόβλημα με ατέρμονη getchar() σε C...


Lomar

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

Δημοσ.

χαίρεται.

 

έχω τον παρακάτω κώδικα:

 

>
#include <stdio.h>

int main(){
      char leksi[0][8];
      char code[8]="eksodos1";
      int elegxos=0;
      int i=0, y=0;
      
      strcpy(leksi[0],"akuro67");        
      while (elegxos=strcmp(leksi[0],code))
            for(i=0;i<8;i++)
                             leksi[0][i]=getchar();

      
return 0;
}

Δημοσ.

και το πρόβλημά μου είναι πως όταν ζητήται η εισαγωγή των χαρακτήρων του προς εξέταση απο την while αλφαριθμητικού (leksi[0]), το πρόγραμμα δεν σταματάει να ζητάει χαρακτήρες. thnks in adnvc, sorry αλλά το τεράστιο ping της Forthnet δεν μου επιτρέπει να ποστάρω πολλά κάθε φορά.

Δημοσ.
και το πρόβλημά μου είναι πως όταν ζητήται η εισαγωγή των χαρακτήρων του προς εξέταση απο την while αλφαριθμητικού (leksi[0]), το πρόγραμμα δεν σταματάει να ζητάει χαρακτήρες. thnks in adnvc, sorry αλλά το τεράστιο ping της Forthnet δεν μου επιτρέπει να ποστάρω πολλά κάθε φορά.

 

Αρχικά το πρόγραμμα που πόσταρες στον δικό μου compiler δεν δουλεύει και αυτό για πολλούς λόγους, αρχικά δεν μπορείς να ορίσεις μηδέν string κατά την δήλωση τους, δηλώνεις 1 ως minimum και το διαχειρίζεσαι μετά σαν string[0][N] για να κάνεις ότι θέλεις. Θα καταλάβεις και από την διόρθωση μου. Επίσης όταν δηλώνεις ένα string και θέλεις καθαρά Ν χαρακτήρες να έχει το string σου αυτό τότε πάντα να το δηλώνεις ως N+1 γιατί υπάρχει και το '\0' που είναι ο χαρακτήρας τερματισμού στα C strings και πρέπει να μπει. Οπότε εσύ δήλωνες 8 χαρακτήρες αλλά διαβάζονταν 7 γιατί ο 8ος υποχρεωτικά από τον compiler θα είναι το '\0' για να τερματιστεί το string. Έτσι το eksodos1 που ήθελες δεν είναι αυτό που έγραφες αλλά η λέξη eksodos γιατί το 1 το έφαγε το υποχρεωτικό '\0'. Επίσης να δηλώσεις και την βιβλιοθήκη string.h γιατί οι συναρτήσεις που χρησιμοποιείς δεν υπάρχουν στο stdio.h. Τέλος να μην ξεχνάς να τερματίζεις κάθε string με το '\0' γιατί αλλιώς θα έχεις μεγάλα προβλήματα. Εγώ το διόρθωσα μετά από ολα αυτά ως εξής: Τώρα εσύ ξέρεις.

 

Corrected

 

>
//---------------------------------------------------------------------------

#include <stdio.h>
#include <string.h>
#pragma hdrstop

//---------------------------------------------------------------------------

#pragma argsused
int main(int argc, char* argv[])
{
	char leksi[1][9] = "";
   char code[9]="eksodos1";
   int elegxos = 0;
   int i=0;
   /* No need to do that but i dont know why. */
   strcpy(leksi[0],"akuro67");
   while ((elegxos = strcmp(leksi[0],code)) != 0)
   {
		/* Loop every time and get a string from user. */
		for(i = 0; i < 9 && ((leksi[0][i] = getchar()) != '\n'); i++);
		/* Terminate the string. */
		leksi[0][i] = '\0';
   }
   if(!elegxos)
	printf("You typed \"eksodos1\" and we were out of the loop.\n");

printf("Hit enter to continue....");
getchar();

return 0;
}
//---------------------------------------------------------------------------

Δημοσ.

καταρχάς σε ευχαριστώ πολύ για τη βοήθεια, αλλά ο compiler μου εμφανίζει το λάθος: "invalid initializer", στη δήλωση char leksi[1][9] = ""; Επίσης με το leksi[0][N], νόμιζα πως το 0 συμβόλιζε την πρώτη συμβολοσειρά, ενώ αν ήταν 1 θα συμβόλιζε 2 συμβολοσειρες...

Δημοσ.

Πρόβλημα με ping ==> πολλά σύντομα ποστ, συγνώμη στους mods. Βασικά δεν ήθελα να καταγράφεται μονομιάς η συμβολοσειρά απο την getchar(), αλλά γράμμα γράμμα, έτσι ώστε να μην φαίνετε ολόκληρο το αλφαριθμητικό που πληκτρολογήθηκε στην οθόνη. Κάτι σαν τα αστεράκια όταν γράφουμε ένα password.

Δημοσ.

Αυτό που ζητάς δεν είναι εύκολο με τις standard βιβλιοθήκες της ANSI-C καθώς θα πρέπει να διαβάζεις συνεχώς (polling) την κατάσταση όχι απλά του stdin buffer αλλά των ίδιων των πλήκτρων του πληκτρολόγιου σου.

 

Την εποχή του DOS (αλλά και των Windows) αυτό μπορούσε να επιτευχθεί στους C compilers (πέραν της χρήσης Assembly σε DOS ή Window API σήμερα) με την χρήση των ρουτινών της βιβλιοθήκης “CONIO” (#include <conio.h>) οι οποίες προσφέρανε διάφορες functions που εξυπηρετούσαν την διεπαφή των C προγραμμάτων κονσόλας με το Λ.Σ.

 

Η CONIO υπήρχε και εξακολουθεί να υπάρχει στους Compilers της Borland/Code Gear και, από όσο γνωρίζω σε αρκετούς παρόμοιους compilers της Microsoft. Στο Unix/Linux η CONIO δεν υπάρχει (αν και θυμάμαι σε παλαιότερο post μου, πως είχα εγώ ή κάποιος άλλος υποδείξει ένα port της CONIO στο Linux) αλλά μπορείς να βασιστείς σε κάποιες άλλες ρουτίνες διαχείρισης συστήματος που προσφέρουν φυσικά αυτά τα Λ.Σ.

 

Τώρα το παρακάτω παράδειγμα, βασίζεται στην ρουτίνα getch() της CONIO η οποία επιστρέφει το πλήκτρο που έχει πατήσει ο χρήστης:

 

>
/*-DIRECTX PASSWORD INPUT LIKE EXAMPLE WITH THE USE OF CONIO-----------------*/

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

/*---------------------------------------------------------------------------*/

#pragma argsused
int main(int argc, char* argv[])
{
char szPassword[12];
int	 nPasswordIdx = 0,
	 nChar;

/*
 * Poll keyboard interrupt (not just stdin) with getch() function.
 *
 * This function does not exists in ANSI-C specification, but it's
 * "standard" in many DOS/Windows era compilers.
 */
while((nChar=getch())!='\r') /* Read keyboard until \r (in getch==Enter=> \r) */
 {
	if(nPasswordIdx<sizeof(szPassword)-1 || nChar=='\b')
	 {			
		if(nChar!='\b')		/* Does the User want's to 'Backspace' ? */
		 {
			szPassword[nPasswordIdx++]=nChar;								
			szPassword[nPasswordIdx]='\0';
			putchar('*');		
		 }
		else				/* Yes, remove char and Backspace -1 char */
		 {
			if(!nPasswordIdx)				 
				putchar('\a');
			else
			 {
				szPassword[--nPasswordIdx]='\0';
				printf("%c%c%c",'\b',' ','\b');
			 }
		 }
	 }
	else
		putchar('\a');		/* szPassword limit! */
 }	 

printf("\nszPassword=\"%s\"\n",szPassword);

printf("Press Enter to resume..");
   getchar();
return 0;
}
/*---------------------------------------------------------------------------*/

 

Το πρόγραμμα αυτό γίνεται compile μόνο αν ο compiler σου διαθέτει την CONIO και φυσικά η getch() της λειτουργεί με τον ίδιο τρόπο που δουλεύει η αντίστοιχη έκδοση που περιλαμβάνει ο compiler μου (CodeGear Turbo C++ 2006) –μάλιστα ο Borland/CodeGear compiler περιλαμβάνει και ρουτίνα έτοιμη που κάνει αυτή την δουλεία (ονομάζεται getpass / CONIO.H) :P..

 

Καλή συνέχεια!

Δημοσ.

Ναι έχεις δίκιο, διόρθωσα το λάθος ορίστε ο κώδικας αν και τώρα που καταλάβαμε τι ζητάς ο DirectX σου έδωσε ένα πολύ ωραίο στρωτό κώδικα για να καλύψει αυτό που θες.

 

Ορίστε:

 

>
//---------------------------------------------------------------------------

#include <stdio.h>
#include <string.h>
#pragma hdrstop

//---------------------------------------------------------------------------

#pragma argsused
int main(int argc, char* argv[])
{
	char leksi[1][9] = {""};
   char code[9]="eksodos1";
   int elegxos = 0;
   int i=0;
   /* No need to do that but i dont know why. */
   strcpy(leksi[0],"akuro67");
   while ((elegxos = strcmp(leksi[0],code)) != 0)
   {
		/* Loop every time and get a string from user. */
		for(i = 0; i < 9 && ((leksi[0][i] = getchar()) != '\n'); i++);
		/* Terminate the string. */
		leksi[0][i] = '\0';
   }
   if(!elegxos)
	printf("You typed \"eksodos1\" and we were out of the loop.\n");

printf("Hit enter to continue....");
getchar();

return 0;
}
//---------------------------------------------------------------------------

Δημοσ.

Σας ευχαριστώ και τους δύο για τη βοήθεια, ειδικά εσύ DIrectX με έχεις βοηθήσει πολλές φορές και δε ξέρω πως να το ανταποδώσω!

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

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

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