89

我写了这个应该做 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;
}

它有效,但有一些奇怪的副作用......其他一些变量会发生变化。我怎样才能解决这个问题?

4

10 回答 10

190

知道 printf 为您进行填充可能会有所帮助,使用 %-10s 作为格式字符串将在 10 个字符长的字段中填充输入

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

将输出

|Hello     |

在这种情况下, - 符号表示“左对齐”,10 表示“字段中的十个字符”,s 表示您正在对齐字符串。

Printf 样式格式有多种语言版本,并且在网络上有大量参考资料。这是解释格式化标志的许多页面之一。像往常一样,维基百科的 printf 页面也有帮助(主要是关于 printf 传播范围的历史课程)。

于 2008-11-10T01:50:15.320 回答
46

对于“C”,当需要自定义填充时,可以使用不需要任何 malloc() 或预格式化的 [s]printf 的替代(更复杂)使用。

诀窍是对 %s 使用 '*' 长度说明符(最小值和最大值),再加上一个用您的填充字符填充到最大潜在长度的字符串。

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 

"%*.*s" 可以放在 "%s" 之前或之后,这取决于对 LEFT 或 RIGHT 填充的需要。

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

我发现 PHP printf (这里) 确实支持在 %s 格式中使用单引号 (') 后跟自定义填充字符来提供自定义填充字符的能力。
printf("[%'#10s]\n", $s); // use the custom padding character '#'
产生:
[####monkey]

于 2012-03-16T16:34:38.640 回答
4
#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;
}

输出:

$ gcc -Wall -ansi -pedantic padding.c
$ ./a.out 
###############Hello
于 2018-03-08T00:37:21.107 回答
2

您必须确保输入字符串有足够的空间来容纳所有填充字符。试试这个:

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

请注意,我为hello字符串分配了 11 个字节以说明最后的空终止符。

于 2008-11-10T01:25:13.670 回答
1

您传递“Hello”的参数位于常量数据区。除非您为 char * 字符串分配了足够的内存,否则它会溢出到其他变量。

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

编辑:从堆栈更正为常量数据区域。

于 2008-11-10T01:25:04.497 回答
1

哦,好吧,有道理。所以我这样做了:

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

谢谢!

于 2008-11-10T01:37:17.250 回答
1
#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;
}
于 2016-08-01T11:32:48.463 回答
0

该功能本身对我来说看起来不错。问题可能是您没有为字符串分配足够的空间来填充那么多字符。您可以在将来通过将size_of_string参数传递给函数来避免此问题,并确保在长度即将大于大小时不填充字符串。

于 2008-11-10T01:25:27.710 回答
0

在这个线程中形成原始问题的函数中绝对错误的一件事是,它正在将额外的字符连接到作为参数传入的字符串文字的末尾。这将产生不可预知的结果。在函数的示例调用中,字符串文字“Hello”将被硬编码到程序中,因此可能连接到它的末尾会危险地覆盖代码。如果您想返回一个大于原始字符串的字符串,那么您需要确保动态分配它,然后在完成后在调用代码中删除它。

于 2015-01-21T15:02:32.843 回答
0
#include<stdio.h>
#include <string.h>


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);
}
于 2018-08-27T16:17:43.623 回答