473,241 Members | 1,522 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,241 software developers and data experts.

problems with sprintf...

Hi all....

I have a little problem that's driving me nuts. I can't seem to make any
sense of it. I have this small webserver that substitutes some data from a
page when finds a substitution string. I all works fine, even the sprintf,
when I write numbers. But if I want to write a character string, it all goes
wrong.
I am trying to print "over" on the pointer Key on a function that looks
like this (this is only an extract of the real one, which is much larger).
While I print floats or integers there's no problem, even if I write a small
string with a couple characters like "/bm" works fine. But when I get to the
case 'c' it displays a 5 digit number, always the same, and then my string.
unsigned char *Key;
unsigned char NewKey[25];
unsigned int i;

if (TCPTxDataCount < 4) return;

Key = TCP_TX_BUF;

for (i = 0; i < (TCPTxDataCount - 2); i++)
{
if (*Key == '¿')
{
if (*(Key + 1) == '?')
{
switch (*(Key + 2))
{
case 'a' :
{
sprintf(NewKey, "%4.2f", Func_returning_a_float());
memcpy(Key, NewKey, 5);
break;
}
case 'b' :
{
if (Get_conditional_function() == 0xAFAF)
{
sprintf(NewKey, "%4.3f", Float_number_1());
memcpy(Key, NewKey, 4);
break;
}
else
{
sprintf(NewKey, "%4.3f%s", float_num_2(), "/bm");
memcpy(Key, NewKey, 7);
break;
}
/* up until here it all works smoothly. */
case 'c' :
{
sprintf(NewKey, "%s", "over");
memcpy(Key, NewKey, 4);
break;
}

/* if I reset the amount of data to be copied to Key from 4 to, lets say,
20, I get a 7 digit number, always the same, and then my string....
something like: "20.7570over"
Any idea of what's going on? I thought I was using sprintf correctly, but it
seems it doesn't want to work with characters....
Cheers!

Yodai



Nov 14 '05 #1
13 4970
If someone sees the problem and feels like answering, feel free. But I
arranged the problem changing the switch caracters. I still don't know what
was failing, but I had one of those lucky strikes
I-don't-know-how-I-did-it-but-it-works....

Yodai
"Yodai" <yo***@spamnot.mail.vu> escribió en el mensaje
news:sw***********************@telenews.teleline.e s...
Hi all....

I have a little problem that's driving me nuts. I can't seem to make any
sense of it. I have this small webserver that substitutes some data from a
page when finds a substitution string. I all works fine, even the sprintf,
when I write numbers. But if I want to write a character string, it all goes wrong.
I am trying to print "over" on the pointer Key on a function that looks
like this (this is only an extract of the real one, which is much larger).
While I print floats or integers there's no problem, even if I write a small string with a couple characters like "/bm" works fine. But when I get to the case 'c' it displays a 5 digit number, always the same, and then my string.

unsigned char *Key;
unsigned char NewKey[25];
unsigned int i;

if (TCPTxDataCount < 4) return;

Key = TCP_TX_BUF;

for (i = 0; i < (TCPTxDataCount - 2); i++)
{
if (*Key == '¿')
{
if (*(Key + 1) == '?')
{
switch (*(Key + 2))
{
case 'a' :
{
sprintf(NewKey, "%4.2f", Func_returning_a_float());
memcpy(Key, NewKey, 5);
break;
}
case 'b' :
{
if (Get_conditional_function() == 0xAFAF)
{
sprintf(NewKey, "%4.3f", Float_number_1());
memcpy(Key, NewKey, 4);
break;
}
else
{
sprintf(NewKey, "%4.3f%s", float_num_2(), "/bm");
memcpy(Key, NewKey, 7);
break;
}
/* up until here it all works smoothly. */
case 'c' :
{
sprintf(NewKey, "%s", "over");
memcpy(Key, NewKey, 4);
break;
}

/* if I reset the amount of data to be copied to Key from 4 to, lets say,
20, I get a 7 digit number, always the same, and then my string....
something like: "20.7570over"
Any idea of what's going on? I thought I was using sprintf correctly, but it seems it doesn't want to work with characters....
Cheers!

Yodai


Nov 14 '05 #2
On Tue, 13 Jan 2004 10:12:40 GMT,
Yodai <yo***@spamnot.mail.vu> wrote
in Msg. <sw***********************@telenews.teleline.es>
Hi all....

I have a little problem that's driving me nuts. I can't seem to make any
sense of it. I have this small webserver that substitutes some data from a
page when finds a substitution string. I all works fine, even the sprintf,
when I write numbers. But if I want to write a character string, it all goes
wrong.
While I can't see right away what causes your code to behave the way it
does, here a few tips:

1) When using sprintf() you run the risk of buffer overflow unless you
can make absolutely sure that no possible argument value can cause an
overflow. It's better to use snprintf() if you have it.

2) The string literal "over" requires 5 bytes, not 4 (but that doesn't
seem to be your problem here). Related note: Replace the calls to memcpy
with strcpy which always takes care of the trailing zero. And make sure
that Key is big enouch to hold the data *in all cases*.
string with a couple characters like "/bm" works fine. But when I get to the
case 'c' it displays a 5 digit number, always the same, and then my string.
What does 'it displays' mean? There is no code in your snippet that
displays anything. The code you posted seems to put the right thing into
NewKey, but NewKey might get corrupted someplace else.

You're experiencing a classic case of Undefined Behaviour. The more
difficult it is to track the mistake, the more embarrasing it usually is
when you finally find it ;-)
case 'c' :
{
sprintf(NewKey, "%s", "over");
memcpy(Key, NewKey, 4);
break;
}
Any idea of what's going on? I thought I was using sprintf correctly, but it
seems it doesn't want to work with characters....


Just for giggles... Have you tried strcpy(Key, "over")? Should accomplish
the exact same thing. But yes, you're using sprintf correctly.

--Daniel

--
"With me is nothing wrong! And with you?" (from r.a.m.p)
Nov 14 '05 #3
On Tue, 13 Jan 2004 10:33:47 GMT,
Yodai <yo***@spamnot.mail.vu> wrote
in Msg. <fQ***********************@telenews.teleline.es>
If someone sees the problem and feels like answering, feel free. But I
arranged the problem changing the switch caracters. I still don't know what
was failing, but I had one of those lucky strikes
I-don't-know-how-I-did-it-but-it-works....


I'm tempted to think that you're still having UB, only now it happens to
behave the way you expect... for a while... until you change something
someplace and everything goes haywire again.

Has happened many times to me (and to everybody else on this ng, I
daresay).

--Daniel

--
"With me is nothing wrong! And with you?" (from r.a.m.p)
Nov 14 '05 #4
In <sw***********************@telenews.teleline.es> "Yodai" <yo***@spamnot.mail.vu> writes:
I am trying to print "over" on the pointer Key on a function that looks
like this (this is only an extract of the real one, which is much larger).
While I print floats or integers there's no problem, even if I write a small
string with a couple characters like "/bm" works fine. But when I get to the
case 'c' it displays a 5 digit number, always the same, and then my string.
unsigned char *Key;
unsigned char NewKey[25];
unsigned int i;

if (TCPTxDataCount < 4) return;

Key = TCP_TX_BUF;

for (i = 0; i < (TCPTxDataCount - 2); i++)
{
if (*Key == '¿')
{
if (*(Key + 1) == '?')
{
switch (*(Key + 2))
{
case 'a' :
{
sprintf(NewKey, "%4.2f", Func_returning_a_float());
memcpy(Key, NewKey, 5);
break;
}
case 'b' :
{
if (Get_conditional_function() == 0xAFAF)
{
sprintf(NewKey, "%4.3f", Float_number_1());
memcpy(Key, NewKey, 4);
break;
}
else
{
sprintf(NewKey, "%4.3f%s", float_num_2(), "/bm");
memcpy(Key, NewKey, 7);
break;
}
/* up until here it all works smoothly. */
case 'c' :
{
sprintf(NewKey, "%s", "over");
memcpy(Key, NewKey, 4);
break;
}

/* if I reset the amount of data to be copied to Key from 4 to, lets say,
20, I get a 7 digit number, always the same, and then my string....
something like: "20.7570over"
Any idea of what's going on? I thought I was using sprintf correctly, but it
seems it doesn't want to work with characters....


I suspect the problem is memory corruption occuring elsewhere in your
program. Put the above code into the main function, along with the
missing bits necessary to turn it into a complete program and see what
happens.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #5
Yup.... but I just found the reason... It belonged to another part of the
program where I was forcing to execute 2 different switch under the same
if,else, giving only once the instruction key++, thus, only allowing one of
my switch to advance forward.....

Cheers...

Yodai
Nov 14 '05 #6
"Yodai" <yo***@spamnot.mail.vu> wrote in message news:<sw***********************@telenews.teleline. es>...
Hi all....

I have a little problem that's driving me nuts. I can't seem to make any
sense of it. I have this small webserver that substitutes some data from a
page when finds a substitution string. I all works fine, even the sprintf,
when I write numbers. But if I want to write a character string, it all goes
wrong.
I am trying to print "over" on the pointer Key on a function that looks
like this (this is only an extract of the real one, which is much larger).
While I print floats or integers there's no problem, even if I write a small
string with a couple characters like "/bm" works fine. But when I get to the
case 'c' it displays a 5 digit number, always the same, and then my string.
unsigned char *Key;
unsigned char NewKey[25];
unsigned int i;

if (TCPTxDataCount < 4) return;

Key = TCP_TX_BUF;

for (i = 0; i < (TCPTxDataCount - 2); i++)
{
if (*Key == '¿')
{
if (*(Key + 1) == '?')
{
switch (*(Key + 2))
{
case 'a' :
{
sprintf(NewKey, "%4.2f", Func_returning_a_float());
memcpy(Key, NewKey, 5);
break;
}
case 'b' :
{
if (Get_conditional_function() == 0xAFAF)
{
sprintf(NewKey, "%4.3f", Float_number_1());
memcpy(Key, NewKey, 4);
break;
}
else
{
sprintf(NewKey, "%4.3f%s", float_num_2(), "/bm");
memcpy(Key, NewKey, 7);
break;
}
/* up until here it all works smoothly. */
case 'c' :
{
sprintf(NewKey, "%s", "over");
memcpy(Key, NewKey, 4);
break;
}

/* if I reset the amount of data to be copied to Key from 4 to, lets say,
20, I get a 7 digit number, always the same, and then my string....
something like: "20.7570over"
Any idea of what's going on? I thought I was using sprintf correctly, but it
seems it doesn't want to work with characters....
Cheers!

Yodai


You aren't allowing for copying the terminating NUL character with your
memcpy. To copy "over", you need to copy 5 bytes. Note that your
stringified floats will often not be copied in full, and the string
won't be terminated if they are not... %4.2f says minimum field
width 4, max precision of 2 digits after the decimal point.

e.g. 100.4567 -> sprintf("%4.2f",...) -> 100.45

Which takes 7 bytes as a string... If you aren't worried
about efficiency you could use strcpy, though you then must make
sure you don't exceed the bounds of your target array. Or you
could use snprintf if you have C99/compiler extensions to
restrict the number of bytes in the string. From the code above,
you also could perhaps sprintf straight into your Key as well.

-David
Nov 14 '05 #7
"David Resnick" <ln********@hotmail.com> wrote in message
news:59**************************@posting.google.c om...
Note that your stringified floats will often not be copied in full,
and the string won't be terminated if they are not...


sprintf() never creates an unterminated string.
Nov 14 '05 #8
Yodai wrote:

Please don't top-post. Your replies belong following properly trimmed
quotes.
If someone sees the problem and feels like answering, feel free. But I
arranged the problem changing the switch caracters. I still don't know what
was failing, but I had one of those lucky strikes
I-don't-know-how-I-did-it-but-it-works....

I don't know that I would call it lucky. You've been successful at
shotgun debugging.

shotgun debugging
n. The software equivalent of Easter egging; the making of relatively
undirected changes to software in the hope that a bug will be perturbed
out of existence. This almost never works, and usually introduces more
bugs.
You did manage to perturb your bug temporarily. However, rearranging
case elements is not likely to fix anything, just cover it up. The sort
of problem you describe, and the "fix" often points toward problems with
automatic storage, "whacking the stack" or some equivalent. Likely some
code is overwriting other elements. By changing the order, you change
with gets clobbered, and now it isn't the thing you could see before.

In some ways, you've gone from bad to worse. Before, you at least had an
indication that things were wrong and approximately where. Now it
probably lurking under the surface, waiting for you to make another
change or add something, so it can bite you in a new place.


Brian Rodenborn
Nov 14 '05 #9
On Tue, 13 Jan 2004 10:33:47 GMT, "Yodai" <yo***@spamnot.mail.vu>
wrote:
If someone sees the problem and feels like answering, feel free. But I
arranged the problem changing the switch caracters. I still don't know what
was failing, but I had one of those lucky strikes
I-don't-know-how-I-did-it-but-it-works....

No, it doesn't. It just misbehaves in a different way, that you
haven't seen yet. "Fixes" like this often produce programs which work
only until a customer uses them.

What you should do now is put the code back the way it was, and find
the real problem. Then look for the same problem in the rest of the
program, because you've probably done it more than once.

--
Al Balmer
Balmer Consulting
re************************@att.net
Nov 14 '05 #10
In <bu************@ID-149533.news.uni-berlin.de> "Alex" <me@privacy.net> writes:
"David Resnick" <ln********@hotmail.com> wrote in message
news:59**************************@posting.google. com...
Note that your stringified floats will often not be copied in full,
and the string won't be terminated if they are not...


sprintf() never creates an unterminated string.


But memcpy(), as used in the code under discussion, does.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #11
"Alex" <me@privacy.net> wrote in message news:<bu************@ID-149533.news.uni-berlin.de>...
"David Resnick" <ln********@hotmail.com> wrote in message
news:59**************************@posting.google.c om...
Note that your stringified floats will often not be copied in full,
and the string won't be terminated if they are not...


sprintf() never creates an unterminated string.


Yep, even if does a buffer overrun to do so. I wasn't saying that,
I was talking about the memcpy. If you memcpy part of a string generated
with sprintf, you won't get the termination...

-David
Nov 14 '05 #12
On Tue, 13 Jan 2004, Yodai wrote:
Hi all....

I have a little problem that's driving me nuts. I can't seem to make any
sense of it. I have this small webserver that substitutes some data from a
page when finds a substitution string. I all works fine, even the sprintf,
when I write numbers. But if I want to write a character string, it all goes
wrong.
I am trying to print "over" on the pointer Key on a function that looks
like this (this is only an extract of the real one, which is much larger).
While I print floats or integers there's no problem, even if I write a small
string with a couple characters like "/bm" works fine. But when I get to the
case 'c' it displays a 5 digit number, always the same, and then my string.
unsigned char *Key;
unsigned char NewKey[25];
unsigned int i;

if (TCPTxDataCount < 4) return;
What is the significance of 4 here? You might want to use a const or
something. If I had to take over your code I'd end up wasting a lot of
time figuring out little things like this.
Key = TCP_TX_BUF;

for (i = 0; i < (TCPTxDataCount - 2); i++)
The variable i is an unsigned int. Do you know what will happen if
TCPTxDataCount is 0, 1 or 2? What does i < -2 means when i is unsigned?
{
if (*Key == '¿')
Failed to see if Key is NULL before dereferencing it. If Key == NULL then
you want to abort this whole thing.
{
/* inside if statement #1 */
if (*(Key + 1) == '?')
{
/* inside if statement #2 */
switch (*(Key + 2))
{
/* inside switch statement */
case 'a' :
{
/* inside case a block */ sprintf(NewKey, "%4.2f", Func_returning_a_float());
memcpy(Key, NewKey, 5);
Why the magic number 5?
break;
}
/* outside case a block */
case 'b' :
{
/* inside case b block */
if (Get_conditional_function() == 0xAFAF)
{
/* inside if statement #3 */
sprintf(NewKey, "%4.3f", Float_number_1());
memcpy(Key, NewKey, 4);
break;
}
/* outside if statement #3 */
else
{

/* inside else statement associated with if #3 */
sprintf(NewKey, "%4.3f%s", float_num_2(), "/bm");
memcpy(Key, NewKey, 7);
Why the magic number 7?
break;
}
/* outside else statement, but still in case b */
/* up until here it all works smoothly. */
You are about to define case c but you have not closed off the case b
block.
case 'c' :
{
sprintf(NewKey, "%s", "over");
memcpy(Key, NewKey, 4);
Why the magic number 4?
break;
}

/* if I reset the amount of data to be copied to Key from 4 to, lets say,
20, I get a 7 digit number, always the same, and then my string....
something like: "20.7570over"
Maybe you are using memcpy wrong? If I have the data:

char NewKey[] = "over";

then the size of NewKey is 5. This is more obvious if I write it as:

char NewKey[] = { 'o', 'v', 'e', 'r', '\0' };
Any idea of what's going on? I thought I was using sprintf correctly, butit
seems it doesn't want to work with characters....


I saw your message indicating that the problem went away. If you don't
know why something was failing and why it started working again, then you
know nothing. It APPEARS to be working.

In real life development the odds of this attitude working are against
you. You do some testing and it looks like it works. Maybe one other
developers will test your code. Someone from integration and system
testing will look at it. Maybe even a dozen people will go over it during
the software development life cycle. We round up to the nearest 10 and say
that 20 people have tried it and it appears to work. You then release it
to the market and 10,000 people try it within the first week. I bet you
10,000 people using it will find that bug you are missing.

--
Send e-mail to: darrell at cs dot toronto dot edu
Don't send e-mail to vi************@whitehouse.gov
Nov 14 '05 #13
hey.! thank's for the post....... it WAS helpful.... I posted above the
solution to my problem which I finally found out....

Yodai
Nov 14 '05 #14

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Darren | last post by:
hi, i'm trying to write some code to generate seperate files with the name of a call number, and containing the call data, from one big file containing all data. but when i run it, i get the...
3
by: huey_jiang | last post by:
Hi All, I am trying to figure out a right syntax to convert an integer array into hex array. sprintf worked for me on doing single integer: int i, Iarray, n=15; char buf; sprintf(buf,...
6
by: jt | last post by:
I need to produce 1 character array from 3 others. I tried sprintf and it terminates on the first 0, null, 0x00 it sees in tmp data. All 3 args print out nice by themselves. By trying to make...
1
by: jimjim | last post by:
Hello, I was wondering about the implications of giving as an argument to sprintf a different data type from the one specified in the format argument. This type of question along with some...
2
by: Mike | last post by:
Hi, I am new to C and having problems with the following program. Basically I am trying to read some files, loading data structures into memory for latter searching. I am trying to use structres...
6
by: merrittr | last post by:
I am trying to build variables for a function using sprintf. However they don't seem to be proper char strings since submiting literals seems to work fine. Any advice to get me rolling? ...
15
by: krister | last post by:
Hello, I'm working in a quite large system that has some limitations. One of those is that I can't use printf() to get an output on a screen. I'm forced to use a special function, let's call it...
4
by: Patrick | last post by:
Hello, I'm currently trying the OpenSSL Library, but I got some problems. I want to create a server and client application that communicate through the OpenSSL API, but this code doesn't work. I...
4
by: Highlander2nd | last post by:
Hello there. I'm Andrew Lucas, I'm a programmer for Half-Life. I've been working on stencil shadows lately, and I've been having problems saving mesh data for my models. When I store mesh data, I...
0
by: jianzs | last post by:
Introduction Cloud-native applications are conventionally identified as those designed and nurtured on cloud infrastructure. Such applications, rooted in cloud technologies, skillfully benefit from...
0
by: abbasky | last post by:
### Vandf component communication method one: data sharing ​ Vandf components can achieve data exchange through data sharing, state sharing, events, and other methods. Vandf's data exchange method...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
0
by: fareedcanada | last post by:
Hello I am trying to split number on their count. suppose i have 121314151617 (12cnt) then number should be split like 12,13,14,15,16,17 and if 11314151617 (11cnt) then should be split like...
0
by: stefan129 | last post by:
Hey forum members, I'm exploring options for SSL certificates for multiple domains. Has anyone had experience with multi-domain SSL certificates? Any recommendations on reliable providers or specific...
0
Git
by: egorbl4 | last post by:
Скачал я git, хотел начать настройку, а там вылезло вот это Что это? Что мне с этим делать? ...
0
by: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....
0
by: Aftab Ahmad | last post by:
So, I have written a code for a cmd called "Send WhatsApp Message" to open and send WhatsApp messaage. The code is given below. Dim IE As Object Set IE =...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.