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

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

Δημοσ.

...

Σκέτο cast σε unsigned δεν αρκεί γιατί θέλεις σύγκριση χωρίς διάκριση κεφαλαιών-πεζών. Ο πίνακας δεν κάνει treat τιμές σαν -128, -127, κτλ αλλά μπαίνει για αυτό που είπε ο DirectX. Για κάποιο λόγο δεν ήθελαν να τρέξουν tolower και χρησιμοποιούν τον πίνακα. Αν δεις πχ τις θέσεις 65 και 97 έχουν και οι δύο τιμή \141 δηλαδή 97 που είναι το μικρό a και πάει λέγοντας. Έτσι συγκρίνοντας ένα A με ένα a θα βρεθούν ίσα.

Ναι, είναι αυτονόητο πως θέλει και tolower/toupper μαζί με το unsigned cast. Γιατί είχαν πίνακα δεν μπρούσα να καταλάβω. Επίσης, με αυτόν τον πίνακα κάνουν rule-out τα codepages που στηρίζονται σε Extended ASCII (8-μπιτ) ή είναι η ιδέα μου; :lol:

 

Σχετικο άσχετο, έπαιζα πριν λίγο με αυτόν τον κώδικα σε Widnows XP με 3 διαφορετικούς compilers:

char *s_tolower( char *s )
{
	register char *ret = NULL;

	/* sanity checks */
	if ( !s ) {
		return NULL;
	}
	if ( !*s ) {
		return s;
	}

	for ( ret=s; (*s=(char)tolower((int)*s)); s++ )
		/* void */;

	return ret;
}
...
int main(void )
{
	char *cp = NULL, s[] = "ΑΒΓΔ";
	const char *syslocale = setlocale(LC_ALL, NULL);

	puts( syslocale ? syslocale : "<NULL>" );
	puts( s );
	cp = s_tolower(s);
	printf( "%s\n", cp ? cp : "<NULL>" );
...
}

Αποτελέσματα

// lcc-win32
C
ΑΒΓΔ
αΒγΔ
Press any key to continue . . .

// mingw32
C
ΑΒΓΔ
ΑΒΓΔ
Press any key to continue . . .

// Pelles C
C
ΑΒΓΔ

Press any key to continue . . .

Τρια πουλάκια κάθονταν :P

 

EDIT:

 

Για την αφαίρεση δεικτών, εφόσον το γράφει το πρότυπο, είναι όντως undefined ;)

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

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

Δημοσ.

Σχετικο άσχετο, έπαιζα πριν λίγο με αυτόν τον κώδικα σε Widnows XP με 3 διαφορετικούς compilers:

char *s_tolower( char *s )
{
	register char *ret = NULL;

	/* sanity checks */
	if ( !s ) {
		return NULL;
	}
	if ( !*s ) {
		return s;
	}

	for ( ret=s; (*s=(char)tolower((int)*s)); s++ )
		/* void */;

	return ret;
}
...
int main(void )
{
	char *cp = NULL, s[] = "ΑΒΓΔ";
	const char *syslocale = setlocale(LC_ALL, NULL);

	puts( syslocale ? syslocale : "<NULL>" );
	puts( s );
	cp = s_tolower(s);
	printf( "%s\n", cp ? cp : "<NULL>" );
...
}

Αποτελέσματα

// lcc-win32
C
ΑΒΓΔ
αΒγΔ
Press any key to continue . . .

// mingw32
C
ΑΒΓΔ
ΑΒΓΔ
Press any key to continue . . .

// Pelles C
C
ΑΒΓΔ

Press any key to continue . . .

Τρια πουλάκια κάθονταν :P

 

 

Το "ΑΒΓΔ" είναι ISO8859-7 ? Αν είναι UTF-8 τότε η συμπεριφορά του mingw είναι σωστή να μην το πειράζει γιατί η tolower δουλεύει με unsigned char οπότε μπορεί να δει μόνο τα επιμέρους bytes κάθε "χαρακτήρα". Αν είναι ISO τότε δοκίμασε να το τρέξεις αλλάζοντας πρώτα το setlocale(LC_ALL, NULL) σε setlocale(LC_ALL, "").

Δημοσ.

Το "ΑΒΓΔ" είναι ISO8859-7 ? Αν είναι UTF-8 τότε η συμπεριφορά του mingw είναι σωστή να μην το πειράζει γιατί η tolower δουλεύει με unsigned char οπότε μπορεί να δει μόνο τα επιμέρους bytes κάθε "χαρακτήρα". Αν είναι ISO τότε δοκίμασε να το τρέξεις αλλάζοντας πρώτα το setlocale(LC_ALL, NULL) σε setlocale(LC_ALL, "").

 

