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

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

Δημοσ.

Γνωρίζει κανείς αν ο \t παράγει πάντα 8 χαρακτήρες στο stdout? Ορίζεται από το πρότυπο? Όπου το έχω δοκιμάσει παράγει 8 χαρακτήρες, αλλά είναι στάνταρ?

 

Έχω μια συνάρτηση που μετράω το μήκος της μεγαλύτερης γραμμής μέσα σε οποιοδήποτε c-string, και χρειάζομαι να μετράει τα tabs expanded. Αν ισχύουν στάνταρ οι 8 χαρακτήρες να καταργήσω αν είναι το όρισμα tabSize...

Δεν ξέρω αν είναι σταθερό. (Δε μπορώ να βοηθήσω επί τις ουσίας)

Καλύτερα να το αφήσεις σαν παράμετρο. Γιατί ακόμα και αν είναι σταθερό σε όλα τα terminlas (που δε το νομίζω) σίγουρα σε όλους τους (σοβαρούς) text editors το ρυθμίζεις όσο θες.

 

Το βρίσκω καλύτερο να έχεις μια Α ευελιξία στη συνάρτηση.

 

Μάλιστα θα έλεγα το fallback σου να μην είναι το 8 αλλά το 1. Ούτως σώστε αν δοθεί τιμή < 1 να μετρήσεις έστω την ύπαρξη του \t σαν χαρακτήρα.

 

EDIT (τροφή για σκέψη):

 

Θα είχε νόημα να διαχωρίζεις τους visible από τους μη, χαρακτήρες ώστε οι δεύτεροι να μην προσμετρώνται;

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

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

Δημοσ.

...

Edit: Εφόσον θέλεις να ξέρεις το μέγεθος της "expanded" γραμμής, αρκεί να προσθέτεις το tabsize ? Δεν θα πρέπει στον κώδικα να λαμβάνεις υπόψη και την τιμή του j ?

 

Νομίζω δεν καταλαβαίνω τι με ρωτάς εδώ;

Αυτή η γραμμή...

 

>
...
              j = ('\t' == s[i]) ? j+tabSize : j+1;
...

 

δεν λαμβάνει υπόψη της την τιμή του j; Εννοείς κάτι άλλο;

 

 

Δεν ξέρω αν είναι σταθερό. (Δε μπορώ να βοηθήσω επί τις ουσίας)

Καλύτερα να το αφήσεις σαν παράμετρο. Γιατί ακόμα και αν είναι σταθερό σε όλα τα terminlas (που δε το νομίζω) σίγουρα σε όλους τους (σοβαρούς) text editors το ρυθμίζεις όσο θες.

 

Το βρίσκω καλύτερο να έχεις μια Α ευελιξία στη συνάρτηση.

 

Μάλιστα θα έλεγα το fallback σου να μην είναι το 8 αλλά το 1. Ούτως σώστε αν δοθεί τιμή < 1 να μετρήσεις έστω την ύπαρξη του \t σαν χαρακτήρα.

 

Ναι, έτσι θα το αφήσω. Αλλά την θέλω για πολύ συγκεκριμένη χρήση, όπου δεν με εξυπηρετεί να κάνει fall-back σε 1. Ή μάλλον, με εξυπηρετεί καλύτερα να κάνει fall-back σε 8.

 

Θέλω να μου τυπώνει τις γραμμές του c-string, γεμίζοντας με έναν χαρακτήρα τα τελειώματα όσων γραμμών είναι μικρότερες από την μέγιστη μέσα στο c-string, μέχρι τη στήλη που τελειώνει η μέγιστη γραμμή.

 

Δημοσ.

Προφανώς είναι ο tab χαρακτήρας o '\t', εξού και το tabSize. Δεν ξέρω αν η διατύπωση μου έδινε την εντύπωση ότι ρωτάω ποιος χαρακτήρας είναι ο '\t', αλλά δεν ήταν αυτή η πρόθεσή μου.

 

Το φαντάστηκα ότι το γνωρίζεις απλά ήθελα να τονίσω ότι δεν γράφονται/διαβάζονται ένας-αριθμός-από-spaces αλλά ένας μόνο χαρακτήρας και απλά μετά αυτός γίνεται expand από τον terminal driver.

 

 

 

Νομίζω δεν καταλαβαίνω τι με ρωτάς εδώ;

Αυτή η γραμμή...

 

>
...
              j = ('\t' == s[i]) ? j+tabSize : j+1;
...

 

δεν λαμβάνει υπόψη της την τιμή του j; Εννοείς κάτι άλλο;

 

Ο κώδικας μετράει τους χαρακτήρες αυξάνοντας το j κατά ένα για κάθε χαρακτήρα εκτός αν ο τρέχων χαρακτήρας είναι TAB οπότε αυξάνει κατά 8 (ας υποθέσουμε ότι tabsize == 8), σωστά ?

