Zeichenfolgenfüllung in C

Lesezeit: 6 Minuten

Ich habe diese Funktion geschrieben, die StringPadRight(“Hello”, 10, “0”) -> “Hello00000” ausführen soll.

char *StringPadRight(char *string, int padded_len, char *pad) {
    int len = (int) strlen(string);
    if (len >= padded_len) {
        return string;
    }
    int i;
    for (i = 0; i < padded_len - len; i++) {
        strcat(string, pad);
    }
    return string;
}

Es funktioniert, hat aber einige seltsame Nebenwirkungen … einige der anderen Variablen werden geändert. Wie kann ich das beheben?

Benutzeravatar von Tom Leys
Tom Leys

Es könnte hilfreich sein zu wissen, dass printf das Auffüllen für Sie übernimmt, indem %-10s als Formatzeichenfolge verwendet wird, um die Eingabe direkt in einem 10 Zeichen langen Feld aufzufüllen

printf("|%-10s|", "Hello");

wird ausgegeben

|Hello     |

In diesem Fall bedeutet das Symbol – “Linksbündig”, die 10 bedeutet “Zehn Zeichen im Feld” und das s bedeutet, dass Sie eine Zeichenfolge ausrichten.

Die Formatierung im Printf-Stil ist in vielen Sprachen verfügbar und hat zahlreiche Referenzen im Internet. Hier ist eine von vielen Seiten Erklärung der Formatierungsflags. Wie gewöhnlich Druckseite von WikiPedia ist auch hilfreich (hauptsächlich eine Geschichtsstunde darüber, wie weit sich printf verbreitet hat).

  • Was ist, wenn Sie möchten, dass die Zeichenfolge neben Leerzeichen mit einem anderen Zeichen aufgefüllt wird? Gibt es eine Möglichkeit, dies mit printf von C zu tun?

    – Peter Ajtai

    1. Oktober 2011 um 18:01 Uhr

  • Es sieht nicht so aus, als wäre das möglich. (Habe etwas gegoogelt. Auch die Manpage für printf scheint keinen Hinweis auf solche Funktionen zu haben.)

    – Victor Zamanian

    4. Februar 2012 um 12:54 Uhr


  • @tom – ja, “das Ergebnis wird mit Leerzeichen aufgefüllt”. Scheint also nicht möglich zu sein. Wie bereits erwähnt, sind dieselben Informationen in der Manpage verfügbar. Auch wenn printf sollte sich dieser meist gleich wenn nicht identisch verhalten ist C, nicht C++.

    – Victor Zamanian

    8. Februar 2012 um 19:24 Uhr

  • @Sieger. Entschuldigung, ich dachte, Sie würden auf meine Antwort antworten, nicht auf Peters nachfolgende Frage. Ja, Sie können nur wählen, ob Sie mit 0 auffüllen oder mit ‘ ‘, sonst nichts.

    – Tom Leys

    19. Februar 2012 um 21:48 Uhr

  • @TomLeys die -Die Flagge wird immer mit einem Leerzeichen auf der rechten Seite aufgefüllt, richtig?. kann es mit pad 0 auf der rechten Seite

    – Ratatouille

    22. August 2018 um 8:44 Uhr

Benutzeravatar von J Jorgenson
J Jörgenson

Für ‘C’ gibt es eine alternative (komplexere) Verwendung von [s]printf, das kein malloc() oder keine Vorformatierung erfordert, wenn benutzerdefinierte Auffüllung gewünscht wird.

Der Trick besteht darin, ‘*’-Längenbezeichner (Min und Max) für %s zu verwenden, plus eine Zeichenfolge, die mit Ihrem Füllzeichen bis zur maximal möglichen Länge gefüllt ist.

int targetStrLen = 10;           // Target output length  
const char *myString="Monkey";   // String for output 
const char *padding="#####################################################";

int padLen = targetStrLen - strlen(myString); // Calc Padding length
if(padLen < 0) padLen = 0;    // Avoid negative length

printf("[%*.*s%s]", padLen, padLen, padding, myString);  // LEFT Padding 
printf("[%s%*.*s]", myString, padLen, padLen, padding);  // RIGHT Padding 

Das “%*.*s” kann vor ODER nach Ihrem “%s” platziert werden, je nach Wunsch nach LINKER oder RECHTER Auffüllung.

