By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
464,342 Members | 1,251 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 464,342 IT Pros & Developers. It's quick & easy.

Having problem on printing a string using printf?

P: n/a
jt
Here is my code below, it doesn't printf. But I step it thru using the for
statement and use putchar to the display, its there...

How can I get it to use printf? If the problem is needing a null at the end
and how can I do this?
I tried pos='\0' after my last memcpy and that doesn't work either.
================================================== ===========

void ERR(char * err_msg){

char tmp[1024],*pos;
unsigned int len,i,s;

memset(tmp,'\0',1024);

len=strlen(err_msg);
s = ntohl(len);

pos=tmp;
memcpy(pos,&s,sizeof(s));
pos+=sizeof(s);
memcpy(pos,err_msg,len);

printf("%s\n",tmp);

}

Nov 14 '05 #1
Share this Question
Share on Google+
11 Replies

P: n/a
jt wrote:
Here is my code below, it doesn't printf. But I step it thru using the for
statement and use putchar to the display, its there...

How can I get it to use printf? If the problem is needing a null at the end
and how can I do this?
I tried pos='\0' after my last memcpy and that doesn't work either.
================================================== ===========

void ERR(char * err_msg){

char tmp[1024],*pos;
unsigned int len,i,s;

memset(tmp,'\0',1024); probably a waste. YMMV.
len=strlen(err_msg);
s = ntohl(len);
ntohl is not a standard C function (which makes it off-topic here); it
isn't even a standard POSIX function (which makes it off-topic in even
more places). Where it exists, its sole function is usually to change
the byte order of a network *long* to a host *long*. For some reason
you have chose to store the result of this conversion into an int-sized
object. This cannot be a good thing. If your use of this non-standard
function has anything to do with your problem, ask in a newsgroup -- not
comp.lang.c -- where it is topical.
pos=tmp;
memcpy(pos,&s,sizeof(s));
pos+=sizeof(s);
memcpy(pos,err_msg,len); Why not strcpy? Oh, well...
printf("%s\n",tmp);
It is up in the air what the effect of a byte-reordered long stored in a
int and then placed into the first bytes of a string might be. If any
of those bytes are 0s, you're dead. Try seeing what
printf("%s\n", pos);
does. pos should point to the beginning of the string.
}

Nov 14 '05 #2

P: n/a
jt wrote:
Here is my code below, it doesn't printf. But I step it thru using the for
statement and use putchar to the display, its there...

How can I get it to use printf? If the problem is needing a null at the end
and how can I do this?
I tried pos='\0' after my last memcpy and that doesn't work either.
================================================== ===========

