Imbottitura a stringa in C

Ho scritto questa funzione che dovrebbe eseguire StringPadRight (“Hello”, 10, “0”) -> “Hello00000”.

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; } 

Funziona ma ha alcuni effetti collaterali strani … alcune delle altre variabili vengono modificate. Come posso risolvere questo?

Potrebbe essere utile sapere che printf fa il padding per te, usando% -10s dato che la stringa di formato riempirà l’input direttamente in un campo di 10 caratteri

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

uscirà

 |Hello | 

In questo caso il simbolo – significa “Allineamento a sinistra”, il 10 significa “Dieci caratteri nel campo” e il simbolo s significa che stai allineando una stringa.

La formattazione dello stile di Printf è disponibile in molte lingue e ha molti riferimenti sul web. Ecco una delle molte pagine che spiegano i flag di formattazione. Come al solito, anche la pagina di stampa di WikiPedia è di aiuto (principalmente una lezione di storia di come ampiamente si è diffusa la stampa ).

Per “C” esiste un uso alternativo (più complesso) di [s] printf che non richiede alcun malloc () o pre-formattazione, quando si desidera un padding personalizzato.

Il trucco è usare gli identificatori di lunghezza ‘*’ (min e max) per% s, più una stringa riempita con il carattere di riempimento alla massima lunghezza potenziale.

 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 

Il "% *. * S" può essere posizionato prima di O dopo il tuo "% s", a seconda del desiderio per il padding sinistro o destro.

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

Ho scoperto che PHP printf ( qui ) supporta la capacità di fornire un carattere di riempimento personalizzato, utilizzando la virgoletta singola (') seguita dal carattere di riempimento personalizzato , all'interno del formato% s.
printf("[%'#10s]\n", $s); // use the custom padding character '#'
produce:
[####monkey]

È necessario assicurarsi che la stringa di input abbia spazio sufficiente per contenere tutti i caratteri di riempimento. Prova questo:

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

Notare che ho allocato 11 byte per la stringa hello per tenere conto del terminatore null alla fine.

L’argomento che hai passato “Ciao” si trova nell’area dei dati costanti. A meno che tu non abbia allocato abbastanza memoria alla stringa char *, è sovrascritta su altre variabili.

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

Modifica: corretto dallo stack all’area dati costante.

Oh ok, ha senso. Così ho fatto questo:

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

Grazie!

 #include  #include #include #include 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; } 

La funzione stessa mi sembra soddisfacente. Il problema potrebbe essere che non stai allocando abbastanza spazio affinché la tua stringa possa contenere su di essa tanti caratteri. In futuro potresti evitare questo problema passando un argomento size_of_string alla funzione e assicurati di non riempire la stringa quando la lunghezza sta per essere maggiore della dimensione.

Una cosa che è decisamente sbagliata nella funzione che forma la domanda originale in questo thread, che non ho mai visto menzionare, è che concatena caratteri extra alla fine della stringa letterale che è stata passata come parametro. Ciò darà risultati imprevedibili. Nell’esempio call della funzione, la stringa letterale “Hello” sarà codificata nel programma, quindi presumibilmente concatenare alla fine di esso scriverà pericolosamente sul codice. Se si desidera restituire una stringa che è più grande dell’originale, è necessario assicurarsi di allocarla dynamicmente e quindi eliminarla nel codice chiamante una volta terminato.

 #include  #include  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; } 

Produzione:

 $ gcc -Wall -ansi -pedantic padding.c $ ./a.out ###############Hello 
 #include #include  void padLeft(int length, char pad, char* inStr,char* outStr) { int minLength = length * sizeof(char); if (minLength < sizeof(outStr)) { return; } int padLen = length - strlen(inStr); padLen = padLen < 0 ? 0 : padLen; memset(outStr, 0, sizeof(outStr)); memset(outStr, pad,padLen); memcpy(outStr+padLen, inStr, minLength - padLen); }