printf Rahmen erstellen



  • Hi,
    hab ein Problem bei einer Testat-Aufgabe:
    Aufgabe:

    Erstellen Sie ein C-Programm, das einen Rahmen am Bildschirm ausgibt. Der Rahmen soll
    immer 5 Zeilen lang sein. Wie breit er sein soll, soll der Benutzer eingeben.
    Beispiel:
    Wie breit soll Rahmen werden: 5↵
    +-----+
    |     |
    |     |
    |     |
    +-----+
    

    Leider bin ich total überfragt wie ich das nur mit printf machen soll. Mit einer Schleife würde ich es hin bekommen.
    Mein Überlegung war ein Umwandlungsbezeichner mit width aus der variable.
    Nur was für einen Bezeichner muss ich für die Leertaste oder das "-" nehmen, bzw. wie bekommt man den Variablenwert in den Umwandlungsbezeichner.

    Mein bisheriger Code:

    #include <stdio.h>
    #include <stdlib.h>
    
    /*
     * 
     */
    int main(int argc, char** argv) {
    
        int rahmen = 0;
    
        printf("Wie breit soll Rahmen werden: ");
        scanf("%d", &rahmen);
        printf("\n");
    
        printf("\n++");
        printf("\n||", rahmen);
        printf("\n||");
        printf("\n||");
        printf("\n++");
    
        return (EXIT_SUCCESS);
    }
    

    Leider noch nicht soviel 😞 ,hoffe jemand hat ein paar Hilfestellungen für mich. Ich möchte keinen Fertigen Code!!!!!

    mfg rufrider



  • Schau dir mal bei printf bei width und precision die * an.
    Dann nimmst du einen seeeeeeehr langen String mit '-' bzw. ' ' die du damit ausgeben kannst.



  • 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