Help! I need to copy a char array initialized as a string from one array to another, using a function containing one line of code. Here is the code:

#include <iostream>
using namespace std;
void cpystr(char *instr, char *outstr);
void cpystr(char *instr, char *outstr)
{
//Insert line of code here
}
int main()
{
char in[]={'d', 'f', 'g', '\0'};
char out[4];
 
cpystr(in, out);
cout << "in: " << in << endl;
cout << "out: " << out << endl;
 
return 0;
}
 
Thanks!

Dani AI

Generated

The short pointer-expression solution that found is a classic C idiom, and the thread hits the main tradeoffs: very concise but easy to misread () and potentially surprising unless you know pointer/operator precedence (). A few practical notes and clearer alternatives that keep the operation to one line while avoiding the gotchas.

If you can use C++ objects, prefer std::string — it removes manual size bookkeeping and is the clearest single-line copy:

// preferred in modern C++
#include <string>

std::string out = in;

If you must work with C-style buffers but want a readable one-liner that also copies the terminating NUL, use the standard algorithms instead of cryptic loop expressions:

#include <algorithm>
#include <cstring>

void cpystr(const char* src, char* dst) {
    std::copy(src, src + std::strlen(src) + 1, dst);
}

Practical cautions: always ensure the destination has room for strlen(src) + 1 bytes; copying overlapping buffers is undefined—use memmove-like routines if overlap is possible; mark the source const to express intent; and add a short comment if you ever use compact pointer tricks so future readers (or lint tools) aren’t misled. For portability, note that some systems provide safer helper functions (for example strlcpy)—use them where available. Finally, readability matters: the cute one-liners are fine for short, well-tested code, but prefer clearer alternatives in shared or safety-critical code.

Recommended Answers

All 9 Replies

What have you tried? The answer you're looking for is a classic example of a controversial solution, but it's not overly difficult if you know how loops and pointers work.

I actually just figured it out from some other website. It's very simple: while( *outstr++ = *instr++); Thanks very much though!

I wonder if people actually figure things out by themselves anymore. It seems to me that the web stifles creativity to a certain extent.

I can see why that is a controversial solution. it would be very easy to mis-read the intention of that code. The least you could do would be to provide brackets around the identifier and post-increment :)
ie

while( *(outstr++) = *(instr++) )

>it would be very easy to mis-read the intention of that code
That's one reason. Here are a few more:

1) It's too compact to be readable.
2) The performance is deceptive (it's usually slower).
3) The tricks used are obscure.
4) Lint goes nuts (abuse of dangerous constructs).
5) The mechanics are too subtle (notably, dealing with '\0').

while( *(outstr++) = *(instr++) );

that ; almost killed me... why do we need that

>>why do we need that
To complete the while statement. Normally putting a semicolon there would be a bug, but not in this case because there is nothing else to do.

>>It's too compact to be readable.
Then the reader doesn't know C language very well, probably a newbe. Looks perfectly ok to me.

>>The performance is deceptive (it's usually slower).
slower than what? possibly strcpy() is faster, depending on how the compiler optimized it.

>>The tricks used are obscure.
What tricks? And how are they obscure.

>>The mechanics are too subtle (notably, dealing with '\0').
Not subtle at all if you realize what that loop is doing.

>>It's too compact to be readable.
>Then the reader doesn't know C language very well, probably a newbe. Looks perfectly ok to me.

>>The tricks used are obscure.
>What tricks? And how are they obscure.

>>The mechanics are too subtle (notably, dealing with '\0').
>Not subtle at all if you realize what that loop is doing.
Okay, let's break it down by difficult concepts. Here's the original code, to save scrolling:

while( *outstr++ = *instr++);

1) You have to know the precedence/associativity of * and ++. This is a notoriously good area to screw up, even for experienced C programmers (to the point where ++ is often banned in complex expressions).

2) You have to know the implicit test made by a loop, and that it correctly checks for the end of a string. Experienced programmers usually have to think about this to get it right. I'm one of them, which is why my style calls for explicit tests except for exact boolean comparisons.

3) You have to know that because the condition is also an assignment, the null character is correctly added to the string without further logic.

4) You have to parse the entire line before realizing that the null body is intended rather than a grievous error.

That's a lot of prerequisite (not to mention intimate) knowledge for understanding such a simple operation.

>slower than what?
Other solutions that vary depending on the compiler and optimization settings. :icon_rolleyes: My wording was poor though, I should have said "The performance is deceptive (it could easily be slower)."

commented: great explanation! +1

>it would be very easy to mis-read the intention of that code
That's one reason. Here are a few more:

1) It's too compact to be readable.
2) The performance is deceptive (it's usually slower).
3) The tricks used are obscure.
4) Lint goes nuts (abuse of dangerous constructs).
5) The mechanics are too subtle (notably, dealing with '\0').

for anyone who doesn't know what lint is{i didn't!} read this.

PS:: although i am not an experienced programmer, for purely aesthetically reasons {plus all the other reasons narue wrote} i never liked this construct...

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.