1

Let's say I have a struct called test:

struct  test
{
    char name[16];

} test;

I want to read the user's input and put it in the name field. Let's say the user has typed in "hello" as the input. My code is like this:

struct test test1;

strcpy(test1.name, user_input);

Now the name has 5 characters in it ("hello"), but I want it to have its 16 characters: 5 for the actual input, and the rest white spaces. How can I achieve that?

nhahtdh
  • 55,989
  • 15
  • 126
  • 162
Arian Motamedi
  • 7,123
  • 10
  • 42
  • 82
  • 1
    Is there any reason you want to do this in the first place? And you should not have the rest to be white space (the last byte should be 0), otherwise, you might have problem when using string functions. – nhahtdh Oct 14 '12 at 05:45
  • Yes. I'm writing a program that works pretty much like the "ar" command in linux, and it's necessary to have fixed-length fields. – Arian Motamedi Oct 14 '12 at 05:48
  • Just let the rest of the bytes be 0. – nhahtdh Oct 14 '12 at 05:49
  • Just make sure the struct is initialize to 0 (possibly `memset`, or http://stackoverflow.com/questions/6891720/initialize-reset-struct-to-zero-null), then you can store the string into the `name` field. – nhahtdh Oct 14 '12 at 05:56

3 Answers3

5

sprintf() can do it:

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))

output:

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

or

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

output

2 padding chars added: [Hollywood Dan  ]
0 padding chars added: [The Honorable H]
15 padding chars added: [               ]
Scooter
  • 6,802
  • 8
  • 41
  • 64
2

I suppose the obvious would be something like this:

memset(test1.name, ' ', 16);

size_t len = min(16, strlen(user_input));

memcpy(test1.name, user_input, len);

If you want to zero-fill any excess space, that's quite a bit simpler:

strncpy(test1.name, user_input, 16);

[The first time I've seen/heard somebody ask a question for which strncpy could actually be a correct answer.]

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • I'd rather not fill the `name` field with space. Zero-fill is safer in terms of expectation when dealing with a string. – nhahtdh Oct 14 '12 at 05:55
0
// 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;
}
Marichyasana
  • 2,966
  • 1
  • 19
  • 20