Είναι ANSI 1253 (πιο γνωστό ως cp1253 στον κόσμο του Unix/Linux). Γνωρίζω πως χρησιμοποιείται η setlocale() (δες π.χ. τα Notes στην τεκμηρίωση της s_CompareToIgnoreCase(), απλώς ήθελα να τονίσω το γενικότερο πρόβλημα που υπάρχει με τον κάθε compiler να κάνει λίγο πολύ ότι του καπνίσει.

 

Ακόμα και περνώντας το locale ως "" δεν λύνεται το πρόβλημα, διότι το "" διαβάζει μια σειρά από environment variables, οι τιμές των οποίων είναι compiler-dependent.

 

Κρατώντας ίδια την κωδικοποίηση του παραπάνω κώδικα, κι αλλάζοντας μονάχα σε "" το 2ο όρισμα της setlocale() τα Αγγλικά XP SP3 με σεταρισμένα τα regional settings σε Ελληνικά δίνουν τα παρακάτω αποτελέσματα...

// mingw32

Greek_Greece.1253
ΑΒΓΔ
αβγδ
Press any key to continue . . .

// lcc-win32
Greek_Greece.1253
ΑΒΓΔ
ΑΒΓΔ
Press any key to continue . . .

// pelles c
GR
ΑΒΓΔ

Press any key to continue . . .

Παρατήρησε πως mingw και lcc-win32 "διαβάζουν" ως current locale το "Greek_Greece.1253" ενώ η pelles-c το "GR". Παρατήρησε επίσης πως μόνο ο mingw δείχνει να λειτουργεί as expected, ενώ π.χ. ο lcc-win32 κάνει σωστά τη μετατροπή σε "C" locale ενώ δεν θα έπρεπε (δες το προηγούμενο post) ενώ με "Greek_Greece.1253" τα παίζει (μάλλον αναγνωρίζει διαφορετικό σετ τιμών για τα locales, αλλά ακόμα κι έτσι να είναι, γιατί δεν αναγνωρίζει τη "δικιά" του τιμή για τα Ελληνικά μέσω του "" της setloclae()). Η δε pelles-c δεν δουλεύει σωστά ούτε με "C" ούτε με "GR".

 

Βασικά πρέπει να ψάξει κανείς τα manuals των compilers για τυχόν ειδικά options σχετικά με την αποθηκευμένη κωδικοποίηση των source files, κάτι που δεν το έκανα (βαριέμαι, το χω κάνει μόνο για mingw και pelles-c), αλλά η ουσία είναι η ασυμβατότητα μεταξύ των compilers, ακόμα και για το "C" locale που υποτίθεται πως είναι portable.

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

Σε C++ Builder το s[] επιστρέφεται ως έχει καθώς σύμφωνα με την τεκμηρίωση του εργαλείου, η tolower τροποποιεί μόνο τους χαρακτήρες του λατινικού αλφάβητου (A-Z) ενώ αγνοεί όλους τους υπόλοιπους.

 

Η setlocale σε "Greek" λειτουργεί μεν (γυρίζοντας σε Greek με CodePage όποιο έχεις ορίσει εσύ στα Options του Project σου..) αλλά δεν τροποποιεί την συμπεριφορά της tolower προς το επιθυμητό.

 

--EDIT:

Τελικά η tolower εφαρμόζει το "Greek" setlocale επιτυχώς (παρόλα όσα λέει η τεκμηρίωση..) σαν ορισθεί στα Options του Project ως "Execution Character Set" το 1253 οπότε το ΑΒΓΔ γίνεται πράγματι "αβγδ" :-)

 

 

..Ψάχνοντας στα source που παρέχει ο μεταφραστής, η υλοποίηση της tolower χρησιμοποιεί το *isupper για να δει αν πρόκειται για κεφαλαίο χαρακτήρα, αν ναι τότε τον περνά στην συνάρτηση _ltolower η οποία όταν το ενεργό LOCALE δεν είναι NULL περνά τον χαρακτήρα στην Windows API συνάρτηση LCMapString η οποία αναλαμβάνει την τελική μετατροπή με βάση το ενεργό CodePage του προγράμματος.

 

*Πάω στοίχημα ότι και αυτή με βάση το LOCALE καταλήγει σε ανάλογη WinAPI συνάρτηση

 

