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

Sorting ελληνικών strings σε C


Papajohn

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

Δημοσ.

Hello!

 

Σήμερα λοιπόν που λέτε έφτιαξα το πρώτο μου πρόγραμμα που κάνει κάτι χρησιμο για κάποιον και δεν είναι απλα μια άσκηση! Είμαι πολύ χαρούμενος! :) Είχα να πιάσω προγραμματισμό ένα χρόνο σχεδόν αλλα τα κατάφερα σχεδόν με την πρώτη! :grin:

 

Λοιπόν, έχω ένα txt αρχείο στο οποίο έχω αποθηκευμένα καμμια 200αριά strings διαφόρων μεγεθών. Χρειάζεται ο πατέρας μου να ταξινομήσει αλφαβητικά τα strings αυτά το οποία όμως είναι και ελληνικά και αγγλικα...

 

Το πρόγραμμα που έφιταξα είναι το εξής:

 

>
/*
 Author: Παπαγιάννης Ιωάννης
 Date: 31/07/05 11:50
 Description: Sorting strings που διαβάζονται ανά γραμμή απο αρχείο
*/

//Υλοποιώ τα strings ως λίστες χαρακτήρων. Αφού διαβάσω κάθε string το προσθέτω
//σε ένα binary search tree (γι' αυτό οι δείκτες left, right στο struct) το οποίο
//θα τυπώσω inorder πετυχαίνοντας την επιθμητή ταξινόμηση.

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

typedef struct tree_node
{
  int data;
  struct tree_node *left, *right, *next;
} tree;

typedef tree *tree_pointer;

void addlist (tree_pointer *list, int c)
{
  if ((*list)==NULL) 
  {
     (*list)=(tree *) malloc(sizeof(tree));
     (*list)->data=c;
     (*list)->next=NULL;
     (*list)->left=NULL;
     (*list)->right=NULL;
  }
  else addlist(&(*list)->next,c);
}

int sigrine_strings (tree_pointer p1, tree_pointer p2)
//Αν τα strings ταυτίζονται επιστρέφεται 1
{
  while ((p1->data==p2->data) && p1->data!='\n')
  {
     p1=p1->next;
     p2=p2->next;
  }
  if (p1->data=='\n') return 1;
  else if (p2->data=='\n') return 2;
  else if (p1->data<p2->data) return 1;
  else return 2;
}

void addbst(tree_pointer tp, tree_pointer *head)
{
  if ((*head)==NULL) *head=tp;        
  else if (sigrine_strings(tp,*head)==1) addbst(tp,&(*head)->left);
  else addbst(tp,&(*head)->right);
}

void print_bst(tree_pointer head, FILE *fp) //inorder εκτύπωση BST δίνει ταξινομημένο αποτέλεσμα
{
  tree_pointer temp=head;
  if (head->left!=NULL) print_bst(head->left,fp);
  do
  {
     fprintf(fp,"%c",temp->data);
     temp=temp->next;
  }
  while (temp->data!='\n');
  fprintf(fp,"\n\n");
  if (head->right!=NULL) print_bst(head->right,fp);
}

int main(int argc, char *argv[])
{
 FILE *fp;
 tree *list=NULL,*tree_top=NULL;
 int c,counter=0;
 
 fp=fopen("in.txt","r");
 printf("To arxeio anoikse pros anagnosi.\n");
 while ((c=fgetc(fp))!=EOF)
 {
    if (c=='\n')
    {
       counter++;
       addlist(&list, c); /*Προσθήκη τελικού newline*/
       addbst(list,&tree_top); /*Τέλος ενός string, προσθήκη στο BS Tree*/
       list=NULL;
       c=fgetc(fp); /*πάντα στα αρχείο έχω διπλά newlines*/
    }
    else
    {
       addlist(&list, c);
    }
 }
 fclose(fp);
 printf("To arxeio ekleise, h anagnosi teliose.\n");
 printf("Diavastikan sinolika %d strings.\n",counter);
 printf("---------------------\n");
 printf("Apothikefsi twn taxinomimenon strings se arxeio...\n");
 fp=fopen("out.txt","w");
 print_bst(tree_top,fp);
 fclose(fp);
 printf("Ta %d taxinomimena strings apothikefthikan sto arxeio out.txt.\n\n", counter);
 
 system("PAUSE");	
 return 0;
}

 

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

 

Ευχαριστω για την οποιαδήποτε βοήθεια!

Δημοσ.

Λοιπόν, μετα απο δοκιμές παρατηρώ την εξής περίεργη συμπεριφορα:

