leon22
leon22

Reputation: 5669

C++ copy const char* to char*

I have a function

ClassA::FuncA(const char *filePath)

and want to copy this const char string* to a char*!

My solution:

char *argv[2];
int length = strlen(filePath);
argv[1] = new char(length +1);
strncpy(argv[1], filePath, length); 

after this I have in argv[1] the desired chars but also some other undefined chars!

filePath:

"C:\Users\userA\Parameter.xmlþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþKŸQyá•"

Whats wrong here? The length with strlen is OK!

Upvotes: 3

Views: 20743

Answers (4)

James Kanze
James Kanze

Reputation: 154047

The problem is that you're using strncpy, rather than strcpy. And the way you're using it, it doesn't copy the terminating \0.

In practice, because strncpy may leave a string without a \0 terminator, it's best to avoid it. In your case, strcpy alone is fine, since you've just allocated a sufficiently large buffer. In the more general case, you may have to use strlen, to ensure that the string you have fits in the target buffer (without ever forgetting to add 1 to the results, for the \0).

If the situation occurs a lot, you might want to write your own version of strncpy, which works (i.e. guarantees a terminating \0, and doesn't copy or write more characters than necessary). Something like:

void
stringCopy( char* dest, int maxLength, char const* source )
{
    assert( maxLength > 0 );
    char* end = dest + maxLength - 1;
    while ( dest != end && *source != '\0' ) {
        *dest = *source;
        ++ dest;
        ++ source;
    }
    *dest = '\0';
}

(This function actually exists, under the name strcpy_s in C 2011, but it isn't widely implemented; Microsoft has it, but I've not seen it elsewhere.)

Upvotes: 1

Bo.
Bo.

Reputation: 2541

You have two problems in your code:

  • You need to add 1 to length after copying in order to copy null character (as strlen returns only number of chars without null character; see more here). So change code to:

    strncpy(argv[1], filePath, length + 1);

  • You need fix how your array is being initialized as you are initializing only one character (and we assume you want full string to be copied). So:

    argv[1] = new char[length + 1]();


Notes:

  • Please when you post also post the code that was used to print out data as problems such as these in a lot of cases depend on what you call to print out data.
  • And at the end you might consider using just an array of fixed size that is initialized to maximum path. For max path size in windows checkout following post

Upvotes: 1

mouviciel
mouviciel

Reputation: 67879

strncpy() copies not more than length characters. In doing so, terminating \0 was not copied.

Upvotes: 1

Luchian Grigore
Luchian Grigore

Reputation: 258668

Like so:

argv[1] = new char[length +1](); // () to value-initialize the array

Your version:

argv[1] = new char(length +1);

only allocates a single char and value-initializes it to length+1.

Upvotes: 16

Related Questions