void ERR(char * err_msg){

char tmp[1024],*pos;
unsigned int len,i,s;
len is better declared as size_t as it's used to store the return value
of strlen(), which is size_t.
memset(tmp,'\0',1024);
Alternatively, you could declare tmp:

char tmp[1024] = {0};
len=strlen(err_msg);
s = ntohl(len);
pos=tmp;
memcpy(pos,&s,sizeof(s));
pos+=sizeof(s);
memcpy(pos,err_msg,len);
You should check the value of len. It shouldn't exceed sizeof tmp -
sizeof s.
Above you said that you tried to solve this by putting pos = '\0'. That
would cause the memcpy() to be useless if you just want to printf() the
string stored in tmp later.
printf("%s\n",tmp);


In order for this to behave well, you should ensure that tmp[sizeof tmp
- 1] == '\0'.

--
ishs

Nov 14 '05 #3

P: n/a
Martin Ambuhl wrote (and now claifies):
jt wrote: ....
void ERR(char * err_msg){

char tmp[1024],*pos;
unsigned int len,i,s;
memset(tmp,'\0',1024);
len=strlen(err_msg);
s = ntohl(len);
pos=tmp;
memcpy(pos,&s,sizeof(s));
pos+=sizeof(s);
memcpy(pos,err_msg,len);
printf("%s\n",tmp);

It is up in the air what the effect of a byte-reordered long stored in a
int and then placed into the first bytes of a string might be. If any
of those bytes are 0s, you're dead. Try seeing what
printf("%s\n", pos);
does. pos should point to the beginning of the string.


[Clarification]
Unless err_msg is very very long (long enough to put an non-zero into
*every* byte of len and so of s), you are *sure* to have a zero byte
withing the first sizeof s bytes of tmp. This guarantees that your
string ends before the stored err_msg and that you see nothing but
whatever gibberish the leading non-zero bytes of s might be represented
as. But err_msg is stored starting at pos, which is *after* any zero
bytes in s, so puts(pos) rather than puts(tmp) if you want to see the
err_msg.
}

Nov 14 '05 #4

P: n/a
jt
None of your replies worked unfortunately.

I'm still confused why I can get this working...

Thanks for trying to help.
jt
"jt" <jt****@hotmail.com> wrote in message
news:om********************@tornado.tampabay.rr.co m...
Here is my code below, it doesn't printf. But I step it thru using the for
statement and use putchar to the display, its there...

How can I get it to use printf? If the problem is needing a null at the
end and how can I do this?
I tried pos='\0' after my last memcpy and that doesn't work either.
================================================== ===========

void ERR(char * err_msg){

char tmp[1024],*pos;
unsigned int len,i,s;

memset(tmp,'\0',1024);

len=strlen(err_msg);
s = ntohl(len);

pos=tmp;
memcpy(pos,&s,sizeof(s));
pos+=sizeof(s);
memcpy(pos,err_msg,len);

printf("%s\n",tmp);

}

Nov 14 '05 #5

P: n/a
jt wrote:
None of your replies worked unfortunately.

I'm still confused why I can get this working...


Probably give an example input and the expected output...?

--
ade ishs

Nov 14 '05 #6

P: n/a
jt wrote:
None of your replies worked unfortunately.

I'm still confused why I can get this working...


A string is an array of characters with a zero-valued
character after its "payload" portion. Functions that work
with strings operate only on the portion up to (and sometimes
including) the zero byte, and pay no attention to anything
that comes after it. In particular, the "%s" specifier to
printf() will output all the characters that precede the
zero, and nothing else.

Your code fills the first few bytes of a character array
with a number in binary form, and then appends a string after
this numeric prefix. It then hands the whole thing to "%s",
which will print out successive characters from the array
until it finds a zero byte. There is almost certainly a zero
byte in the prefix, so "%s" stops generating output before it
ever gets to the appended string; as far as "%s" is concerned,
the string ended somewhere in the prefix. (It's likely that
the very first byte of the prefix is zero, so "%s" decides that
the string is empty and prints no characters at all.)

Even if "%s" did produce some output, the output would
most likely be garbage: the binary prefix probably doesn't
make any sense when viewed as characters.

What's the fix? Well, what are you trying to do? What is
the purpose of all this prefixing and printing?

--
Eric Sosman
es*****@acm-dot-org.invalid
Nov 14 '05 #7

P: n/a
jt wrote:
None of your replies worked unfortunately.

I'm still confused why I can get this working...

Thanks for trying to help.
jt
"jt" <jt****@hotmail.com> wrote in message
news:om********************@tornado.tampabay.rr.co m...
Here is my code below, it doesn't printf. But I step it thru using the for
statement and use putchar to the display, its there...

How can I get it to use printf? If the problem is needing a null at the
end and how can I do this?
I tried pos='\0' after my last memcpy and that doesn't work either.
================================================ =============

void ERR(char * err_msg){

char tmp[1024],*pos;
unsigned int len,i,s;

memset(tmp,'\0',1024);

len=strlen(err_msg);
s = ntohl(len);

pos=tmp;
memcpy(pos,&s,sizeof(s));
pos+=sizeof(s);
memcpy(pos,err_msg,len);

printf("%s\n",tmp);

}

So you've created a char array with a mangled int at the start and then
a string after, and you want to look at it? (Before presumably doing
something more useful.)

Maybe it'd be better to tell printf exactly what you want to look at.
(Not a string, but some numbers then a string). Something like:

int count;
for (count = 0; count < sizeof s; count++) {
printf("%02X", tmp[count]);
}
printf("%s\n", tmp+sizeof s);

This could give you output something like:
13000000There was an error.

Maybe that's what you're looking for.

--
Rob Morris: arr emm four four five (at) cam dot ac dot uk
Nov 14 '05 #8

P: n/a
On Sun, 12 Jun 2005 06:11:32 +0000, jt wrote:
Here is my code below, it doesn't printf. But I step it thru using the for
statement and use putchar to the display, its there...

How can I get it to use printf? If the problem is needing a null at the end
and how can I do this?
I tried pos='\0' after my last memcpy and that doesn't work either.
================================================== ===========

void ERR(char * err_msg){
This is a good opportunity for a const char * parameter.
char tmp[1024],*pos;
unsigned int len,i,s;

memset(tmp,'\0',1024);
A string is terminated by the first null character, it isn't normally
necessary to set the whole array containing a string to null.
len=strlen(err_msg);
You have the length of the string here so it would be easy as well as good
programming practice to check that it will fit in tmp.
s = ntohl(len);
ntohl() is not defined by the C language. There is a function by this
name associated with socket libraries which changes byte order of a long
sized integer from network to host byte order. If that is what you want
then you should be using it with long sized value and result variables.
Note that using it here doesn't make sense because the value you are
passing it is in host byte order, not network byte order.
pos=tmp;
memcpy(pos,&s,sizeof(s));
Now you're trying to copy data from a binary object to what appears to be
intended to be the start of a string. This again makes no sense.
pos+=sizeof(s);
memcpy(pos,err_msg,len);
If you use

memcpy(pos,err_msg,len+1);

or just

strcpy(pos,err_msg);

you will copy the err_msg string properly i.e. including the null
character at the end.
printf("%s\n",tmp);
The string you're trying to output contains binary data from len. This is
likely to appear as garbage when you try to display it.
}


The code as it stands doesn't do anything sensible. And it is so oddball
that it is not clear what you wanted it to do. Explain what you want the
code to do and the output you expect. I'll start with a suggestion and see
where we go from there:

void ERR(const char *err_msg)
{
printf("%lx %s\n", (unsigned long)strlen(err_msg), err_msg);
{


Nov 14 '05 #9

P: n/a
jt
> void ERR(const char *err_msg)
{
printf("%2x %s\n", (unsigned long)strlen(err_msg), err_msg);
{


That is good, but we are not quite there of what I need to accomplish.

This is what printf prints: 2Athis is a test for the err messages to cad
(that good and we are getting somewhere not)

The client will read it in binary hex and you see that the 1st 4 bytes (32
61): 32 61 74 68 78 20 and so on .... would be a very large decimal.

note: my requirement is that fist four bytes should be in network byte order
and read as 00 2A ..... in binary hex. Not ascii as above.

I tried everything and it always comes out in ascii as you have it as well.

jt

Nov 14 '05 #10

P: n/a
jt wrote:
void ERR(const char *err_msg)
{
printf("%2x %s\n", (unsigned long)strlen(err_msg), err_msg);
{

That is good, but we are not quite there of what I need to accomplish.

This is what printf prints: 2Athis is a test for the err messages to cad
(that good and we are getting somewhere not)

The client will read it in binary hex and you see that the 1st 4 bytes (32
61): 32 61 74 68 78 20 and so on .... would be a very large decimal.

note: my requirement is that fist four bytes should be in network byte order
and read as 00 2A ..... in binary hex. Not ascii as above.

I tried everything and it always comes out in ascii as you have it as well.


You need something like this:

unsigned long len = strlen(err_msg);
printf ("%c%c%c%c%s",
(int)(len >> 24),
(int)((len >> 16) & 0xFF),
(int)((len >> 8) & 0xFF),
(int)(len & 0xFF),
err_msg);

--
Eric Sosman
es*****@acm-dot-org.invalid
Nov 14 '05 #11

P: n/a
On Sun, 12 Jun 2005 07:01:31 GMT, Martin Ambuhl
<ma*****@earthlink.net> wrote:
jt wrote:

s = ntohl(len);


ntohl is not a standard C function (which makes it off-topic here); it
isn't even a standard POSIX function (which makes it off-topic in even
more places). <snip>


It is POSIX now, as of 2001/2002 = SUS3. Still not standard C.

- David.Thompson1 at worldnet.att.net
Nov 14 '05 #12

This discussion thread is closed

Replies have been disabled for this discussion.