Concat string (not ended ...)

C

collinm

hi

if i need to concat some string, how can i do it?


Generic Code:

char CMD_INIT[]={'\0', '\0', '\0', '\0', '\0', '\1', 'Z', '0', '0',
'\2'};
char CMD_HOLD[]={'\142'};
char CMD_TXT_GREEN[]={'\34','\62'};
char MSG[]={'T','e','s','t'};
char CMD_END[]={'\04'};


i would like to do something

CMD_INIT + CMD_HOLD + CMD_TXT_GREEN + MSG + CMD_END
 
E

Eric Sosman

collinm said:
hi

if i need to concat some string, how can i do it?


Generic Code:

char CMD_INIT[]={'\0', '\0', '\0', '\0', '\0', '\1', 'Z', '0', '0',
'\2'};
char CMD_HOLD[]={'\142'};
char CMD_TXT_GREEN[]={'\34','\62'};
char MSG[]={'T','e','s','t'};
char CMD_END[]={'\04'};


i would like to do something

CMD_INIT + CMD_HOLD + CMD_TXT_GREEN + MSG + CMD_END

Nomenclature: A "string" is an array of characters
containing some number of "payload" characters (perhaps
none) followed by a character with the value zero. Only
the first of the five arrays above qualifies as a "string,"
and that string has zero length. (I'm not saying this
merely to be pedantic, but to warn you against trying to
use any of C's string-manipulating functions to operate
on these arrays. They are not strings, and if you feed
them to functions that expect strings all Hell will break
loose.)

If what you want is one array containing all the
characters from the five given arrays, you can do

#include <string.h> /* Yes, I know. Trust me. */

char ALL[sizeof CMD_INIT + sizeof CMD_HOLD
+ sizeof CMD_TXT_GREEN + sizeof MSG
+ sizeof CMD_END];
char *p = ALL;
memcpy (p, CMD_INIT, sizeof CMD_INIT);
p += sizeof CMD_INIT;
memcpy (p, CMD_HOLD, sizeof CMD_HOLD);
p += sizeof CMD_HOLD;
memcpy (p, CMD_TXT_GREEN, sizeof CMD_TXT_GREEN);
p += sizeof CMD_TXT_GREEN;
memcpy (p, MSG, sizeof MSG);
p += sizeof MSG;
memcpy (p, CMD_END, sizeof CMD_END);
p += sizeof CMD_END; /* optional */

