3

My question should be rather simple.

I need to give a function a char array of a pre-defined length, but I have a character pointer with variable length, but not longer than the length of my array.

Here the code:

#define SIZE_MAX_PERSON_NAME 50
char person[SIZE_MAX_PERSON_NAME];
char* currentPerson = "John";

now how would I get John into the person array but also setting the rest of the array to 0 (/NUL) ?

so that I would have

BINARY DATA: "John/NUL/NUL/NUL/NUL/NUL/NUL/NUL/NUL/NUL/NUL/NUL/NUL/NUL/NUL....."

in my memory?

sorry if this is overly stupid, but I can't seem to find a solution right now.

10
  • 3
    why don't you use std::string. Commented Aug 4, 2014 at 0:23
  • using old C libraries Commented Aug 4, 2014 at 0:23
  • 2
    Duplicate? use strcpy en.cppreference.com/w/c/string/byte/strcpy Commented Aug 4, 2014 at 0:24
  • 1
    @user2334932 Who told you, that you can't use std::string to pass a const char* parameter elsewhere? Ever heard of std::string::c_str()? Commented Aug 4, 2014 at 0:36
  • 3
    Title says C, poster says C and the code looks like C what gives with the C++ answers? ;) Commented Aug 4, 2014 at 0:38

4 Answers 4

4

First, zero-initialize the fixed-size array :

// Using memset here because I don't know if the whole copy operation can or will be used
// multiple times. We want to be sure that the array is properly zero-initialized if the next
// string to copy is shorter than the previous.
memset(person, '\0', SIZE_MAX_PERSON_NAME);

Then, copy the variable-size string into it :

strcpy(person, currentPerson);

If you are not certain that currentPerson will fit into person :

strncpy(person, currentPerson, SIZE_MAX_PERSON_NAME - 1);

Note that strncpy also zero-initialize the remaining bytes of the array if

strlen(currentPerson) < SIZE_MAX_PERSON_NAME - 1

So you basically have these two options :

memset(person, '\0', SIZE_MAX_PERSON_NAME);
strcpy(person, currentPerson);

Or :

strncpy(person, currentPerson, SIZE_MAX_PERSON_NAME - 1);
person[SIZE_MAX_PERSON_NAME - 1] = '\0';
Sign up to request clarification or add additional context in comments.

8 Comments

Why memset and not just char person[SIZE_MAX_PERSON_NAME] = {'\0'};
@40two That works too but only at initialization time, with memset (or even bzero), there is no such restriction.
the memset (instead of shorter, simpler and safer C++ curly braces initialization) jars with the use of strncopy as a "Safer version.". extreme disharmony here. my ears!
Thank you a lot Chnossos. I know that the standarts of C++ improved. You still sometimes got to deal with old libraries and go back to old standarts. This seems to be the best way to do this. Question Answered
Never use strncpy as a safer strcpy: It is not! Also, sizeof(char) reads "I don't know any C..."
|
2

After this answer was posted the question was retagged from C++ to C.

Use a std::string, like this:

// "using namespace std;" or "using std::string;", then:

string const person = currentPerson;
old_c_function( person.c_str() );

To do things at the C level, which I recommend that you don't, first replace the unnecessary #define with a typed constant:

int const max_person_name_size = 50;

Then zero-initialize your array:

char person[max_person_name_size] = {};

(Note: no silly memset here.) (Also note: this zeroing is only a preventive measure. You wanted it. But it's not really necessary since strcpy will ensure a trailing zero-byte.)

Then just copy in the string:

assert( strlen( current_person ) < max_person_name_size );
strcpy( person, current_person );

But don't do this. Use std::string instead.


Update: doing other things for some minutes made me realize that this answer, as all the others so far, is completely off the mark. The OP states in a comment elsewhere that

I've got a function in the library which only takes a character array. Not a character pointer.

Thus, apparently it's all about a misconception.

The only way this can make sense is if the array is modified by the function, and then std::string::c_str() is not a solution. But a std::string can still be used, if its length is set to something sufficient for the C function. Can go like this:

person.resize( max_person_name_size );
foo( &person[0] );                // Assuming foo modifies the array.
person.resize( strlen( person.c_str() ) );

Comments

0

With literal, you may do:

char person[SIZE_MAX_PERSON_NAME] = "John";

if c-string is not a literal, you have to do the copy with strcpy

strcpy(person, currentPerson);

Comments

0

This is the one and only reason for the existence of strncpy:

Putting a string (up to the 0-terminator or buffer end) into a fixed-length array and zeroing out the rest.
This does not ensure 0-termination, thus avoid it for anything else.

7.24.2.4 The strncpy function

#include <string.h>
char *strncpy(char * restrict s1, const char * restrict s2, size_t n);

2 The strncpy function copies not more than n characters (characters that follow a null character are not copied) from the array pointed to by s2 to the array pointed to by s1.308) If copying takes place between objects that overlap, the behavior is undefined.
3 If the array pointed to by s2 is a string that is shorter than n characters, null characters are appended to the copy in the array pointed to by s1, until n characters in all have been written.
4 The strncpy function returns the value of s1.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.