• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 390
  • Last Modified:

more elegant way to load characters?

Hey, I'm a little rusty in C.  Is there a more elegant way to load a series of chars of the caller's choice into an outgoing array?  I don't want to use up RAM to allocate a separate char array, nor use string manipulation functions; but I'd prefer to write

outmsg_cmd("ABC");
instead of
outmsg_cmd('A', 'B', 'C');

to get data loaded into the characters 2-4 of my array.  Simply because the former is more readable.

Is there a way to achieve this?  

Thanks.

char out_buf[50];
 
void outmsg_cmd(char a, char b, char c)
{
  out_buf[2] = a;
  out_buf[3] = b;
  out_buf[4] = c;
}
 
void foo()
{
  outmsg_cmd('A', 'B', 'C');
}

Open in new window

0
riceman0
Asked:
riceman0
  • 5
  • 2
1 Solution
 
ZoppoCommented:
Hi riceman0,

IMO you could do it like this:

> void outmsg_cmd( char* pBuf )
> {
>  strncpy( out_buf + 1, pBuf, 3 );
> }

Hope that helps,

ZOPPO
0
 
riceman0Author Commented:

For nuanced reasons (this is an interrupt service routine) I don't want to use string manipulation functions.  

But I guess this would work, wouldn't it:

> void outmsg_cmd( char* pBuf )
> {
  out_buf[2] = *pBuf;
  out_buf[3] = *(pBuf+1);
  out_buf[4] = *(pBuf+2);

> }
0
 
evilrixSenior Software Engineer (Avast)Commented:
Without using string functions, memcpy is your best bet.
http://www.cplusplus.com/reference/clibrary/cstring/memcpy/

Frankly, I'd use strncpy as Zoppo suggests.
#include <cstdio>
 
char out_buf[50];
 
void outmsg_cmd(char const * p)
{
	memcpy(&out_buf[2], p, sizeof(char) * 3);
}
 
void foo()
{
  outmsg_cmd("ABC");
}
 
int main()
{
	foo();
}

Open in new window

0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
evilrixSenior Software Engineer (Avast)Commented:
out_buf[2] = *pBuf;
out_buf[3] = *(pBuf+1);
out_buf[4] = *(pBuf+2);

is identical to

out_buf[2] = pBuf[0];
out_buf[3] = pBuf[1];
out_buf[4] = pBuf[2];

as far as the compiler is concerned since the index operator is just syntactic sugar. To prove this to yourself try the little bit of code below, either look as the value of 'c' in the debugger or output it.

int main()
{
	char const a[] = "ABC";
	size_t x = 1;
 
	char c = x[a]; // c == B
}

Open in new window

0
 
riceman0Author Commented:
Oops, my counterproposal doesn't work:

> void outmsg_cmd( char* pBuf )
> {
  out_buf[2] = *pBuf;
  out_buf[3] = *(pBuf+1);
  out_buf[4] = *(pBuf+2);

> }

If I call

outmsg_cmd("ABC");

I get the error
 function argument #1 of type 'flash unsigned char [4]' is incompatible with required parameter of type 'unsigned char *'
0
 
riceman0Author Commented:
evilrix: I agree strncpy is preferable to memcpy.  Also, yeah I'm not so rusty that I've forgotten those are identical.
0
 
riceman0Author Commented:

Ah, I think the "flash" error is because I'm programming a chip with harvard architecture (i.e., volatile and nonvolatile memory are not compatible), am trying this on a desktop app.
0
 
riceman0Author Commented:
I think the problem is specific to my chip, and using a pointer parameter as first suggested by Zoppo would otherwise be the right way to go.
0

Featured Post

[Webinar On Demand] Database Backup and Recovery

Does your company store data on premises, off site, in the cloud, or a combination of these? If you answered “yes”, you need a data backup recovery plan that fits each and every platform. Watch now as as Percona teaches us how to build agile data backup recovery plan.

  • 5
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now