Ersetzen von Tabulator durch Leerzeichen



  • So soll das ganze nachher aussehen:

    http://i.imgur.com/wnVMwDi.png



  • In deiner Eingabedatei (wenn sie richtig ist), kommt weder das Zeichen \ noch t noch n drin vor.
    Also sind deine Vergleiche (Zeile 24, 34 und 78) nicht richtig.
    (Komischerweise war der Vergelich in deinem ersten Post richtig.)

    Sehrwohl kommen der Tabulator und und Newline drin vor.

    Und bei deinem switch gibt es einen Zusammenhang zwischen counter, i und der Zahl mit der du counter immer vergleichst.
    Diesen Zusammenhang kann man mit einer Subtraktion ausdrücken.

    Komischerweise war der Vergelich in deinem ersten Post richtig



  • @EOP: Könnte ich. Aber warum sollte ich?

    @OP: Schau dir mal diese kleine Referenzimplementierung an:

    #include <limits.h> /*Fuer size_t*/
    #include <string.h> /*Fuer strlen*/
    #include <stdlib.h> /*Fuer die EXIT_*-Konstanten*/
    #include <stdio.h>  /*Fuer printf und solche Spaesse.*/
    
    /*Seit mich DirkB darauf aufmerksam gemacht hat, dass %lu nicht immer korrekt
    **ist, aber da %z erst in C99 vorgestellt wurde ... :p*/
    #if defined(__x86_64__) || defined(_M_X64)
     #ifdef _WIN64
      #ifdef __CYGWIN__
       #define SIZE_T_PRINTF "%lu"
      #else
       #define SIZE_T_PRINTF "%I64u"
      #endif
     #else
      #define SIZE_T_PRINTF "%lu"
     #endif
    #else
     #define SIZE_T_PRINTF "%u"
    #endif
    
    /*Anzahl der Zeichen, die ein Tabstopp wert ist.*/
    #define SPACES_PER_TAB (4)
    
    /*Zeichen, welches das Ersetzen auslösen soll.*/
    #define SEARCH_CHAR '\t'
    
    int main(int argc,char*argv[])
    {
            size_t index_args,
                    index_string,
                    index_string_visual,
                    spaces_current,
                    spaces_left_to_print,
                    string_length;
    
            /*Keine Daten angegeben.*/
            if(argc<2)
            {
                    fprintf(stderr,"Usage: %s <parameters>\n",argv[0]);
                    exit(EXIT_FAILURE);
            }
    
            for(index_args=1;index_args<argc;index_args++)
            {
                    /*Anfang des Strings.*/
                    printf("Chunk No. " SIZE_T_PRINTF "\n"
                            "===============================================================================\n",
                            index_args);
    
                    /*Ansgabe mit gleichzeitiger Ersetzung.*/
                    string_length=strlen(argv[index_args]);
                    for(index_string=0,index_string_visual=0;index_string<string_length;index_string++,index_string_visual++)
                    {
                            if(argv[index_args][index_string]==SEARCH_CHAR)
                            {
                                    spaces_current=0;
                                    spaces_left_to_print=SPACES_PER_TAB-index_string_visual%SPACES_PER_TAB;
    
                                    while(spaces_current++<spaces_left_to_print)
                                            printf(" ");
                                    index_string_visual+=spaces_left_to_print-1;
                            }
                            else
                                    printf("%c",argv[index_args][index_string]);
                    }
    
                    /*Ende des Strings.*/
                    printf("\n\n");
            }
    
            /*Alles lief besser als erwartet.*/
            exit(EXIT_SUCCESS);
    }
    

    Ist nicht das komplette Program, funktioniert aber:

    $ perl -e 'printf("\t 131312 \t13\t\t123 12s3r12j13aj\tddsad")' | xargs -0 ./tab 
    Chunk No. 1
    ===============================================================================
         131312     13      123 12s3r12j13aj    ddsad
    

    Wenn man einen Tabsize von 8 eingibt, funzt es auch:

    $ perl -e 'printf("\t 131312 \t13\t\t123 12s3r12j13aj\tddsad")' | xargs -0 ./tab
    Chunk No. 1
    ===============================================================================
             131312         13              123 12s3r12j13aj        ddsad
    

    War aber jetzt schnell zusammengehackt. Ich übernehme also keine Garantie für Fehler.

    EDIT: Ich soll mich hinlegen, habe die Prüfung für VS-Compiler vergessen. 😕



  • dachschaden schrieb:

    /*Seit mich DirkB darauf aufmerksam gemacht hat, dass %lu nicht immer korrekt
    **ist, aber da %z erst in C99 vorgestellt wurde ... :p*/
    #ifdef __x86_64__
    #define SIZE_T_PRINTF "%lu"
    #else
    #define SIZE_T_PRINTF "%u"
    #endif
    

    Wofür soll das sein?
    Was bewirkt das?
    Warum verzichtest du auf C99?

    Warum erkärst du nicht, was dein Programm anders macht gegenüber der Aufgabenstellung?



  • DirkB schrieb:

    Warum verzichtest du auf C99?

    Diese Diskussion hatten wir bereits.

    DirkB schrieb:

    Warum erkärst du nicht, was dein Programm anders macht gegenüber der Aufgabenstellung?

    Weil der OP hier eine Teillösung bekommt und lernen soll, diese selbstständig in seine Aufgabenstellung einzubinden.



  • dachschaden schrieb:

    DirkB schrieb:

    Warum verzichtest du auf C99?

    Diese Diskussion hatten wir bereits.

    Wenn du damit eine Kompatibilität zu alten C-Compilern von Microsoft haben willst, dann funktioniert das so nicht.

    __x86_64__ ist bei Visual-Studio nicht definiert.
    long ist auch auf Windows bei 64-Bit-Programmen "nur" 32-Bit groß.
    size_t ist aber auf Windows bei 64-Bit-Programmen durchaus 64-Bit groß.

    Bei anderen Compilern als GCC bekommst du also %u. Und das ist aber auch nicht immer richtig.



  • DirkB schrieb:

    __x86_64__ ist bei Visual-Studio nicht definiert.

    Hast recht, habe noch die Prüfung auf _M_X64 eingefügt und %I64u verwendet.

    DirkB schrieb:

    long ist auch auf Windows bei 64-Bit-Programmen "nur" 32-Bit groß.
    size_t ist aber auf Windows bei 64-Bit-Programmen durchaus 64-Bit groß.

    Das weiß ich. Deswegen verwende ich auch nur size_t.



  • dachschaden schrieb:

    DirkB schrieb:

    __x86_64__ ist bei Visual-Studio nicht definiert.

    Hast recht, habe noch die Prüfung auf _M_X64 eingefügt.

    Dann ist das immer noch falsch.

    dachschaden schrieb:

    DirkB schrieb:

    long ist auch auf Windows bei 64-Bit-Programmen "nur" 32-Bit groß.
    size_t ist aber auf Windows bei 64-Bit-Programmen durchaus 64-Bit groß.

    Das weiß ich.

    Anscheinend nicht. %lu steht für unsigned long .
    Was hat das mit size_t zu tun, wenn _M_X64 definiert ist?
    Und was hat %u mit size_t in den anderen Fällen zu tun?

    dachschaden schrieb:

    Deswegen verwende ich auch nur size_t.

    Wenn man davon ausgehen kann, dass int ausreicht, dann nimmt man int ²
    Und in deinem Programm reicht int aus.



  • DirkB schrieb:

    Dann ist das immer noch falsch. [...] %lu steht für unsigned long .

    Schau dir den letzten EDIT an.


  • Mod

    size_t s;
    printf("%llu", (unsigned long long)s);
    

    ?



  • @SeppJ: Ist long long nicht wieder in C99 eingeführt worden?


  • Mod

    dachschaden schrieb:

    @SeppJ: Ist long long nicht wieder in C99 eingeführt worden?

    Dann nimmste eben unsigned long. Die Fälle, in denen selbst das nicht mehr funktioniert sind weitaus konstruierter als die Fälle, in denen deine jetzige Lösung nicht funktioniert.



  • Auf jeder Windows-Maschine kann dir das auf die Füße fallen. Weil long auf Windows 64-Bit 32 Bit groß ist, aber size_t 64 Bit. Und nicht nur bei printf , sondern auch bei sprintf , snprintf ... hat DirkB doch schon geschrieben. Wenn ich mir Objekten arbeite, die >4 GB groß sind, bekomme ich Müll.
    So ein Problem hatte ich schon mal, und es überhaupt zu finden hat mich 10 Stunden meines Lebens gekostet. Da riskiere ich lieber eine Warnung vom Compiler und eine nachträgliche Korrektur der Definitionen.


Anmelden zum Antworten