Όταν παιρνω την έξοδο στην οθόνη τότε τα ελληνικά εμφανίζονται κινέζικα, όταν πάλι παίρνω την έξοδο σε αρχείο τότε τα ελληνικά είναι οκ. Τι συμβαίνει; Γενικά πάντως οταν προσπαθω να έχω ελληνική εξοδο στην οθόνη (πχ printf("Γεια σου!"); τότε παίρνω κινέζικα, το fprintf(fp,"Γεια σου"); θα μου δώσει σωστα ελληνικά στο αρχείο. Τι συμβαίνει και δεν μπορώ να δω ελληνικά στην command line;

 

Note: Έχω WinXP SP2 και το compile το κάνω με το DevC++ που χρησιμοποιεί τον minigw.

Δημοσ.

Φίλε Papajohn το φαινόμενο των "κινέζικων" παρουσιάζεται διότι οι γραμματοσειρές του DOS έχουν διαφορετικό mapping απο αυτές των windows οπότε μάλλον δεν μπορείς να κάνεις τίποτα για αυτό... Δοκίμασε να δημιουργήσεις ένα αρχειο κειμένου με το notepad με Ελληνικούς χαρακτήρες και μετά άνοιξε το με το EDIT του DOS και θα δεις ότι θα τα βγάζει πάλι "κινεζικα"... Μετά κανε το αντίθετο δηλ. ένα αρχειο απο το EDIT με Ελληνικους χαρακτήρες να το ανοίξεις με το notepad. Θα δείς ότι πάλι παρουσιάζεται το ίδιο πρόβλημα. Άρα δεν φταίει το πρόγραμμα σου...

Δημοσ.

OK παίδες, ευχαριστω για τις διευκρινίσεις. Κάτι ακόμα όμως.

Εξακολουθώ να μη καταλαβαίνω γιατι το πρόγραμμα μου ...λειτουργεί με ελληνικά!

Διαβάζοντας χαρακτήρες με την getchar ουσιαστικά δεν παίρνω ένα ένα byte απο το αρχείο; Πως γίνεται σε αυτο το ένα byte να περιεχονται οι ελληνικοι χαρακτήρες; 1 byte=8 bits=2^8=256 συνδυασμοί του ASCII (ο ASCII 128 χαρακτήρες δεν έχει όμως; Χάνω κάτι;;) στους οποίους δεν υπάρχουν τα ελληνικα... Η μήπως η getchar δεν διαβάζει ενα-ενα byte βασιζόμενη στον ASCII αλλα κατάλληλο αριθμό απο bytes (πχ 2) ωστε με κάποιο character set του οποίου εγω αγνοώ την ύπαρξη να συμπεριλαμβάνονται τα ελληνικα;

Δημοσ.

Επειδη ειχα το ιδιο προβλημα ,συμπεριφφερεται κανονικα γιατι δεν χρησιμοποιει απλα το ascii γιατι εχει 7 bit και παει χαμενο 1 bit .Οταν διαβαζεις ενα χαρακτηρα τον ανα γνωριζει στις θεσεις πανω απο 128 μεχρι 256.

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

Δημοσ.
papajohn για unicode και χαρακτηρες στην C ψαξε λιγο για τον τυπο wchar μηπως και βοηθηθεις.

 

Τύπος wchar;! Δεν το λέει ο Kernighan αυτο! :smile:

Τεσπα, θα το googlάρω! Ευχαριστω!

Δημοσ.
OK παίδες' date=' ευχαριστω για τις διευκρινίσεις. Κάτι ακόμα όμως.

Εξακολουθώ να μη καταλαβαίνω γιατι το πρόγραμμα μου ...λειτουργεί με ελληνικά!

Διαβάζοντας χαρακτήρες με την getchar ουσιαστικά δεν παίρνω ένα ένα byte απο το αρχείο; Πως γίνεται σε αυτο το ένα byte να περιεχονται οι ελληνικοι χαρακτήρες; 1 byte=8 bits=2^8=256 συνδυασμοί του ASCII (ο ASCII 128 χαρακτήρες δεν έχει όμως; Χάνω κάτι;;) στους οποίους δεν υπάρχουν τα ελληνικα... Η μήπως η getchar δεν διαβάζει ενα-ενα byte βασιζόμενη στον ASCII αλλα κατάλληλο αριθμό απο bytes (πχ 2) ωστε με κάποιο character set του οποίου εγω αγνοώ την ύπαρξη να συμπεριλαμβάνονται τα ελληνικα;[/quote']

 

Το πρότυπο ASCII χωρίζεται σε δυο μεγάλες κατηγορίες, το «Regular ASCII» το οποίο χρησιμοποιεί 7-bit κωδικοποίηση και έχει εύρος 127 (μετρώντας από το μηδέν) χαρακτήρων (τιμές) και το «Extended ASCII» το οποίο χρησιμοποιεί 8-bit κωδικοποίηση με εύρος 255 (μετρώντας από το μηδέν) χαρακτήρες (τιμές).

Το πρώτο ASCII περιέχει ολόκληρο το Λατινικό αλφάβητο μαζί με αρκετούς χαρακτήρες στίξης, κώδικες τηλετύπου (πχ. nul, soh, stx κτλ.) και όλους τους βασικούς αραβικούς αριθμούς ενώ το δεύτερο (το οποίο προστέθηκε αργότερα) περιλαμβάνει το Ελληνικό αλφάβητο (ή άλλες γλώσσες, εξαρτάται από το customization του συστήματος) μαζί με χαρακτήρες σχεδίασης και ορισμένα μαθηματικά σύμβολα.

Δημοσ.

Βαριέμαι να διαβάσω όλο το topic, απαντάω μόνο στο κομμάτι για τα ελληνικά:

Σε XP, βάζεις σαν πρώτη εντολή του προγράμματος την

system("chcp 1253");

και πλέον το πρόγραμμα διαβάζει και γράφει κανονικά ελληνικά, όπως αυτά του Notepad (κωδικοσελίδα 1253 ή αλλιώς 928 ).

 

Αν πάλι θες να διαβάζεις και να γράφεις ελληνικά σαν αυτά του DOS των 98/Me (δηλαδή κωδικοσελίδα 737) πρέπει να χρησιμοποιείς έναν editor που να υποστηρίζει 737 encoding, όπως είναι το visual studio και διάφοροι άλλοι. Σε αυτήν την περίπτωση δεν χρειάζεται η system("chcp 737"), παίζει κατευθείαν.

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

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

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