Δημοσ.

Σωστά.

 

Καλά το κατάλαβα τότε :)

 

Είχες δουλέψει καθόλου τις παλιές γραφομηχανές τις "μηχανικές" ας τις πούμε ? Υπήρχαν κάποια δοντάκια σε fixed θέσεις και όταν πατούσες το "tab", ο δρομέας μετακινούνταν σε αυτά τα δοντάκια δημιουργώντας επίπεδα εσοχών.

 

Αυτή τη δουλειά μιμείται και το Tab στα τερματικά. Όταν λέμε "το tab ισοδυναμεί με 8 spaces" (ή 4 ή οσεσδήποτε) δεν σημαίνει ότι εισάγονται κάθε φορά 8 spaces αλλά ότι μετακινείται ο δρομέας στο επόμενο 8άρι επίπεδο εσοχής.

 

Για να το πω πιο απλά, αν γράψεις "12" και πατήσεις tab, ο δρομέας θα μετακινηθεί στην επόμενη εσοχή που με 8άρια tab είναι η στήλη 9. Αν έχεις γράψει "12345" και πατήσεις tab, και πάλι θα μετακινηθεί στη στήλη 9. Για αυτό το λόγο θα πρέπει να λαμβάνεις υπόψη την τιμή του j ώστε να προσθέτεις τον κατάλληλο αριθμό spaces.

  • Like 1
Δημοσ.

Και πάλι έχεις απόλυτο δίκιο ;)

 

Οπότε πρέπει να παιχτεί κάτι με (j % tabSize) ... αλλά τώρα παλεύω με κάτι άλλα. Θα το κάνω όμως και θα ξανα-ποστάρω ;)

Δημοσ.

...

EDIT (τροφή για σκέψη):

 

Θα είχε νόημα να διαχωρίζεις τους visible από τους μη, χαρακτήρες ώστε οι δεύτεροι να μην προσμετρώνται;

 

Το σκέφτηκα κι εγώ αυτό, να αφήνω δηλαδή το tabSize να παίρνει και την τιμή 0, αυτό δεν εννοείς; Αλλά υπάρχουν κι άλλοι non-visible χαρακτήρες, και νομίζω πως δεν εξυπηρετεί κιόλας να τα βάλουμε όλα μαζί σε μια συνάρτηση.

 

Καλύτερα να γίνει ξεχωριστή συνάρτηση αν είναι (υπάρχουν και οι έτοιμες isspace() και isblank() ).

 

Για το modulus με το tabSize, πρέπει να κάτσω να το δοκιμάσω. Δεν είμαι σίγουρος πως αρκεί αυτό που έγραψες (θα το κοιτάξω με ησυχία αργότερα ή αύριο, να τελειώσω πρώτα κάτι άλλα που κάνω και με παιδεύουν). Αλλά δοκιμάστε το κι εσείς αν έχετε όρεξη, να το διορθώσετε εννοώ.

Δημοσ.

Σε ένα πρόχειρο τεστ που έκανα φαίνεται να δουλεύει καλά.

 

 

 

>

#include <stdio.h>

int s_maxLineLen( const char *s, int tabSize )
{
   int i=0,j=0, maxLineLen = 0;

   if ( !s )
       return -1;
   if ( !*s )
       return 0;

   if ( tabSize < 1 )
       tabSize = 8;

   // count len of largest line in s
   for (i=0,j=0; '\0' != s[i] && EOF != (int)(s[i]); i++)
   {
       if ( '\n' == s[i] ) {
           if ( j > maxLineLen )
               maxLineLen = j;
           j = 0;
           continue;
       }
       j += ('\t' == s[i]) ? (tabSize - (j % tabSize))  : 1;
   }
   if ( j > maxLineLen )
       maxLineLen = j;

   return maxLineLen;
}

void test_m(const char *strName, const char *str)
{
   printf("%s:  %d\n", strName, s_maxLineLen(str, 8));
}

int main(int argc, char **argv)
{
   char *s1 = "1234\tFF";               //10
   char *s2 = "123456789\tFF";          //18;
   char *s3 = "1234567812345678\t";     //24;
   char *s4 = "12345678123456781234\t"; //24;
   char *s5 = "1234567812345678\t4567"; //28;

   test_m("s1", s1);
   test_m("s2", s2);
   test_m("s3", s3);
   test_m("s4", s4);
   test_m("s5", s5);

   return 0;
}

output:

 

 

s1: 10

s2: 18

s3: 24

s4: 24

s5: 28

 

 

 

Δημοσ.

@moukoublen:

 

Στα πρόχειρα που το δοκίμασα, νομίζω είναι όπως το είπες...

 

>
	j = ('\t' == s[i]) ? j+(tabSize - (j%tabSize)) : j+1;

 

Και ...

 

>
...
int main( void )
{
   char *s = "12\t1234\t.";

   puts(s);
   printf("%s\n", s);
   printf( "s_maxLineLen(%s): %d\n", s, s_maxLineLen(s,8) );

   system( "pause" );
   ...
}

 

Το τελευταίο printf() τα παίζει, επειδή το s εμφανίζεται και στα 2 ορίσματά του, αλλά η puts() και η 1η printf() νομίζω αρκούν για να επιβεβαιώσουν το ορθό του modulus.

 

Δημοσ.

EDIT: Πήγα να το γράψω γρήγορα να να προστεθεί στο παραπάνω αλλά με πρόλαβες και έγραψες ενδιάμεσα :)

 

Για visible και μη έλεγα όλους του άλλους πέραν του tab που κάτι εκτυπώνεται για αυτό.

 

Δηλαδή αφού γίνεται η "ερμηνεία" του \t ας γίνει και για τους άλλους χαρακτήρες (δηλαδή να μην υπολογίζονται).

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

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

Λοιπόν έτρεξα και το δικό σου παράδειγμα και βγαίνει σωστό:

 

1-------1-------1-------1-------

12------1234----.

12------1234----.

s_maxLineLen(12 1234----.): 17

1-------1-------1-------1-------

 

Σημ: βάζω - αντί για space γιατί τα space τα τρώει o "προβολέας" των post. Ετσι κι αλλιώς στο terminal βγαίνει απλα ο χαρακτήρας tab και αυτό μεταφράζει ανάλογα το σε πια στήλη πρέπει να πάει.

 

Με το 1 σημειώνω την έναρξη ανα 8δες. Οπότε (αυτονόητα) σωστή είναι η εκτύπωση.

Σαν αυτόνομο μέγεθος η φράση (αν ξεκινήσει απο την αρχή της γραμμής του terminal) τόσο πιάνει. 17 χαρακτήρες.

 

 

Οταν όμως μπαίνει μέσα στο μήνυμα s_maxLineLen() δεν είναι είναι πια αυτόνομο.

 

Προηγούνται αυτού 13 χαρακτήρες.

 

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

 

Οπότε και λογικά αν μέσα στο μήνυμα πριν τη φράση προηγούνταν ακέραιο πολλαπλάσιο του 8 η φράση θα ήταν ακριβώς ίδια "εμφανισιακά".

 

δηλαδή

 

>
char *s = "12\t1234\t.";
puts(s);
printf("%s\n", s);
printf( "s_maxLineLen(%s): %d\n", s, s_maxLineLen(s,8) );
printf( "s_maxLineLen (%s): %d\n", s, s_maxLineLen(s,8) );

 

έχει σαν έξοδο.

 

|-------|-------|-------|-------|-------

12------1234----.

12------1234----.

s_maxLineLen(12-1234----.): 17

s_maxLineLen (12------1234----.): 17

|-------|-------|-------|-------|-------

 

Στη δεύτερη περίπτωση τοποθετώ άλλους 3 χαρακτήρες πριν τι φράση μας (τα spaces πριν την παρένθεση) ώστε οι συνολικοί χαρακτήρες πριν το μήνυμα να είναι 16. Και έτσι το μήνυμα έχει ακριβώς την ίδια "εμφάνιση"

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

Δεν θα πρέπει να ελέγχεται αν στη γραμμή υπάρχουν "ειδικοί" χαρακτήρες ?

 

>
int main(int argc, char **argv)                                                 
{                                                                               
       char *s1 = "1234\tFF";                                                  
       char *s3 = "1234\t\bFF";                                                
       char *s4 = "1234\r2\tFF";                                               
       char *s5 = "1234\t\rFF";                                                

       printf("123456781234567812345678\n");                                   

       test_m("s1", s1);                                                       
       printf("%s\n",s1);                                                      
       test_m("s3", s3);                                                       
       printf("%s\n",s3);                                                      
       test_m("s4", s4);                                                       
       printf("%s\n",s4);                                                      
       test_m("s5", s5);                                                       
       printf("%s\n",s5);                                                      

       return 0;                                                               
}

 

Έξοδος linux-gcc:

>
123456781234567812345678
s1:  10
1234    FF
s3:  11
1234   FF
s4:  10
2234    FF
s5:  11
FF34    

 

Έξοδος ideone:

>
123456781234567812345678
s1:  10
1234    FF
s3:  11
1234    FF
s4:  10
1234
2    FF
s5:  11
1234    
FF

 

Όπως βλέπουμε, μόνο το s1 είναι πραγματικό τόσο μεγάλο όσο υπολογίζεται.

Δημοσ.

Δεν θα πρέπει να ελέγχεται αν στη γραμμή υπάρχουν "ειδικοί" χαρακτήρες ?

 

Μα αυτό έλεγα πριν όταν μίλησα για visible και μη visible χαρακτήρες :) . Τελικά είναι εύκολο να προστεθεί σαν "επέκταση".

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

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