migf1 Δημοσ. 11 Μαρτίου 2012 Δημοσ. 11 Μαρτίου 2012 Ενδεχομένως να είναι απλό, αλλά έχω φάει 1 ολόκληρη ημέρα χωρία επιτυχία. Βασικά θέλω να υλοποιήσω χειροκίνητα σε C παραπλήσια λειτουργικότητα με το regex... > [^string] Έστω το κείμενο... > Hello, this is a test Έστω οι εντολές... > /this /* αναζήτηση της επόμενης εμφάνισης του string "this" */ /!this /* αναζήτηση του 1ου χαρακτήρα που ΔΕΝ αρχίζει με το string "this" */ Έστω, τέλος, πως ο δρομέας βρίσκεται στο κενό διάστημα μετά το κόμα του "Hello" Η 1η εντολή είναι trivial, κανένα πρόβλημα εκεί. Η 2η όμως εντολή πού πρέπει να μεταφέρει τον δρομέα; Στον χαρακτήρα 'h' ή στο κενό διάστημα μεταξύ "this" και "is" ; Το να τον μεταφέρει στον χαρακτήρα 'h' είναι επίσης trivial, το να τον μεταφέρει όμως αμέσως μετά το "this" μου έχει βγάλει το λάδι! Φανταστείτε για παράδειγμα το παρακάτω κείμενο... > /******** 8 αστερίσκοι εκατέρωθεν ********/ και τις εντολές... > /!* /!** /!*** Για δώστε τα φώτα σας, γιατί είμαι έτοιμος να τον πετάξω από το παράθυρο τον υπολογιστή, μαζί με τα παρελκόμενά του ΥΓ1. Γνωρίζω την ύπαρξη του regex.h (το οποίο έστω και με κάποιες μικροδιαφορές στα ονόματα, υποστηρίζεται από τους περισσότερους σύγχρονους compilers) όμως δεν θέλω το overhead, μιας και προς το παρόν χρειάζομαι μονάχα ότι περιγράφω παραπάνω (συν αναζήτηση στην αντίστροφη κατεύθυνση). ΥΓ2. Σε περίπτωση που αναρωτιέστε, φτιάχνω έναν HexViewer, οπότε τελικά θα χρησιμοποιήσω regex.h όταν θελήσω να τον κάνω full-blown, αλλά προς το παρόν χρειάζομαι μονάχα ότι περιέγραψα παραπάνω (προέχει δηλαδή να υλοποιήσω πιο βασικά πράγματα, πριν κι εάν καταπιαστώ με regular-expressions). Η παρακάτω εικόνα δείχνει την εν λόγω εντολή, η οποία όπως είναι τώρα απλώς προσπερνάει τον 1ο χαρακτήρα του pattern (σταματάει δηλαδή στο 'h' σύμφωνα με το παράδειγμα που έδωσα στην αρχή του ποστ...
nspyrou Δημοσ. 11 Μαρτίου 2012 Δημοσ. 11 Μαρτίου 2012 Ενδεχομένως να είναι απλό, αλλά έχω φάει 1 ολόκληρη ημέρα χωρία επιτυχία. Βασικά θέλω να υλοποιήσω χειροκίνητα σε C παραπλήσια λειτουργικότητα με το regex... > [^string] Έστω το κείμενο... > Hello, this is a test Έστω οι εντολές... > /this /* αναζήτηση της επόμενης εμφάνισης του string "this" */ /!this /* αναζήτηση του 1ου χαρακτήρα που ΔΕΝ αρχίζει με το string "this" */ Έστω, τέλος, πως ο δρομέας βρίσκεται στο κενό διάστημα μετά το κόμα του "Hello" Η 1η εντολή είναι trivial, κανένα πρόβλημα εκεί. Η 2η όμως εντολή πού πρέπει να μεταφέρει τον δρομέα; Στον χαρακτήρα 'h' ή στο κενό διάστημα μεταξύ "this" και "is" ; Το να τον μεταφέρει στον χαρακτήρα 'h' είναι επίσης trivial, το να τον μεταφέρει όμως αμέσως μετά το "this" μου έχει βγάλει το λάδι! Φανταστείτε για παράδειγμα το παρακάτω κείμενο... > /******** 8 αστερίσκοι εκατέρωθεν ********/ και τις εντολές... > /!* /!** /!*** Για δώστε τα φώτα σας, γιατί είμαι έτοιμος να τον πετάξω από το παράθυρο τον υπολογιστή, μαζί με τα παρελκόμενά του ΥΓ1. Γνωρίζω την ύπαρξη του regex.h (το οποίο έστω και με κάποιες μικροδιαφορές στα ονόματα, υποστηρίζεται από τους περισσότερους σύγχρονους compilers) όμως δεν θέλω το overhead, μιας και προς το παρόν χρειάζομαι μονάχα ότι περιγράφω παραπάνω (συν αναζήτηση στην αντίστροφη κατεύθυνση). ΥΓ2. Σε περίπτωση που αναρωτιέστε, φτιάχνω έναν HexViewer, οπότε τελικά θα χρησιμοποιήσω regex.h όταν θελήσω να τον κάνω full-blown, αλλά προς το παρόν χρειάζομαι μονάχα ότι περιέγραψα παραπάνω (προέχει δηλαδή να υλοποιήσω πιο βασικά πράγματα, πριν κι εάν καταπιαστώ με regular-expressions). Η παρακάτω εικόνα δείχνει την εν λόγω εντολή, η οποία όπως είναι τώρα απλώς προσπερνάει τον 1ο χαρακτήρα του pattern (σταματάει δηλαδή στο 'h' σύμφωνα με το παράδειγμα που έδωσα στην αρχή του ποστ... Εφόσων, θα χρησιμοποιήσεις regular expressions, όταν θα το κάνεις "full-blown",, γιατί δεν το κάνεις από την αρχή να ησυχάσεις και να μη χάνεις το χρόνο σου, με το να ξανα-εφεύρεις το τροχό???
nilosgr Δημοσ. 11 Μαρτίου 2012 Δημοσ. 11 Μαρτίου 2012 επειδη δεν καταλαβα το προβλημα σου, κανεις μια επεξηγηση...;
migf1 Δημοσ. 11 Μαρτίου 2012 Μέλος Δημοσ. 11 Μαρτίου 2012 Εφόσων, θα χρησιμοποιήσεις regular expressions, όταν θα το κάνεις "full-blown",, γιατί δεν το κάνεις από την αρχή να ησυχάσεις και να μη χάνεις το χρόνο σου, με το να ξανα-εφεύρεις το τροχό??? Διότι αφενός δεν είναι σίγουρο πως θα χρησιμοποιήσω τελικά regular expressions γενικώς (εννοώ έχω αμφιβολίες για την γενικότερη χρησιμότητά τους σε έναν HexViewer) κι αφετέρου χρειάζομαι προς το παρόν την συγκεκριμένη και μόνο λειτουργία (και προς τις 2 κατευθύνσεις) για να μπορώ να προσπερνάω γρήγορα byte-sequences που επαναλαμβάνονται συνεχόμενα (ειδικά όταν κάνω view πολύ μεγάλα αρχεία). @nilos: Το πρόβλημα είναι πως δεν μπορώ να φτιάξω έναν γενικό αλγόριθμο (μια συνάρτηση) που να λειτουργεί με συνέπεια σε όλες τις πιθανές περιπτώσεις όταν ο χρήστης δώσει τον τελεστή ! στην αναζήτηση. Αυτό δηλαδή που περιγράφω στο αρχικό ποστ στο παράδειγμα με τους 8 αστερίσκους εκατέρωθεν. Αυτή τη στιγμή οι εντολές αναζήτησης που περιγράφονται στην παρακάτω εικόνα (είναι από το Help screen του viewer) λειτουργούν μεν, αλλά όταν χρησιμοποιηθεί ο τελεστής ! λειτουργεί μονάχα για τον 1ο χαρακτήρα του προς αναζήτηση string και όχι για ολόκληρο το string.
bnvdarklord Δημοσ. 11 Μαρτίου 2012 Δημοσ. 11 Μαρτίου 2012 Τι εννοείς με το αναζήτηση του 1ου χαρακτήρα που δεν αρχίζει από this? Πχ στο παραδειγμα με τα αστεράκια: /******** 8 αστερίσκοι εκατέρωθεν ********/ Αν εχουμε πχ /!** το 1ο αστεράκι αφού αρχίζει με /, οπότε ειναι ο πρώτος που δεν αρχίζει απο ** ? Φανταζομαι εννοείς κατι αλλο.
Directx Δημοσ. 11 Μαρτίου 2012 Δημοσ. 11 Μαρτίου 2012 Ενδεχομένως να είναι απλό, αλλά έχω φάει 1 ολόκληρη ημέρα χωρία επιτυχία. Βασικά θέλω να υλοποιήσω χειροκίνητα σε C παραπλήσια λειτουργικότητα με το regex... [..] Καταρχήν ωραίος! Πριν αρκετό καιρό είχα γράψει έναν Hex Viewer σε C# (σε ρυθμό κονσόλας), η αναζήτηση που εφάρμοζα ήταν τυπική, καθώς ομολογώ ότι η χρήση regexp μου φάνηκε overkill (περιέπλεκε αρκετά τα πράματα), παρόλα αυτά αν αποφασίσεις τελικά να την υποστηρίξεις νομίζω ότι είναι καλύτερα να χρησιμοποιήσεις έτοιμη βιβλιοθήκη καθώς πρόκειται για πολύπλοκο κώδικα. Καλή συνέχεια!!
virxen75 Δημοσ. 11 Μαρτίου 2012 Δημοσ. 11 Μαρτίου 2012 δεν ξέρω αν σε βοηθάει το παρακάτω.Δες το και πες μου > #include <stdio.h> #include <string.h> int main(){ int position=8,tryAgain=1,newPosition=-1,i;//position =τρέχουσα θέση κέρσορα μέσα στην συμβολοσειρά text , newPosition η ζητούμενη θέση του κέρσορα μέσα στην συμβολοσειρά char *ch; char *text="Hello, this is a this test"; char *find="this";//η λέξη μετά την οποία θέλουμε την θέση του κέρσορα char temp[100]; printf("\ntext =\"%s\"\n",text); printf("current cursor position=%d\n",position); printf("string to find=\"%s\"\n",find); //το substring από την θέση του κέρσορα μέχρι το τέλος του κειμένου text for (i=position;i<strlen(text);i++) temp[i-position]=text[i]; temp[i-position]='\0'; //------------------------------------------------------------ while(tryAgain==1){ tryAgain=0; ch=strstr(temp,find); if (!ch){ printf("\nstring not found!\n"); break; } newPosition=strlen(text)-strlen(ch);//θεση κερσορα πριν από την ζητούμενη λέξη---> find newPosition=newPosition+strlen(find);//θέση κέρσορα μετά την ζητούμενη λέξη--> find } printf("new position= %d",newPosition);//Η θέση προκύπτει με βάση το κείμενο text π.χ. 2-->text[2] getchar(); return 0; }
migf1 Δημοσ. 11 Μαρτίου 2012 Μέλος Δημοσ. 11 Μαρτίου 2012 Τι εννοείς με το αναζήτηση του 1ου χαρακτήρα που δεν αρχίζει από this? Πχ στο παραδειγμα με τα αστεράκια: /******** 8 αστερίσκοι εκατέρωθεν ********/ Αν εχουμε πχ /!** το 1ο αστεράκι αφού αρχίζει με /, οπότε ειναι ο πρώτος που δεν αρχίζει απο ** ? Φανταζομαι εννοείς κατι αλλο. Μετρώντας τις θέσεις του κειμένου με 0-based index, και ξεκινώντας από τη θέση 1 (ο 1ος αστερίσκος) τότε... α) με /!* θα πρέπει να πάει στη θέση 8, ταξιδεύοντας με βήμα 1 β) με /!** θα πρέπει να πάει στη θέση 8, ταξιδεύοντας με βήμα 2 γ) με /!*** θα πρέπει να πάει στη θέση 6 (δλδ πριν τους 2 τελευταίους αστερίσκους) ταξιδεύοντας με βήμα 3 Φίλε virxen, ευχαριστώ για τον κώδικα αλλά αυτό το έχω υλοποιήσει ήδη. Το πρόβλημα είναι όταν πρέπει να προσπεράσει επαναλαμβανόμενα, συνεχόμενα patterns. Π.χ. στον κωδικά σου με τα παρακάτω δεδομένα... > char *text = "Hello, thisthisthis is a this test"; int pos = 6; θέλουμε να πάει τον δρομέα στη θέση 18 (και όχι στη θέση 11 που τον πάει τώρα). Ένα επιπρόσθετο πρόβλημα είναι πως δεν μπορώ να χρησιμοποιήσω έτοιμες συναρτήσεις str* διότι περιμένουν null-terminated strings, ενώ η ρουτίνα πρέπει να μπορεί να εφαρμοστεί και σε μη-NULL terminated strings, όταν εφαρμόζεται στο hex area αντί για το ascii area. Όπως γράφω και παραπάνω, όλα αυτά τα έχω φτιάξει ήδη, εκτός από το συγκεκριμένο που ρώτησα, δηλαδή την εξαίρεση της συμβολοσειράς (ή ακολουθίας από bytes για να είμαστε ακριβέστεροι). Για όποιον ενδιαφέρεται, ο τωρινός κώδικας για την αναζήτηση ascii string (χωρίς να στηρίζεται σε null-terminated strings) είναι ο ακόλουθος... > ... bool negmode = false; /* exclude string from search? */ char *tmpstr = NULL; uintmax_t ibt; /* update bt only if str found */ size_t slen, ssize; /* string len & size in Bytes */ int tmp = 1; /* temporary int MUST INIT to 1*/ ... /* housekeeping */ ibt = *bt; /* remember cursor position */ tmpstr = command_strsearch_parse( cmd, &negmode ); /* get negmode & strkey*/ if ( !tmpstr ) return false; slen = strlen( tmpstr ); ssize = slen * sizeof(Byte); /* Byte is our own custom type */ /* (!)search forward for string */ if ( KEY_FNDSTR == key && slen > 0 ) { colorMSG( settings, MSGTXT_SEARCHING ); ibt = ibt > 0 ? ibt + 1 : 1; /* do the search */ if ( negmode ) { while ( ibt < buffer->len - slen + 1 && !(tmp = memcmp(&buffer->data[ibt], (Byte *)tmpstr, ssize)) ) ibt++; } else { while ( ibt < buffer->len - slen + 1 && (tmp = memcmp(&buffer->data[ibt], (Byte *)tmpstr, ssize)) ) ibt++; } colorMSG( settings, MSGTXT_DONE ); } /* (!)search backward for string */ else if ( KEY_RFNDSTR == key && slen > 0 ) { colorMSG( settings, MSGTXT_SEARCHING ); ibt = ibt > 0 ? ibt - 1 : 0; /* do the search */ if ( negmode ) { while ( ibt > 0 && !(tmp=memcmp(&buffer->data[ibt], (Byte *)tmpstr, ssize)) ) ibt--; /* 0 is treaded separately because ibt is unsigned */ if ( ibt == 0 && tmp == 0 ) tmp = memcmp( &buffer->data[ibt], (Byte *)tmpstr, ssize ); } else { while ( ibt > 0 && (tmp = memcmp(&buffer->data[ibt], (Byte *)tmpstr, ssize)) ) ibt--; /* 0 is treaded separately because ibt is unsigned */ if ( ibt == 0 && tmp != 0 ) tmp = memcmp( &buffer->data[ibt], (Byte *)tmpstr, ssize ); } colorMSG( settings, MSGTXT_DONE ); } /* invalid command key */ else { return false; } /* string found? update cursor position */ if ( (0 == tmp && !negmode) || (0 != tmp && negmode) ) *bt = ibt; else BELL(1); ... Ενώ για την αναζήτηση 16αδικής ακολουθίας από bytes είναι ο εξής... > ... bool negmode = false; /* exclude seq from search? */ char *cp = NULL; /* for sscanf'ing the hex seq */ uintmax_t ibt; /* update bt only if str found */ uintmax_t iseq; /* eventually the len of seq[] */ Byte seq[MAXINPUT] = {0}; /* to hold the byte-sequence */ int tmp = 1; /* temporary int MUST INIT TO 1*/ ... /* convert the text-string pointed to by cp into a byte-sequence seq[] */ cp = (char *)( negmode ? &cmd[2] : &cmd[1] ); tmp = iseq = 0; while ( 1 == sscanf( (cp+tmp), "%2"SCNx8, (Byte *)&seq[iseq]) ) { tmp += 2; iseq++; } seq[iseq] = '\0'; /* this is just for debugging */ /* (!)search forward for byte-sequence */ if ( KEY_FNDSEQ == key && iseq > 0 ) { colorMSG( settings, MSGTXT_SEARCHING ); ibt = ibt > 0 ? ibt + 1 : 1; /* do the search */ if ( negmode ) { while ( ibt < buffer->len - iseq + 1 && !(tmp=(memcmp( &buffer->data[ibt], seq, iseq*sizeof(Byte) ))) ) ibt++; } else { while ( ibt < buffer->len - iseq + 1 && (tmp=(memcmp( &buffer->data[ibt], seq, iseq*sizeof(Byte) ))) ) ibt++; } colorMSG( settings, MSGTXT_DONE ); } /* (!)search backwards for byte-sequence */ else if ( KEY_RFNDSEQ == key && iseq > 0 ) { colorMSG( settings, MSGTXT_SEARCHING ); ibt = ibt > 0 ? ibt - 1 : 0; /* do the search */ if ( negmode ) { while ( ibt > 0 && !(tmp=memcmp(&buffer->data[ibt], seq, iseq * sizeof(Byte))) ) ibt--; /* 0 is treaded separately because ibt is unsigned */ if ( ibt == 0 && tmp == 0 ) tmp = memcmp(&buffer->data[ibt], seq, iseq * sizeof(Byte)); } else { while ( ibt > 0 && (tmp=memcmp(&buffer->data[ibt], seq, iseq * sizeof(Byte))) ) ibt--; /* 0 is treaded separately because ibt is unsigned */ if ( ibt == 0 && tmp != 0 ) tmp = memcmp(&buffer->data[ibt], seq, iseq * sizeof(Byte)); } colorMSG( settings, MSGTXT_DONE ); } /* invalid command key */ else { return false; } /* sequence found? update cursor position */ if ( (0 == tmp && !negmode) || (0 != tmp && negmode) ) *bt = ibt; else BELL(1); ... ο οποίος κάνει την τετριμμένη αναζήτηση (και προς τις 2 κατευθύνσεις) και όχι αυτό που περιγράφω στο νήμα. @DirectX: Ωραίος κι εσύ φίλε DirectX. Αυτό που φτιάχνω εγώ είναι σε στάνταρ ISO C99 και σκοπεύω να το αφήσω ελεύθερο όταν το τελειώσω (για τον κώδικα εννοώ). ΤΥο έχω έτοιμο κατά τα 3/4 (ή 3/5, δεν ξέρω ακόμα ). Τα βασικά που λείπουν (πριν ασχοληθώ με regex.h ή κάποια άλλη σχετική βιβλιοθήκη) είναι: α) bookmarks β) selection highlighting (με δυνατότητα αποθήκευσης ... όχι clipboard, γιατί αυτό είναι platform-specific) γ) προβολή βασικών data types σύμφωνα με το byte που βρίσκεται ο δρομέας (αυτή τη στιγμή δείχνει στη μωβ μπάρα μόνο τα πρώτα 8 bits ως: char, signed/unisgned 10-δικό, unsigned 16-αδικό, unsigned 8-δικό και 2-αδικό... θα του προσθέσω και 16 και 32 bits απεικονίσεις από τη θέση του δρομέα, καθώς και απεικόνιση float, double και long-double) δ) command-line argument support (προς το παρόν δέχεται μονάχα 1 argument, το αρχείο που θα ανοίξει... αν κι έχει κι εσωτερική εντολή για αυτό... βασικά στόχος είναι όλες οι εσωτερικές εντολές να μπορούν να ρυθμιστούν και με command-line arguments). ε) Unicode support στο ASCII pane (τώρα δείχνει είτε ASCII, είτε extended ASCII... άρα και τα βασικά του UTF-8) ... αυτό ίσως το παραλείψω, δεν ξέρω... έχει πολύ δρόμο ακόμα μέχρι να φτάσω εκεί Του έχω βάλει και skin-support (του έχω φτιάξει 4 skins μέχρι στιγμής) ενώ το έχω κάνει και δίγλωσσο (Ελληνικά.Αγγλικά) με τα output text της κάθε γλώσσας να είναι ένα ξεχωριστό header file... άρα κάθε νέα γλώσσα θέλει νέο compile, με ορισμένο το κατάλληλο #define. Τα 4 skins μέχρι στιγμής όπως φαίνονται στην κονσόλα των Windows με μαύρο φόντο (πάνω εικόνες) και στο Cygwin με άσπρο φόντο (κάτω εικόνες). Το Cygwin προσομοιώνει Linux στην κονσόλα των Windows, και όπως φαίνεται από τις εικόνες μεταφράζονται σε ελαφρώς διαφορετικά χρώματα τα ANSI escape sequences... (ανοίξτε το spoiler)... SKIN SCREEN-SHOTS (ανοίξτε το spoiler)... BLACK SKIN: BLUE SKIN: RED SKIN: GRAY SKIN: ΥΓ1. Το βασικό μου πρόβλημα τις 2 τελευταίες ημέρες είναι αυτό με την αναζήτηση, που τελικά αναγκάστηκα να ζητήσω τη βοήθειά σας. ΥΓ2. Αν δεν σας πειράζει που πολλά κομμάτια του κώδικα είναι ακόμα σε κατάσταση "first-draft" και θέλετε να τον χαζέψετε, πείτε μου να τον ποστάρω.
Directx Δημοσ. 11 Μαρτίου 2012 Δημοσ. 11 Μαρτίου 2012 [..][..] α) bookmarks β) selection highlighting (με δυνατότητα αποθήκευσης ... όχι clipboard, γιατί αυτό είναι platform-specific) [..] ε) Unicode support στο ASCII pane (τώρα δείχνει είτε ASCII, είτε extended ASCII... άρα και τα βασικά του UTF-8) ... αυτό ίσως το παραλείψω, δεν ξέρω... έχει πολύ δρόμο ακόμα μέχρι να φτάσω εκεί Λοιπόν, όταν έγραφα το δικό μου, είχα σκεφτεί την προσθήκη των α) & β) αλλά τελικά δεν τα έβαλα καθώς αν το αρχείο αλλάξει τότε όλες αυτές οι πληροφορίες μπορεί να χρειασθούν ανανέωση, οπότε κάπου εκεί (συν ότι ήταν καλοκαίρι και τεμπέλιασα ) προτίμησα τελικά να μην τις υποστηρίξω. Παρόλα αυτά ψηφίζω υπέρ της προσθήκης τους (+1)! Για το ε), εδώ εκμεταλλεύομαι την υποστήριξη Unicode του .NET οπότε παρέχω την δυνατότητα στον χρήστη να γράψει ένα δικό του code-page script αρχείο της μορφής ASCII-Code=Unicode χαρακτήρας (έτσι μπορώ να προσφέρω υποστήριξη 737 ή 1253 Ελληνικών ή άλλων γλωσσών κλπ άνετα καθώς ο Viewer βλέπει τα αρχεία ως ASCII) -στο αναφέρω μήπως και φανεί χρήσιμο (ως ιδέα). Υ.Γ. Πολύ ωραία ιδέα τα skins (και όμορφες χρωματικές επιλογές +1)
migf1 Δημοσ. 11 Μαρτίου 2012 Μέλος Δημοσ. 11 Μαρτίου 2012 ... Για το ε), εδώ εκμεταλλεύομαι την υποστήριξη Unicode του .NET οπότε παρέχω την δυνατότητα στον χρήστη να γράψει ένα δικό του code-page script αρχείο της μορφής ASCII-Code=Unicode χαρακτήρας (έτσι μπορώ να προσφέρω υποστήριξη 737 ή 1253 Ελληνικών ή άλλων γλωσσών κλπ άνετα καθώς ο Viewer βλέπει τα αρχεία ως ASCII) -στο αναφέρω μήπως και φανεί χρήσιμο (ως ιδέα). ... Thanks! Αν και το κάνω κι εγώ support (μόνο σε Windows), μέσω μια συλλογής από macros που είχα φτιάξει για αυτό το σκοπό. Νομίζω την είχα ποστάρει κι εδώ, αλλά επειδή βαριέμαι τώρα να ψάχνω... > /*****************************************************//** * @file w32con_cpout.h * @version 0.1A * @date 4 Feb, 2012 * @author migf1 <[email protected]> * @par Language: * C (C99 / ANSI C89) * * @brief A small preprocessor interface to easily manage the * output codepage of the Windows' console (XP or later). * * @par Sample usage: * @code * #include "w32con_cpout.h" * ... * int main( void ) * { * W32CON_CPOUT_STORE(); // αποθήκευση τρέχουσας κωδικοσελίδας * W32CON_CPOUT_SET(1253); // αλλαγή κωδικοσελίδας σε Windows-1253 * ... * W32CON_CPOUT_RESTORE(); // επαναφορά αρχικής κωδικοσελίδας * exit(0); * } * @endcode ********************************************************* */ #ifndef W32CON_CPOUT_H /* Inclusion Guard */ #define W32CON_CPOUT_H /** @cond */ /* #define _WIN32 */ /** @endcond */ #if defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__) || defined(__TOS_WIN__) /** @cond start doxygen exclusion */ #include <windows.h> UINT oRIgiNalCp = 737; /** @endcond */ /** * @brief Store the current output codepage. */ #define W32CON_CPOUT_STORE() \ do { \ oRIgiNalCp = GetConsoleOutputCP(); \ } while(0) /** * @brief Get the current output codepage. * @return The identifier of the current output codepage. * @sa * http://msdn.microsoft.com/en-us/library/windows/desktop/dd317756%28v=vs.85%29.aspx */ #define W32CON_CPOUT_GET() GetConsoleOutputCP() /** * @brief Set a new output codepage. * @param[in] newcp (UINT) The identifier of the codepage to be set. * @sa * http://msdn.microsoft.com/en-us/library/windows/desktop/dd317756%28v=vs.85%29.aspx */ #define W32CON_CPOUT_SET( newcp ) \ do { \ if ( !SetConsoleOutputCP( (UINT) newcp ) ) \ fprintf(stderr, \ "\n*** %s|Ln%d: CP%u WAS NOT SET!\n\n", \ __func__, __LINE__, (UINT)(newcp) \ ); \ else printf("Active code page: %u\n\n", (UINT)(newcp) ); \ } while(0) /** * @brief Set the output codepage to UTF-8 (65001). */ #define W32CON_CPOUT_SET_UTF8() \ do { \ if ( !SetConsoleOutputCP( (UINT)65001 ) ) \ fprintf(stderr, \ "\n*** %s|Ln%d: UTF-8 WAS NOT SET!\n\n", \ __func__, __LINE__ \ ); \ else puts("Active code page: 65001 (UTF-8)\n"); \ } while(0) /** * @brief Set the output codepage to UTF-7 (65000) */ #define W32CON_CPOUT_SET_UTF7() \ do { \ if ( !SetConsoleOutputCP( (UINT)65000 ) ) \ fprintf(stderr, \ "\n*** %s|Ln%d: UTF-7 WAS NOT SET!\n\n", \ __func__, __LINE__ \ ); \ else puts("Active code page: 65000 (UTF-7)\n"); \ } while(0) /** * @brief Restore the output codepage that was * previously stored with W32CON_CPOUT_STORE(). */ #define W32CON_CPOUT_RESTORE() \ do { \ if ( !SetConsoleOutputCP( oRIgiNalCp ) ) \ fprintf(stderr, \ "\n*** %s|Ln%d: CP%u WAS NOT RESTORED!\n\n", \ __func__, __LINE__, oRIgiNalCp \ ); \ else printf( "Active code page: %u\n\n", (UINT)oRIgiNalCp); \ } while(0) #else #define W32CON_CPOUT_STORE() #define W32CON_CPOUT_GET() #define W32CON_CPOUT_SET( dummy ) #define W32CON_CPOUT_SET_UTF8() #define W32CON_CPOUT_SET_UTF7() #define W32CON_CPOUT_RESTORE() #endif #endif /* #ifndef W32CON_CPOUT_H */ Απλώς το έχω hardcoded αυτή τη στιγμή στον κώδικα... > int main( int argc, char *argv[] ) { bool success = false; char tmpfname[ MAXINPUT ] = {'\0'}; Buffer buffer; /* our Buffer struct, must be inited */ Settings settings; /* our Settings struct, must be inited */ W32CON_CPOUT_STORE(); // αποθήκευση τρέχουσας κωδικοσελίδας W32CON_CPOUT_SET(1253); // αλλαγή κωδικοσελίδας σε Windows-UTF8 CONOUT_INIT(); settings_init( &settings ); buffer_init( &buffer ); ... buffer_cleanup( &buffer ); CONOUT_RESTORE(); W32CON_CPOUT_RESTORE(); // επαναφορά αρχικής κωδικοσελίδας exit( EXIT_SUCCESS ); } αλλά είναι πολύ εύκολο να το μετατρέψω σε user-defined επιλογή Υ.Γ. Πολύ ωραία ιδέα τα skins (και όμορφες χρωματικές επιλογές +1) Ευχαριστώ ρε συ! Και το δικό σου όμως δεν πάει πίσω : ΥΓ. Πρέπει να οργανωθούμε 5-6 από το φόρουμ και να ξεκινήσουμε κάνα κοινό project με επιμερισμό εργασιών, να περνάμε την ώρα μας (όση μας μένει ελεύθερη δηλ :lol;) θα είναι καλή φάση
bnvdarklord Δημοσ. 12 Μαρτίου 2012 Δημοσ. 12 Μαρτίου 2012 Αυτό σε (C++ με strings ομως) κανει αυτό που θες νομιζω. Για το παράδειγμα που δινω κατω βγαζει 18 και για τα * τις τιμες που ειπες. Ουσιαστικά μονο η find και η length παιζουν που θελουν null terminated strings που θες να αποφυγεις, αλλα η υλοποιηση τους ειναι πολυ απλή, οποτε φαντάζομαι σου κανει. > #include <iostream> #include <string> using std::cout; using std::endl; using std::string; int exclIndex(string text, string z) { int textLen = text.length(); int zLen = z.length(); int pos = text.find(z, 0); int prevpos = pos; while(pos != -1) { pos = text.find(z, pos + zLen); if(pos == -1 || pos > prevpos + zLen) { return prevpos + zLen - 1; } prevpos = pos; } return -1; } int main() { string s = "Hello, thisthisthis is a this test"; string z = "this"; cout << exclIndex(s, z); return 0; }
migf1 Δημοσ. 12 Μαρτίου 2012 Μέλος Δημοσ. 12 Μαρτίου 2012 Παιδιά 1000 ευχαριστώ για τους κώδικες, με βοήθησαν! Κυρίως ο κώδικας που μου έστειλε ο Virxen σε pm, που κάνει truncate την αρχή του κειμένου σε κάθε επανάληψη, αν και ο κώδικας που έγραψα μοιάζει περισσότερο με του bnvdarklord (τον οποίο τον είδα στο νήμα αφού είχα γράψει τον δικό μου). Τελικά δεν ήταν κάτι το δύσκολο, αλλά πραγματικά είχα κολλήσει! Κατέληξα στον παρακάτω κώδικα, αλλά δεν το έχω τεστάρει όσο πρέπει ακόμα... αύριο γιατί με πήρε η μαύρη νύχτα σήμερα... > #include <stdio.h> #include <string.h> #include <inttypes.h> typedef uint8_t Byte; /* --------------------------------------------------------------- */ size_t buflookup_exclude_str( const Byte *buffer, const size_t startpos, const size_t bufsize, const char *str ) { int temp = 0; size_t i, ssize = strlen( str ) * sizeof(char); /* sanity checks */ if ( !buffer || !str || !*str ) return startpos; i = startpos; while ( temp == 0 && i < bufsize - ssize) { temp = memcmp( (char *)(&buffer[i]), str, ssize ); i += ssize; } return (temp != 0) ? i -= ssize : i; } Αύριο θα φτιάξω και μια αντίστοιχη συνάρτηση για την άλλη κατεύθυνση (προς τα πίσω). Και πάλι ευχαριστώ! Α, έγραψα και μια main για testing της συνάρτησης... > int main( void ) { // Byte buffer[]= "/******** ********/"; // char str[] = "***"; Byte buffer[]= "thisthisthis is a this test"; char str[] = "this"; size_t bufsize = sizeof(buffer); size_t pos = 0; printf( "\nbuffer : \"%s\"\n", buffer ); printf( "!find : \"%s\"\n", str ); printf( "istart %02zu: \"%s\"\n\n", pos, &buffer[pos] ); for (; { pos = buflookup_exclude_str( buffer, pos, bufsize, str ); printf( "result %02zu: \"%s\"", pos, &buffer[pos] ); if ( pos++ >= bufsize - 1 ) break; printf( "\t...press ENTER... " ); getchar(); } printf( "\tpress ENTER... " ); getchar(); return 0; }
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα