printf Rahmen erstellen



  • rufrider schrieb:

    Leider bin ich total überfragt wie ich das nur mit printf machen soll. Mit einer Schleife würde ich es hin bekommen.

    Wo steht denn, dass Du printf nicht in einer Schleife ausführen darfst?



  • @DirkB
    Danke für die schnelle Antwort und Hilfe.

    meine Code erweiterung:

    printf("\n+%*.*s+", rahmen, rahmen, "------------------------------------");
        printf("\n|%*.*s|", rahmen, rahmen, "                                    ");
        printf("\n|%*.*s|", rahmen, rahmen, "                                    ");
        printf("\n|%*.*s|", rahmen, rahmen, "                                    ");
        printf("\n+%*.*s+", rahmen, rahmen, "------------------------------------");
    

    @Belli

    Der Prof hat das gesagt, ohne Kontrollstrukturen.

    mfg



  • Die Strings kannst du ja noch mit malloc und memset machen, dann hast du (fast) keine Längenbeschränkung 🙂



  • Der Format-String, nach dem du für den Mittelteil des Rahmens (in vertikaler Richtung) suchst, ist "|%*c|" oder etwas in der Art. (Die genaue Funktionsweise nachzuschlagen überlasse ich dir, um den Lerneffekt nicht zu unterwandern).

    Das eigentlich spannende scheint mir aber der obere und untere Teil zu sein, weil man mit printf nur Leerzeichen (oder bei Zahlen Nullen) als Füllelemente benutzen kann. Ist für die Rahmenbreite eine Obergrenze festgelegt? Dann könnte man nämlich einen gaaaaanz langen Buffer voller '-' vorbereiten und an der passenden Stelle einen Nullterminator einfügen, bevor man den Kram in printf wirft.

    @DirkB: Wenn Schleifen und if verboten sind, sollte es mich wundern, wenn memset erlaubt wäre.



  • Danke DirkB,

    memset funktioniert prima.

    mfg



  • rufrider schrieb:

    Danke DirkB,

    memset funktioniert prima.

    mfg

    Hast du auch an die '\0' am Ende gedacht?



  • Habs doch hinbekommen.

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define _MINUS "----------------------------------------------------------------"
    #define _LEER "                                                                "
    
    /*
     * 
     */
    int main(int argc, char** argv) {
    
        int rahmen = 0;
        char leer[80] = "";
        char minus[80] = "";
    
        printf("Wie breit soll Rahmen werden: ");
        scanf("%d", &rahmen);
        printf("\n");
    
        memset(minus,'-',80);
        memset(leer,' ',80);
    
        printf("\n+%*.*s+", rahmen, rahmen, minus);
        printf("\n|%*.*s|", rahmen, rahmen, leer);
        printf("\n|%*.*s|", rahmen, rahmen, leer);
        printf("\n|%*.*s|", rahmen, rahmen, leer);
        printf("\n+%*.*s+", rahmen, rahmen, minus);
        printf("\0");
    
        return (EXIT_SUCCESS);
    }
    

    Hoffe hat alles seine Richtigkeit.

    mfg und danke



  • rufrider schrieb:

    #define _MINUS "----------------------------------------------------------------"
    #define _LEER "                                                                "
    

    Das ist nicht gut. Bezeichner, die mit einem Unterstrich gefolgt von einem Großbuchstaben beginnen oder zwei Unterstriche direkt hintereinander beinhalten, sind für die Implementierung reserviert. Im File-Scope ist zusätzlich noch alles andere reserviert, was mit einem Unterstrich beginnt. Diese Bezeichner darfst du nicht verwenden, bzw. ein Compiler darf deinen Code ablehnen, wenn du es tust. Da du die beiden aber eh nicht benutzt, kannst du sie einfach entfernen.

    Ferner ist

    char leer[80] = "";
        char minus[80] = "";
    
    ...
    
        memset(minus,'-',80);
        memset(leer,' ',80);
    

    insofern unglücklich, als dass minus und leer danach nicht mehr nullterminiert sind. Wenn eine Breite von mehr als 80 angegeben wird, kriegst du so nicht nur einen deformierten Rahmen, sondern undefiniertes Verhalten. Das ist aber mit

    char leer[81] = "";
        char minus[81] = "";
    

    leicht zu beheben.

    Was ich mir gedacht hatte (ohne memset), ist etwa Folgendes:

    #include <stdio.h>
    
    #define TEN(x) x x x x x x x x x x
    
    int main(void) {
      char m1000[] = TEN(TEN(TEN("-"))); /* 1000 Minus-Zeichen */
      unsigned breite;
    
      scanf("%u", &breite);
    
      if(breite >= sizeof(m1000)) return -1;
    
      m1000[breite] = '\0';
    
      printf("+%s+\n", m1000);
      printf("|%*c|\n", breite, ' ');
      printf("|%*c|\n", breite, ' ');
      printf("|%*c|\n", breite, ' ');
      printf("+%s+\n", m1000);
    
      return 0;
    }
    


  • Mal systematisch:

    (1) Du hast 2 Sorten von Strings nötig um den Kasten zu erzeugen
    (2) erstes und letztes Zeichen sind gleich
    (3) zwischen dem ersten und letzten Zeichen sind Füllzeichen

    Eine Funktion zum Zeichnen einer Zeile könnte so aussehen:

    DruckeZeile( ae, fill, size) {
      printf( "\n%c", ae);
      for ( i=0; i<size; i++)
        printf( "%c", fill);
      printf( "%c", ae);
    }
    

    Die Box ergäbe sich dann so:

    DruckeZeile( '+', '-', breite-2);
    DruckeZeile( '|', ' ', breite-2);
    ... // ggfls wiederholen
    DruckeZeile( '+', '-', breite-2);
    


  • Scheppertreiber schrieb:

    DruckeZeile( ae, fill, size) {
      printf( "\n%c", ae);
      for ( i=0; i<size; i++)
        printf( "%c", fill);
      printf( "%c", ae);
    }
    

    Der TO hat doch etwas von keiner Schleife bzw. "ohne Kontrollstrukturen" geschrieben.

    Und printf zur Ausgabe von einem Zeichen zu nehmen, ist auch etwas heftig. Dafür gibt es putchar()


Anmelden zum Antworten