【问题标题】:String Padding in CC中的字符串填充
【发布时间】:2010-09-21 13:37:06
【问题描述】:

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

它有效,但有一些奇怪的副作用......其他一些变量会改变。我该如何解决这个问题?

【问题讨论】:

    标签: c string padding


    【解决方案1】:
    #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);
    }
    

    【讨论】:

      【解决方案2】:
      #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
      

      【讨论】:

        【解决方案3】:
        #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;
        }
        

        【讨论】:

        • 别忘了释放 str1
        【解决方案4】:

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

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

        会输出

        |Hello     |
        

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

        Printf 样式格式可用于多种语言,并且在网络上有大量参考资料。这是one of many pages 解释格式化标志。像往常一样,WikiPedia's printf page 也有帮助(主要是关于 printf 传播范围的历史课程)。

        【讨论】:

        • 如果你想让字符串被除空格之外的另一个字符填充怎么办?有没有办法用 C 的 printf 做到这一点?
        • 看起来不可能。 (做了一些谷歌搜索。另外,printf 的手册页似乎没有任何关于这些功能的迹象。)
        • @victor - cplusplus.com/reference/clibrary/cstdio/printf - 参见“标志”部分和“宽度”部分。
        • @tom - 是的,“结果用空格填充”。所以,这似乎是不可能的。如前所述,手册页中提供了相同的信息。此外,即使printf 的行为即使不相同,也应该大体相同,但这个 C,而不是 C++。
        • @Victor。抱歉,我以为您是在回答我的回答,而不是彼得的后续问题。是的,您只能选择用 0 或 ' ' 填充。
        【解决方案5】:

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

        诀窍是对 %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”之前或之后,这取决于对左或右填充的需要。

        [####Monkey] &lt;-- Left padded, "%*.*s%s"
        [Monkey####] &lt;-- Right padded, "%s%*.*s"

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

        【讨论】:

        【解决方案6】:

        在这个线程中形成原始问题的函数中肯定有一个错误,我没有看到任何人提到它,它正在将额外的字符连接到已作为传递的字符串文字的末尾范围。这将产生不可预知的结果。在函数的示例调用中,字符串文字“Hello”将被硬编码到程序中,因此可能连接到它的末尾会危险地覆盖代码。如果你想返回一个比原来大的字符串,那么你需要确保你动态分配它,然后在完成后在调用代码中删除它。

        【讨论】:

          【解决方案7】:

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

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

          谢谢!

          【讨论】:

            【解决方案8】:

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

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

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

            【讨论】:

            • 您仍在传递字符串文字...:P
            • 你复制的太多了。 Hello 是 char[6] 类型,但您尝试从中复制 1024 个字节。那只能失败。将其更改为读取 sizeof "Hello" 而不是第二个 sizeof(buffer)
            • strncpy(buffer, "Hello", sizeof(buffer));已经用 '\0' 填充了整个缓冲区,所以你的 memset() 是多余的。
            • @litb, strncpy:如果在复制 num 个字符之前找到源 C 字符串的结尾(由空字符表示),则用零填充目标,直到总共 num字符已写入其中。
            • @Chris,缓冲区后的 memset 是一种习惯。我会把它留在里面。
            【解决方案9】:

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

            【讨论】:

              【解决方案10】:

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

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

              请注意,我为 hello 字符串分配了 11 个字节来说明末尾的空终止符。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多