(The pointer `p' is just a convenience and could be dispensed
with at the cost of more typing.)

If that's not what you want, you'll need to explain
further.
 
C

collinm

Eric Sosman wrote:



#include said:
char ALL[sizeof CMD_INIT + sizeof CMD_HOLD
+ sizeof CMD_TXT_GREEN + sizeof MSG
+ sizeof CMD_END];
char *p = ALL;
memcpy (p, CMD_INIT, sizeof CMD_INIT);
p += sizeof CMD_INIT;
memcpy (p, CMD_HOLD, sizeof CMD_HOLD);
p += sizeof CMD_HOLD;
memcpy (p, CMD_TXT_GREEN, sizeof CMD_TXT_GREEN);
p += sizeof CMD_TXT_GREEN;
memcpy (p, MSG, sizeof MSG);
p += sizeof MSG;
memcpy (p, CMD_END, sizeof CMD_END);
p += sizeof CMD_END; /* optional */

i need to add a character, this is my code:

void analyzeFilename(char *filename, int size, char *led_line)
//void analyzeFilename()
{
#ifdef DEBUG
printf("analyzeFilename\n");
#endif

printf("led_line: %s\n",led_line);

char CMD_INIT[]={'\0', '\0', '\0', '\0', '\0', '\1', 'Z', '0', '0',
'\2'};
char CMD_TEXT_FILE_TYPE[]={'A'};
char CMD_FILE_LABEL=filename[0]; //get the first character of
filename
char CMD_HOLD[]={'\142'};
char CMD_TXT_GREEN[]={'\34','\62'};
char CMD_END[]={'\04'};

char ALL[sizeof(CMD_INIT) + sizeof(CMD_TEXT_FILE_TYPE) +
sizeof(CMD_FILE_LABEL) + sizeof(CMD_HOLD) + sizeof(CMD_TXT_GREEN) +
size + sizeof(CMD_END)];

char *p=ALL;

memcpy(p,CMD_INIT, sizeof(CMD_INIT));
p += sizeof(CMD_INIT);
memcpy (p, CMD_TEXT_FILE_TYPE, sizeof(CMD_TEXT_FILE_TYPE));
p += sizeof(CMD_TEXT_FILE_TYPE);
memcpy (p, CMD_FILE_LABEL, sizeof(CMD_FILE_LABEL)); //problem here
p += sizeof(CMD_FILE_LABEL);
memcpy (p, CMD_HOLD, sizeof(CMD_HOLD));
p += sizeof(CMD_HOLD);
memcpy (p, CMD_TXT_GREEN, sizeof(CMD_TXT_GREEN));
p += sizeof(CMD_TXT_GREEN);
memcpy (p, filename, sizeof(size));
p += sizeof(size);
memcpy (p, CMD_END, sizeof(CMD_END));
p += sizeof(CMD_END);

printf("msg complet: %s", p);

....
....
}

i got a problem with:

memcpy (p, CMD_FILE_LABEL, sizeof(CMD_FILE_LABEL));

the message here:

warning: passing arg 2 of `memcpy' makes pointer from integer without a
cast

i don't know why i get this error and how to solve it
 
E

Eric Sosman

collinm said:
[...]
char CMD_FILE_LABEL=filename[0]; //get the first character of
filename
[...]
i got a problem with:

memcpy (p, CMD_FILE_LABEL, sizeof(CMD_FILE_LABEL));

the message here:

warning: passing arg 2 of `memcpy' makes pointer from integer without a
cast

i don't know why i get this error and how to solve it

This is Question 8.1 in the comp.lang.c Frequently
Asked Questions (FAQ) list

http://www.eskimo.com/~scs/C-faq/top.html

.... and a review of Section 6 would also be a good idea.
 
C

collinm

ok no error at compile time...
memcpy (p, CMD_FILE_LABEL, sizeof(CMD_FILE_LABEL));

convert to

memcpy (p, &CMD_FILE_LABEL, sizeof(CMD_FILE_LABEL));

compile without error

but when i display p, i get bullshit...

Code:
printf("msg complet: %s\n", p);

give

msg complet: ÿôÿóècÿôÈ
 
K

Keith Thompson

collinm said:
ok no error at compile time...
memcpy (p, CMD_FILE_LABEL, sizeof(CMD_FILE_LABEL));

convert to

memcpy (p, &CMD_FILE_LABEL, sizeof(CMD_FILE_LABEL));

compile without error

but when i display p, i get bullshit...

Code:
printf("msg complet: %s\n", p);

give

msg complet: ÿôÿóècÿôÈ

Your definition of CMD_FILE_LABEL was

char CMD_FILE_LABEL=filename[0];

(Incidentally, using all-caps for variable names is bad style;
all-caps is more commonly used for macros.)

So CMD_FILE_LABEL is a *copy* of filename[0], and you can't expect it
to be the start of a valid string.

What you want is the address of filename[0], not a copy of it.

Incidentally, your attempted solution uses sizeof() on fixed-size
arrays of characters. This isn't going to be helpful if you want to
use arrays whose size isn't determined at compilation time. If that's
all you're trying to do, that's fine, but if you need a more general
solution you'll probably need to store the sizes separately.

Also, if you didn't get a compilation error (or at least a warning) on

memcpy (p, CMD_FILE_LABEL, sizeof(CMD_FILE_LABEL));

then you should turn up the warning level on your compiler. For gcc
use something like "gcc -ansi -pedantic -W -Wall"; for other
compilers, consult the documentation.
 
P

Peter Shaggy Haywood

Groovy hepcat collinm was jivin' on 25 Mar 2005 12:33:08 -0800 in
comp.lang.c.
Re: Concat string (not ended ...)'s a cool scene! Dig it!
ok no error at compile time...
memcpy (p, CMD_FILE_LABEL, sizeof(CMD_FILE_LABEL));

convert to

memcpy (p, &CMD_FILE_LABEL, sizeof(CMD_FILE_LABEL));

compile without error

but when i display p, i get bullshit...

Code:
printf("msg complet: %s\n", p);

give=20

msg complet: =FF=F4=FF=F3=E8c=FF=F4=C8

That's because you passed p to printf() instead of ALL. Remember,
you're changing the value of p so that it ends up pointing beyond the
end of your array.
But you can't print the array as a string anyhow. As Eric told you,
a string is a sequence of contiguous characters terminated by a null
character. ALL does not contain a string, as such. The null character
('\0') in the first element of ALL effectively makes a string whose
length is zero characters. Thus, if you simply pass ALL to printf(),
it will print nothing. Instead, you must loop through the elements of
ALL and print them one by one. Of course, if you try to print a null
character it will print nothing. So you might want to skip those, or
print something else in their place. You should also not try to print
arbitrary values such as '\1' and '\2' as they might have some meaning
to the system, and may cause strange behaviour. You could do something
like this perhaps:

#include <ctype.h>
....
printf("msg complet: ");

for(p = ALL; p < sizeof ALL; p++)
{
if(isprint((unsigned char)*p))
putchar(*p);
else
putchar('.');
}
putchar('\n');

--

Dig the even newer still, yet more improved, sig!

http://alphalink.com.au/~phaywood/
"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
 
C

collinm

Peter said:
That's because you passed p to printf() instead of ALL. Remember,
you're changing the value of p so that it ends up pointing beyond the
end of your array.
But you can't print the array as a string anyhow. As Eric told you,
a string is a sequence of contiguous characters terminated by a null
character. ALL does not contain a string, as such. The null character
('\0') in the first element of ALL effectively makes a string whose
length is zero characters. Thus, if you simply pass ALL to printf(),
it will print nothing. Instead, you must loop through the elements of
ALL and print them one by one. Of course, if you try to print a null
character it will print nothing. So you might want to skip those, or
print something else in their place. You should also not try to print
arbitrary values such as '\1' and '\2' as they might have some meaning
to the system, and may cause strange behaviour. You could do something
like this perhaps:

#include <ctype.h>
...
printf("msg complet: ");

for(p = ALL; p < sizeof(ALL); p++)
{
if(isprint((unsigned char)*p))
putchar(*p);
else
putchar('.');
}
putchar('\n');

this code doesn't work, it compile but nothing is displayed

also on the for line, we get this warning: comparison between pointer
and integer...

i changed: p < sizeof(ALL) to p* < sizeof(ALL)

and now we get: ......
 
C

collinm

Keith Thompson wrote:

Your definition of CMD_FILE_LABEL was

char CMD_FILE_LABEL=filename[0];

(Incidentally, using all-caps for variable names is bad style;
all-caps is more commonly used for macros.)

So CMD_FILE_LABEL is a *copy* of filename[0], and you can't expect it
to be the start of a valid string.

What you want is the address of filename[0], not a copy of it.

you mean:

char CMD_FILE_LABEL=&filename[0];
Incidentally, your attempted solution uses sizeof() on fixed-size
arrays of characters. This isn't going to be helpful if you want to
use arrays whose size isn't determined at compilation time. If that's
all you're trying to do, that's fine, but if you need a more general
solution you'll probably need to store the sizes separately.

only ALL is not determined at compilation time
Also, if you didn't get a compilation error (or at least a warning) on

memcpy (p, CMD_FILE_LABEL, sizeof(CMD_FILE_LABEL));

then you should turn up the warning level on your compiler. For gcc
use something like "gcc -ansi -pedantic -W -Wall"; for other
compilers, consult the documentation.

with gcc, i use: CFLAGS= -Os -Wall $(DEFINES)
 
R

Richard Bos

collinm said:
this code doesn't work, it compile but nothing is displayed

If you've declared your objects right it should work.
also on the for line, we get this warning: comparison between pointer
and integer...

Aha.
- How have you declared p?
- How have you declared ALL?
- Are you sure you're writing C, not C++?
i changed: p < sizeof(ALL) to p* < sizeof(ALL)

That doesn't even compile. Guess why.

Richard
 
C

collinm

Richard Bos wrote:
If you've declared your objects right it should work.


Aha.
- How have you declared p?
- How have you declared ALL?
- Are you sure you're writing C, not C++?

char ALL[sizeof(CMD_INIT) + sizeof(CMD_TEXT_FILE_TYPE) +
sizeof(CMD_FILE_LABEL) + sizeof(CMD_HOLD) + sizeof(CMD_TXT_GREEN) +
size + sizeof(CMD_END)];

char *p=ALL;

we don't have c++ compiler, only c...
 
B

Barry Schwarz

Keith Thompson wrote:

Your definition of CMD_FILE_LABEL was

char CMD_FILE_LABEL=filename[0];

(Incidentally, using all-caps for variable names is bad style;
all-caps is more commonly used for macros.)

So CMD_FILE_LABEL is a *copy* of filename[0], and you can't expect it
to be the start of a valid string.

What you want is the address of filename[0], not a copy of it.

you mean:

char CMD_FILE_LABEL=&filename[0];

Syntax error. &filename[0] is a value with type pointer to char.
CMD_FILE_LABLE is a variable with type char. You cannot implicitly
convert between the two. Explicit conversion is allowed,
implementation specific, and in this case almost certainly useless.
On most systems, it would also lead to undefined behavior due to the
converted value being too large to fit in a char.




<<Remove the del for email>>
 
P

Peter Shaggy Haywood

Groovy hepcat collinm was jivin' on 29 Mar 2005 06:17:23 -0800 in
comp.lang.c.
Re: Concat string (not ended ...)'s a cool scene! Dig it!
this code doesn't work, it compile but nothing is displayed

also on the for line, we get this warning: comparison between pointer
and integer...

Whoops! Sorry 'bout that. Wasn't thinking straight. That should be

for(p = ALL; p < (ALL + sizeof ALL); p++)

--

Dig the even newer still, yet more improved, sig!

http://alphalink.com.au/~phaywood/
"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top