* Βέβαια όταν προγραμματίζεις σε C++ Builder λίγη σημασία έχει καθώς το βασικό framework του εργαλείου (η VCL) υποστηρίζει Unicode οπότε ουδέν πρόβλημα.

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

...

--EDIT:

Τελικά η tolower εφαρμόζει το "Greek" setlocale επιτυχώς (παρόλα όσα λέει η τεκμηρίωση..) σαν ορισθεί στα Options του Project ως "Execution Character Set" το 1253 οπότε το ΑΒΓΔ γίνεται πράγματι "αβγδ" :-)

 

 

..Ψάχνοντας στα source που παρέχει ο μεταφραστής, η υλοποίηση της tolower χρησιμοποιεί το *isupper για να δει αν πρόκειται για κεφαλαίο χαρακτήρα, αν ναι τότε τον περνά στην συνάρτηση _ltolower η οποία όταν το ενεργό LOCALE δεν είναι NULL περνά τον χαρακτήρα στην Windows API συνάρτηση LCMapString η οποία αναλαμβάνει την τελική μετατροπή με βάση το ενεργό CodePage του προγράμματος.

 

*Πάω στοίχημα ότι και αυτή με βάση το LOCALE καταλήγει σε ανάλογη WinAPI συνάρτηση

 

* Βέβαια όταν προγραμματίζεις σε C++ Builder λίγη σημασία έχει καθώς το βασικό framework του εργαλείου (η VCL) υποστηρίζει Unicode οπότε ουδέν πρόβλημα.

Ναι, βασικά ξέχασα να αναφέρω πως εγω έχω αλλάξει την OEMCP (και την ACP) ρύθμιση στο registry από 737 ή 437 που είναι η default στα ελληνικά Windows σε 1253.

 

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage\OEMCP (στο spoiler)...

 

 

 

post-38307-0-21749200-1357133002_thumb.jpg

 

 

 

ΠΡΟΣΟΧΗ:

 

Έχω δοκιμάσει να την αλλάξω και σε 65001 (το αναπηρικό UTF-8 της κονσόλας των Windows) με καταστροφικά αποτελέσματα. Το PC δεν ξαναμπούταρε ποτέ, παρά μόνο μετά από δημιουργία BartPE boot cd στο laptop για να μπορέσω να μπουτάρω το PC και να ξαναλλάξω τη ρύθμιση στο registry.

Δημοσ.

Καλή χρονιά σε όλους! Κάτι λίγο άσχετο με τα προηγούμενα...

 

Δεν ξέρω αν έχει αναφερθεί ξανά εδώ μέσα (όσο έψαξα λίγο δεν το βρήκα) σχετικά με την printf και τους long double σε mingw.

Χρησιμοποιώ Orwell Dev-C++ (se windows 7 64bit) και προσπαθώντας να τρέξω το παρακάτω πρόγραμμα:

#include <stdio.h>

main()
{
	long double k = 1;
	
	printf("%llf, %Lf, %Lg, %Le",k,k,k,k);
	
	return 0;
}

έπαιρνα σαν αποτέλεσμα

0.000000, 0.000000, 1.13302e-317, 1.133015e-317

Process exited normally.
Press any key to continue . . .

Τελικά μετά από λίγο ψάξιμο βρήκα ότι για να δουλέυει σωστά η printf με τους long double πρέπει να προστεθεί στα option του compiler το

-D__USE_MINGW_ANSI_STDIO

Το αναφέρω μήπως προκύψει και σε κάποιον άλλον παρόμοιο πρόβλημα...

Δημοσ.

 

