473,503 Members | 2,150 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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 4985
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
1837
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
42090
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
2478
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
3504
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
3253
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
2643
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
3501
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
6564
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
3749
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
7205
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7287
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7349
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
7467
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
5594
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
4688
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3168
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1521
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
0
399
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

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.