[####Monkey] <-- Left padded, "%*.*s%s"
[Monkey####] <-- Right padded, "%s%*.*s"

Ich habe festgestellt, dass das PHP printf (hier) unterstützt die Möglichkeit, ein benutzerdefiniertes Füllzeichen zu geben, Verwenden Sie das einfache Anführungszeichen (‘), gefolgt von Ihrem benutzerdefinierten Füllzeicheninnerhalb des %s-Formats.
printf("[%'#10s]\n", $s); // use the custom padding character '#'

produziert:
[####monkey]

  • Anscheinend habe ich die gepostete Antwort eines anderen hier dupliziert: Polsterung mit variabler Größe in printf

    – J. Jorgenson

    16. März 2012 um 16:39 Uhr


Benutzeravatar von Izya Budman
Izya Budmann

#include <stdio.h>
#include <string.h>

int main(void) {
    char buf[BUFSIZ] = { 0 };
    char str[] = "Hello";
    char fill="#";
    int width = 20; /* or whatever you need but less than BUFSIZ ;) */

    printf("%s%s\n", (char*)memset(buf, fill, width - strlen(str)), str);

    return 0;
}

Ausgabe:

$ gcc -Wall -ansi -pedantic padding.c
$ ./a.out 
###############Hello

Sie müssen sicherstellen, dass die Eingabezeichenfolge genügend Platz hat, um alle Füllzeichen aufzunehmen. Versuche dies:

char hello[11] = "Hello";
StringPadRight(hello, 10, "0");

Beachten Sie, dass ich 11 Bytes für die zugewiesen habe hello Zeichenfolge, um das Null-Terminator am Ende zu berücksichtigen.

Benutzeravatar von Eugene Yokota
Eugen Yokota

Das von Ihnen übergebene Argument „Hallo“ befindet sich im konstanten Datenbereich. Wenn Sie char * string nicht genügend Speicher zugewiesen haben, überläuft es andere Variablen.

char buffer[1024];
memset(buffer, 0, sizeof(buffer));
strncpy(buffer, "Hello", sizeof(buffer));
StringPadRight(buffer, 10, "0");

Bearbeiten: Korrigiert vom Stack zum konstanten Datenbereich.

  • Sie übergeben immer noch ein Zeichenfolgenliteral … : P

    – Paige Ruten

    10. November 2008 um 1:33 Uhr

  • du kopierst zu viel. Hallo ist vom Typ char[6] , aber Sie versuchen, 1024 Bytes daraus zu kopieren. das kann nur scheitern. Ändern Sie es, um sizeof “Hello” anstelle des zweiten sizeof (buffer) zu lesen

    – Johannes Schaub – litb

    10. November 2008 um 1:52 Uhr

  • strncpy(buffer, “Hallo”, sizeof(buffer)); füllt bereits den gesamten Puffer mit ‘\0’, sodass Ihr memset() überflüssig ist.

    – Chris Jung

    10. November 2008 um 6:24 Uhr

  • @litb, strncpy: Wenn das Ende des Quell-C-Strings (was durch ein Null-Zeichen signalisiert wird) gefunden wird, bevor num Zeichen kopiert wurden, wird das Ziel mit Nullen aufgefüllt, bis insgesamt num Zeichen darin geschrieben wurden.

    – Eugen Yokota

    10. November 2008 um 8:34 Uhr

  • @Chris, Memset nach Puffer ist eine gewöhnliche Sache. Ich lasse es drin.

    – Eugen Yokota

    10. November 2008 um 8:39 Uhr

Ah okay, macht Sinn. Also habe ich das gemacht:

    char foo[10] = "hello";
    char padded[16];
    strcpy(padded, foo);
    printf("%s", StringPadRight(padded, 15, " "));

Vielen Dank!

  • Sie übergeben immer noch ein Zeichenfolgenliteral … : P

    – Paige Ruten

    10. November 2008 um 1:33 Uhr

  • du kopierst zu viel. Hallo ist vom Typ char[6] , aber Sie versuchen, 1024 Bytes daraus zu kopieren. das kann nur scheitern. Ändern Sie es, um sizeof “Hello” anstelle des zweiten sizeof (buffer) zu lesen

    – Johannes Schaub – litb

    10. November 2008 um 1:52 Uhr

  • strncpy(buffer, “Hallo”, sizeof(buffer)); füllt bereits den gesamten Puffer mit ‘\0’, sodass Ihr memset() überflüssig ist.

    – Chris Jung

    10. November 2008 um 6:24 Uhr

  • @litb, strncpy: Wenn das Ende des Quell-C-Strings (was durch ein Null-Zeichen signalisiert wird) gefunden wird, bevor num Zeichen kopiert wurden, wird das Ziel mit Nullen aufgefüllt, bis insgesamt num Zeichen darin geschrieben wurden.

    – Eugen Yokota

    10. November 2008 um 8:34 Uhr

  • @Chris, Memset nach Puffer ist eine gewöhnliche Sache. Ich lasse es drin.

    – Eugen Yokota

    10. November 2008 um 8:39 Uhr

#include <iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

using namespace std;

int main() {
    // your code goes here
    int pi_length=11; //Total length 
    char *str1;
    const char *padding="0000000000000000000000000000000000000000";
    const char *myString="Monkey";

    int padLen = pi_length - strlen(myString); //length of padding to apply

    if(padLen < 0) padLen = 0;   

    str1= (char *)malloc(100*sizeof(char));

    sprintf(str1,"%*.*s%s", padLen, padLen, padding, myString);

    printf("%s --> %d \n",str1,strlen(str1));

    return 0;
}

  • Vergessen Sie nicht, str1 freizugeben

    – Pierre-Louis Sauvage

    12. März 2017 um 15:07 Uhr

1420460cookie-checkZeichenfolgenfüllung in C

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy