【问题标题】:Copying strings with white spaces in C在C中复制带有空格的字符串
【发布时间】:2012-10-04 11:34:25
【问题描述】:

假设我有一个名为teststruct

struct  test
{
    char name[16];

} test;

我想读取用户的输入并将其放在name 字段中。假设用户输入了"hello" 作为输入。我的代码是这样的:

struct test test1;

strcpy(test1.name, user_input);

现在名称中有 5 个字符 ("hello"),但我希望它有 16 个字符:5 个用于实际输入,其余为空格。我怎样才能做到这一点?

【问题讨论】:

  • 您有什么理由首先要这样做吗?并且你不应该让其余的为空白(最后一个字节应该是0),否则,你在使用字符串函数时可能会遇到问题。
  • 是的。我正在编写一个与 linux 中的“ar”命令非常相似的程序,并且必须有固定长度的字段。
  • 让其余字节为 0。
  • 只要确保结构初始化为0(可能是memset,或stackoverflow.com/questions/6891720/…),然后你可以将字符串存储到name字段中。

标签: c


【解决方案1】:
// first remember
// that  a character array of length 16 can only hold a string of 15
// chars because it needs the trailing zero
// this program puts in the user input (you should check that it is short enough to fit)
// then puts in the spaces, one at a time, then the terminating zero

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

int main()
{
    char name [16];         // room for 15 chars plus a null terminator
    char word [] = "hello"; // user input

    strcpy(name,word);      // copy user input to name
    int i;
    for (i = strlen(name); i < (sizeof(name)-1); i++) {
        name[i] = ' ';      // pad with blanks
    }
    name[sizeof(name)-1] = 0; // string terminator

    printf("name = \"%s\"\n",name);
    return 0;
}

【讨论】:

    【解决方案2】:

    sprintf() 可以做到:

    sprintf(test1.name,"%-15s","John Doe");
    printf("[%s] length of test1.name: %ld\n",test1.name,strlen(test1.name));
    sprintf(test1.name,"%-*s",(int) sizeof(test1.name) - 1,"Jane Jones");
    printf("[%s] length of test1.name: %ld\n",test1.name,strlen(test1.name))
    

    输出:

    [John Doe       ] length of test1.name: 15
    [Jane Jones     ] length of test1.name: 15
    

    #include <stdio.h>
    #include <string.h>
    
    int copy_with_pad(char *destination,const char *source, int dest_size, char pad_char)
    {
       int pad_ctr = 0;
       if (dest_size < 1 ) return -1;
       int source_length = strlen(source);
       int data_size = dest_size - 1;
       destination[data_size] = '\0';
       int i = 0;
       while (i < data_size)
       {
          if ( i >= source_length )
          {
             destination[i] = pad_char;
             pad_ctr++;
          }
          else
             destination[i] = source[i];
          i++;
       }
       return pad_ctr;
    }
    
    
    int main(void)
    {
       struct test {
          char name[16];
       };
       struct test test1;
       int chars_padded = copy_with_pad(test1.name,"Hollywood Dan",
                                        sizeof(test1.name),' ');
       printf("%d padding chars added: [%s]\n",chars_padded,test1.name);
       chars_padded = copy_with_pad(test1.name,"The Honorable Hollywood Dan Jr.",
                                     sizeof(test1.name),' ');
       printf("%d padding chars added: [%s]\n",chars_padded,test1.name);
       chars_padded = copy_with_pad(test1.name,"",16,' ');
       printf("%d padding chars added: [%s]\n",chars_padded,test1.name);
    }
    

    输出

    2 padding chars added: [Hollywood Dan  ]
    0 padding chars added: [The Honorable H]
    15 padding chars added: [               ]
    

    【讨论】:

    • sprintf() 正是我想要的!
    【解决方案3】:

    我想显而易见的是这样的:

    memset(test1.name, ' ', 16);
    
    size_t len = min(16, strlen(user_input));
    
    memcpy(test1.name, user_input, len);
    

    如果你想对多余的空间进行零填充,那就简单多了:

    strncpy(test1.name, user_input, 16);
    

    [我第一次看到/听到有人问strncpy 可能实际上是正确答案的问题。]

    【讨论】:

    • 我不想用空格填充name 字段。在处理字符串时,零填充在期望方面更安全。
    猜你喜欢
    • 2017-09-06
    • 1970-01-01
    • 1970-01-01
    • 2011-09-11
    • 2017-01-23
    • 1970-01-01
    • 2011-04-30
    • 2020-08-30
    • 1970-01-01
    相关资源
    最近更新 更多