Είναι ANSI 1253 (πιο γνωστό ως cp1253 στον κόσμο του Unix/Linux). Γνωρίζω πως χρησιμοποιείται η setlocale() (δες π.χ. τα Notes στην τεκμηρίωση της s_CompareToIgnoreCase(), απλώς ήθελα να τονίσω το γενικότερο πρόβλημα που υπάρχει με τον κάθε compiler να κάνει λίγο πολύ ότι του καπνίσει.

 

Ακόμα και περνώντας το locale ως "" δεν λύνεται το πρόβλημα, διότι το "" διαβάζει μια σειρά από environment variables, οι τιμές των οποίων είναι compiler-dependent.

 

Κρατώντας ίδια την κωδικοποίηση του παραπάνω κώδικα, κι αλλάζοντας μονάχα σε "" το 2ο όρισμα της setlocale() τα Αγγλικά XP SP3 με σεταρισμένα τα regional settings σε Ελληνικά δίνουν τα παρακάτω αποτελέσματα...

// mingw32

Greek_Greece.1253
ΑΒΓΔ
αβγδ
Press any key to continue . . .

// lcc-win32
Greek_Greece.1253
ΑΒΓΔ
ΑΒΓΔ
Press any key to continue . . .

// pelles c
GR
ΑΒΓΔ

Press any key to continue . . .

Παρατήρησε πως mingw και lcc-win32 "διαβάζουν" ως current locale το "Greek_Greece.1253" ενώ η pelles-c το "GR". Παρατήρησε επίσης πως μόνο ο mingw δείχνει να λειτουργεί as expected, ενώ π.χ. ο lcc-win32 κάνει σωστά τη μετατροπή σε "C" locale ενώ δεν θα έπρεπε (δες το προηγούμενο post) ενώ με "Greek_Greece.1253" τα παίζει (μάλλον αναγνωρίζει διαφορετικό σετ τιμών για τα locales, αλλά ακόμα κι έτσι να είναι, γιατί δεν αναγνωρίζει τη "δικιά" του τιμή για τα Ελληνικά μέσω του "" της setloclae()). Η δε pelles-c δεν δουλεύει σωστά ούτε με "C" ούτε με "GR".

 

Βασικά πρέπει να ψάξει κανείς τα manuals των compilers για τυχόν ειδικά options σχετικά με την αποθηκευμένη κωδικοποίηση των source files, κάτι που δεν το έκανα (βαριέμαι, το χω κάνει μόνο για mingw και pelles-c), αλλά η ουσία είναι η ασυμβατότητα μεταξύ των compilers, ακόμα και για το "C" locale που υποτίθεται πως είναι portable.

 

 

 

 

Την αλλαγή σε "" την επισήμανα ώστε να χρησιμοποιηθεί το Ελληνικό locale και να μην έχεις C όπως είχες στον αρχικό κώδικα. Όπως το βλέπω εγώ, το πρόβλημα είναι στους compilers lcc και pelles. Ο mingw συμπεριφέρθηκε λογικά και στις δύο περιπτώσεις.
Δημοσ.

Καλή χρονιά σε όλους! Κάτι λίγο άσχετο με τα προηγούμενα...

...

Τελικά μετά από λίγο ψάξιμο βρήκα ότι για να δουλέυει σωστά η printf με τους long double πρέπει να προστεθεί στα option του compiler το

-D__USE_MINGW_ANSI_STDIO
Το αναφέρω μήπως προκύψει και σε κάποιον άλλον παρόμοιο πρόβλημα...

 

 

 

Καλή χρονιά!

 

Έχω φάει κι εγώ φρίκη με το συγκεκριμένο στον mingw, και συγκεκριμένα όταν έφτιαχα τον CC HexView (δες την τελευταία παράγραφο στο spoiler των Features) και μάλιστα δεν είχα βρει κιόλας άκρη (μάλλον από το πολύ πήξιμο δεν γκουγλάριζα με καθαρό μυαλό)!

 

Τhanks για την λύση!

 

Την αλλαγή σε "" την επισήμανα ώστε να χρησιμοποιηθεί το Ελληνικό locale και να μην έχεις C όπως είχες στον αρχικό κώδικα. Όπως το βλέπω εγώ, το πρόβλημα είναι στους compilers lcc και pelles. Ο mingw συμπεριφέρθηκε λογικά και στις δύο περιπτώσεις.

Επίτηδες είχα βάλει "C" (NULL) επειδή υποτίθεται πως είναι portable. Και για μένα ο mingw είναι ο μόνος που συμπεριφέρθηκε σωστά, αν και δεν ξέρω αν συμπεριφερθούν σωστά και οι άλλοι δυο με ειδικά encoding flags στον cc driver τους (προς το παρόν βαριέμαι οικτρά να το ψάξω, αν και νομίζω πως η pelles-c δεν παρέχει σχετικό command-line option, παρά μόνο μέσα από το IDE της).

Δημοσ.

[..]Έχω δοκιμάσει να την αλλάξω και σε 65001 (το αναπηρικό UTF-8 της κονσόλας των Windows) με καταστροφικά αποτελέσματα. Το PC δεν ξαναμπούταρε ποτέ, παρά μόνο μετά από δημιουργία BartPE boot cd στο laptop για να μπορέσω να μπουτάρω το PC και να ξαναλλάξω τη ρύθμιση στο registry.

Δυστυχώς σε CHCP 65001 η κονσόλα χάνει την μπάλα σε κρίσιμες υπηρεσίες της, για παράδειγμα με ενεργό το CodePage 65001 τα αρχεία BAT απλά δεν εκτελούνται (ούτε μήνυμα λάθους δεν εμφανίζεται!)
Δημοσ.

 

Ίσως δεν το κατάλαβα καλά αλλά έτσι που το έχεις, whatever δεν είναι ο τύπος του δείκτη ? Το αντικείμενο είναι αυτό στο οποίο ανήκει η διεύθυνση "γάμος του καραγκιόζη".

 

whatever a[30];
whatever b[12];
whatever *p = a[16];
whatever *q = b[7];

Εδώ οι p και q δείχνουν σε διαφορετικά αντικείμενα (α και β) οπότε δεν μπορούν να αφαιρεθούν. Αν εννοούσες κάτι άλλο πάω πάσο.

 

 

Τα a[16] , a[7] ειναι στοιχεια και οχι διευθύνσεις. :P

Δημοσ.

Καλή χρονιά και χρόνια πολλά σε όλους!!!

 

Έχω την εξής απορία στο θέμα της επαναλαμβανόμενης κλήσης συναρτήσεων απο τον εαυτό τους.Στον παρακάτω κώδικα

 

void f(void)
{
     int i;
   
     printf("in f() \n");

     for(i=0;i<10;i++) f();
}

μου λέει ότι δεν υπάρχει εντολή που να ελέγχει το αν θα πρέπει να ξανακληθεί ή να τερματίσει.Κι εγώ ρωτάω:το for δεν μου λέει ότι αν i=10 σταμάτα;

Δημοσ.

Κάθε i σε κάθε f είναι διαφορετικό. Οπότε, ποτέ δεν θα πάει το i στο 10. 

 

Εάν είχες κάτι σαν:

 

>void f(int i){  printf("in f() \n");  for( ; i < 10; ++i) f(i);  printf("Exited from f() \n");}

 

Θα μπορούσε να τερματίσει κάπου. 

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

@capoelo

 

Ξεκινά η συνάρτηση η οποια έχει μέσα ενα for-loop το i αρχικοποιείται κάπου ή ξεκινα με την τιμή στην οποια ηδη εχει αρχικοποιηθεί (αν για παραδειγμα η πρωτη εκφραση στην for ειναι το ερωτηματικο) . Το σώμα του loop ομως έχει την κλήση της f . Οποτε καλειται η f το i ξεκινά με την τιμή στην οποια εχει ηδη αρχικοποιηθει μεσα στην συναρτηση σαν τοπικη μεταβλητη , καλειται ξανα η συνάρτηση (δεν προλαβαινει καν να εκτιμηθει η έκφραση αυξησης της for) κ.ο.κ και τελικα έχεις έναν βροχο που δεν τερματιζει ποτε.

 

Ουτε με αυτο που σου έδωσε ο Timon τερματίζει ακριβως επειδη δεν προλαβαινει να εκτιμηθεί η έκφραση αυξησης......

 

Αν θες να τερματισει θα πρέπει να παιξεις με κάτι σαν και αυτο

 

 

 
#include <stdio.h>
void f(int i)
{
 
  for( ; i++ < 10;)
  {
      printf("%d" , i);
      f(i);
  }
}
int main(void)
{
  int x=0;
 
  f(x);
 
    return 0;
}
 

 

 

Διοτι εδω η εκτιμηση της αυξησης γινεται πριν μπεις στο σωμα του βροχου και μετα τον έλεγχο ... ή ++i < 10 αν θες αυξηση πριν τον ελεγχο.

 

Αν και κώδικες οπως ο :

 

 

 
#include <stdio.h>
void f(int i)
{
 
  //printf("%d" , i);
 
  for(; i++ <2;)
  {
      printf("\n%d" , i);
      f(i);
      printf("Here");
  }
}
 

 

 

Νομιζω προκαλουν UB. Οποτε δεν θα μαθεις και τιποτα αν απαντησεις σε αυτο το ερωτημα απλα κρατησε οτι γενικα η f(i) δεν επιστρεφει και ποτε.... πεφτει σε ατερμονα βροχο.

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

μπορει καποιος να με βοηθισει γιατι κολησα?

 

εχω αυτο:

 

printf ("%d%13d", element, value);

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

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

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