473,768 Members | 8,216 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Integer to "string" conversions

Now, I read the faq, and it suggests using sprintf. However,
I want to all ways know where the integer finishes in the string.
Basically, I want to:

nbr | other data

But the other data all ways has to start at the same place. I had
some problems using sprintf to accomplish this requirement. Maybe
I am overlooking something. But sprintf translates the nbr exactly
into
the string, so the nbr 123, would end up occupying:

p[0] = '1'
p[1] = '2'
p[2] = '3'

So as the number grew, the space taken grew.

To solve this, I went with the solution below. But this would require
me
to OR back the number later. Is there a better way to do this?

Note: I am using uint32_t to signify a 32 bit unsigned integer. This
is implementation
specific, but for the sake of this discussion, I need to know
the size
of the integer being assigned to buf ahead of time. I am also
ignoring
dynamically allocated arrays for this discussion as well.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int
main(void) {

int i;
uint32_t nbr;
unsigned char buf[4];

nbr = 0xffffffff;
memset(buf, 0, sizeof buf);

buf[0] = (unsigned char)(nbr >24) & 0xff;
buf[1] = (unsigned char)(nbr >16) & 0xff;
buf[2] = (unsigned char)(nbr > 8) & 0xff;
buf[3] = (unsigned char) nbr & 0xff;

for(i = 0; i < 4; i++)
printf("%d\n", buf[i]);

exit(EXIT_SUCCE SS);
}

Sep 30 '06 #1
13 6877
bw*****@yahoo.c om wrote:
Now, I read the faq, and it suggests using sprintf. However,
I want to all ways know where the integer finishes in the string.
Basically, I want to:

nbr | other data

But the other data all ways has to start at the same place. I had
some problems using sprintf to accomplish this requirement. Maybe
I am overlooking something. [...]
Probably things like "%5d" or "%05d".

--
Eric Sosman
es*****@acm-dot-org.invalid
Sep 30 '06 #2
bw*****@yahoo.c om wrote:
Now, I read the faq, and it suggests using sprintf. However,
I want to all ways know where the integer finishes in the string.
Basically, I want to:

nbr | other data

But the other data all ways has to start at the same place. I had
some problems using sprintf to accomplish this requirement. Maybe
I am overlooking something. But sprintf translates the nbr exactly
into
the string, so the nbr 123, would end up occupying:

p[0] = '1'
p[1] = '2'
p[2] = '3'

So as the number grew, the space taken grew.

To solve this, I went with the solution below. But this would require
me
to OR back the number later. Is there a better way to do this?

Note: I am using uint32_t to signify a 32 bit unsigned integer. This
is implementation
specific, but for the sake of this discussion, I need to know
the size
of the integer being assigned to buf ahead of time. I am also
ignoring
dynamically allocated arrays for this discussion as well.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int
main(void) {

int i;
uint32_t nbr;
unsigned char buf[4];

nbr = 0xffffffff;
memset(buf, 0, sizeof buf);

buf[0] = (unsigned char)(nbr >24) & 0xff;
buf[1] = (unsigned char)(nbr >16) & 0xff;
buf[2] = (unsigned char)(nbr > 8) & 0xff;
buf[3] = (unsigned char) nbr & 0xff;

for(i = 0; i < 4; i++)
printf("%d\n", buf[i]);

exit(EXIT_SUCCE SS);
}
You are making your life far far too hard.

A) If you you used the following:

char buf[25];
unsigned int num = 3784;
sprintf(buf, "%d", num);

you could easily use strlen(buf) to figure out how long the sprintf()
result is.

B) Why not combine all the string formatting together into one process
using something like:

char buf[100];
unsigned int num = 23405;
unsigned int num2 = 978;
char name[] = "Ben Hurr";
sprintf(buf, "%10d %s - %d\n", num, name, num2);

- mkaras

Sep 30 '06 #3
bw*****@yahoo.c om wrote:
>
Now, I read the faq, and it suggests using sprintf. However,
I want to all ways know where the integer finishes in the string.
Basically, I want to:

nbr | other data

But the other data all ways has to start at the same place. I had
some problems using sprintf to accomplish this requirement. Maybe
I am overlooking something. But sprintf translates the nbr exactly
into
the string, so the nbr 123, would end up occupying:

p[0] = '1'
p[1] = '2'
p[2] = '3'
sizeof "123" is four, not three.

p[3] = '\0'

--
pete
Sep 30 '06 #4

mkaras wrote:
You are making your life far far too hard.

A) If you you used the following:

char buf[25];
unsigned int num = 3784;
sprintf(buf, "%d", num);

you could easily use strlen(buf) to figure out how long the sprintf()
result is.
True, but then buf grows even larger. Let me explain what I am doing.
I am writing a file to a socket. I am working on designing the
protocol,
so I want to write the size of the file as well as other information
before
appending a portion of the file to the buffer. I need to make sure that
the size of the file is all ways at the same place in the buffer, and I
want to make sure the portion of the file all ways starts in the
same place.

Once that is done, the receiving end will know how to process the
packet
being received.

At the end of the day, I am just copying between two buffers. The file
transfer
stuff is implementation specific -- off topic here. One side just
creates a
buffer and sends if over the wire. The other side writes that packet
to a buffer
and processes it. It still is just copying one buffer to another.
>
B) Why not combine all the string formatting together into one process
using something like:

char buf[100];
unsigned int num = 23405;
unsigned int num2 = 978;
char name[] = "Ben Hurr";
sprintf(buf, "%10d %s - %d\n", num, name, num2);
I intend to write specific functions for handling the creation of the
final buffer.
I posted one under "more buffer" here a while ago. That one just
appended
characters to a buffer and resized as needed. I received great
feedback
for expanding that buffer by incremental pages. That solution is
working out great.
It lead me to look more carefully at bitwise operators.

For the purposes of this buffer, I do not need to nul terminate, I just
need
to store somewhere the location of the end of the buffer as well as the
size of
the buffer. But I can nul terminate for the sake of maintaining c
strings, and just overwrite
the nul terimator with the subsequent append.

Sep 30 '06 #5
"bw*****@yahoo. com" wrote:
>
Now, I read the faq, and it suggests using sprintf. However,
I want to all ways know where the integer finishes in the string.
Basically, I want to:

nbr | other data

But the other data all ways has to start at the same place. I had
some problems using sprintf to accomplish this requirement. Maybe
I am overlooking something. But sprintf translates the nbr exactly
into the string, so the nbr 123, would end up occupying:

p[0] = '1'
p[1] = '2'
p[2] = '3'

So as the number grew, the space taken grew.

To solve this, I went with the solution below. But this would
require me to OR back the number later. Is there a better way
to do this?

Note: I am using uint32_t to signify a 32 bit unsigned integer.
This is implementation specific, but for the sake of this
discussion, I need to know the size of the integer being
assigned to buf ahead of time. I am also ignoring dynamically
allocated arrays for this discussion as well.

#include <stdio.h>
#include <stdlib.h>
/* #include <string.h>
*/
int
main(void) {
int i;
unsigned long nbr;
unsigned char buf[4];

nbr = 0xff100401;
/* memset(buf, 0, sizeof buf); */
>
buf[0] = (unsigned char)(nbr >24) & 0xff;
buf[1] = (unsigned char)(nbr >16) & 0xff;
buf[2] = (unsigned char)(nbr > 8) & 0xff;
buf[3] = (unsigned char) nbr & 0xff;
for (i = 0; i < 4; i++) printf("%03d ", buf[i]);
putchar('\n');
>
exit(EXIT_SUCCE SS);
}
Does the above do what you want? Note changes.

--
Some useful references about C:
<http://www.ungerhu.com/jxh/clc.welcome.txt >
<http://www.eskimo.com/~scs/C-faq/top.html>
<http://benpfaff.org/writings/clc/off-topic.html>
<http://anubis.dkuug.dk/jtc1/sc22/wg14/www/docs/n869/(C99)
<http://www.dinkumware. com/refxc.html (C-library}
<http://gcc.gnu.org/onlinedocs/ (GNU docs)
<http://clc-wiki.net (C-info)

Oct 1 '06 #6

CBFalconer wrote:
#include <stdio.h>
#include <stdlib.h>
/* #include <string.h>
*/
int
main(void) {
int i;
unsigned long nbr;
unsigned char buf[4];

nbr = 0xff100401;
/* memset(buf, 0, sizeof buf); */

buf[0] = (unsigned char)(nbr >24) & 0xff;
buf[1] = (unsigned char)(nbr >16) & 0xff;
buf[2] = (unsigned char)(nbr > 8) & 0xff;
buf[3] = (unsigned char) nbr & 0xff;
for (i = 0; i < 4; i++) printf("%03d ", buf[i]);
putchar('\n');

exit(EXIT_SUCCE SS);
}

Does the above do what you want? Note changes.
Yes. Here's taking those changes to the next step:

int
main(void) {

int i;
unsigned long nbr, nbr2;
unsigned char buf[4];

nbr = 0xff100401;

printf("%lu\n", nbr);

buf[0] = (unsigned char)(nbr >24) & 0xff;
buf[1] = (unsigned char)(nbr >16) & 0xff;
buf[2] = (unsigned char)(nbr > 8) & 0xff;
buf[3] = (unsigned char) nbr & 0xff;

for(i = 0; i < 4; i++)
printf("%03d", buf[i]);
putchar('\n');

nbr2 = (unsigned long)buf[0] << 24;
nbr2 |= (unsigned long)buf[1] << 16;
nbr2 |= (unsigned long)buf[2] << 8;
nbr2 |= (unsigned long)buf[3];

printf("%lu\n", nbr2);

exit(EXIT_SUCCE SS);
}

I am able to "save" the integer to the buffer and extract it later.
You removed my
memset because I was immediately assigning the array after it, right?
unsigned
long is 32 bit, so you backed away my implementation specific type. But
I don't
quite get your printf change. It guarantees that each item printed
from the array
buf is 3 characters wide and will lead with a zero if needed. Why that
change?

Thanks!

Oct 1 '06 #7
bw*****@yahoo.c om wrote:
True, but then buf grows even larger. Let me explain what I am doing.
I am writing a file to a socket. I am working on designing the
protocol,
so I want to write the size of the file as well as other information
before
appending a portion of the file to the buffer. I need to make sure that
the size of the file is all ways at the same place in the buffer, and I
want to make sure the portion of the file all ways starts in the
same place.

Once that is done, the receiving end will know how to process the
packet
being received.
You are still making this incredibly too hard for what is normally done. By
hard I mean you shouldn't be converting integers to strings, etc. just to
transmit it over a socket. You're working with sockets, so we're already out
of comp.lang.c land, and I'm adding comp.unix.progr ammer here. As a result of
working with sockets, you SHOULD have the standard repertoire of functions
available. If you want to transmit the size of a file, previous to the file,
aka LV, or extended more, TLV (type-length-value), you do just that. However,
you design things ahead of time such that both sides know what protocol
they're speaking, and you always transmit any single object larger than a
byte in network byte order. This applies to shorts, ints, longs, etc. It does
not apply to streams of byte data. Before you even get into this territory,
it's pretty much required that you pick up a copy of W. Richard Stevens: Unix
Network Programming, Volume 1. Without it, you're going to make a lot of
novice mistakes.

In your particular example, you want to send size first, most likely as a
network byte order uint_32t and then the stream of bytes representing the
file. Extremely basic protocol, essentially:

/*
* all code below not entirely comp.lang.c safe
*/

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/uio.h>

ssize_t file_send(int, char *, size_t);
ssize_t file_recv(int, char *, size_t);

ssize_t file_send(int s, char *buf, size_t sz)
{
struct iovec packet[2];
ssize_t bw;
uint32_t nbo_sz;

/* host to network long, look it up and use it, or else */
nbo_sz = htonl(sz);
packet[0].iov_len = sizeof(nbo_sz);
packet[0].iov_base = &nbo_sz;
packet[1].iov_len = sz;
packet[1].iov_base = buf;

/*
* naive, don't do as one call and call it a day, and don't do it as
* blocking. this is entirely for simple contrived example.
* read: W. Richard Stevens: UNPv1
*/
if ((bw = writev(s, packet, 2)) == -1) {
perror("writev" );
return -1;
}

return bw;
}

ssize_t file_recv(int s, char *buf, size_t sz)
{
struct iovec packet[2];
ssize_t br, brt = 0;
uint32_t nbo_sz;

/*
* in this recv example, one doesn't necessarily need to use iovecs,
* but it's a good idea as you may end up sending more than just size
* initially.
*/
packet[0].iov_len = sizeof(nbo_sz);
packet[0].iov_base = &nbo_sz;

/*
* naive, don't do as one call and call it a day, and don't do it as
* blocking. this is entirely for simple contrived example.
* read: W. Richard Stevens: UNPv1
*/
if ((br = readv(s, packet, 1)) == -1) {
perror("readv") ;
return -1;
}
brt += br;

/* network to host long, look it up and use it, or else */
nbo_sz = ntohl(nbo_sz);

/*
* better handle nbo_sz sz, and handle it appropriately either
* through a callback to handle the remaining bytes, realloc, etc
* or some other form of unexpected case handling or do it
* after the intial sz-max read.
*/
packet[0].iov_len = nbo_sz sz ? sz : nbo_sz; /* example only */
packet[0].iov_base = buf;

/*
* naive, don't do as one call and call it a day, and don't do it as
* blocking. this is entirely for simple contrived example.
* read: W. Richard Stevens: UNPv1
*/
if ((br = readv(s, packet, 1)) == -1) {
perror("readv") ;
return -1;
}
brt += br;

/*
* possibly handle nbo_sz sz here by calling a user supplied callback
* to realloc or store elsewhere or some other form of unexpected case
* handling. either way, plan for it - as it will happen.
*/

return brt;
}

Oct 1 '06 #8
"bw*****@yahoo. com" wrote:
CBFalconer wrote:
.... snip ...
>
for (i = 0; i < 4; i++)
printf("%03d", buf[i]);
putchar('\n');
.... snip ...
>
I don't quite get your printf change. It guarantees that each
item printed from the array buf is 3 characters wide and will
lead with a zero if needed. Why that change?
I thought you were complaining that the field used varied with the
value. If you don't want the leading zeroes, remove the '0'.

--
Some informative links:
<news:news.anno unce.newusers
<http://www.geocities.c om/nnqweb/>
<http://www.catb.org/~esr/faqs/smart-questions.html>
<http://www.caliburn.nl/topposting.html >
<http://www.netmeister. org/news/learn2quote.htm l>
<http://cfaj.freeshell. org/google/>
Oct 1 '06 #9
CBFalconer wrote:
I thought you were complaining that the field used varied with the
value. If you don't want the leading zeroes, remove the '0'.
As far as I could tell, he was looking for a way of encoding "size" in a fixed
length method that would be network-portable. snprintf() could be used for
that, in a rather bizarre, inefficient, and roundabout way.
Oct 1 '06 #10

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

Similar topics

32
2693
by: Indrid Colt | last post by:
Thank's for your help ! Indrid
9
7135
by: rsine | last post by:
I have developed a program that sends a command through the serial port to our business system and then reads from the buffer looking for a number. Everything worked great on my WinXP system, but when I tried the program on the Win98 system it will be running on, I get the following error: Cast from string "2076719" to type 'Long' is not valid I am not sure why I only get this error on the Win98 system or how to go about correcting...
35
75218
by: pinkfloydhomer | last post by:
How do I check if a string contains (can be converted to) an int? I want to do one thing if I am parsing and integer, and another if not. /David
4
13776
by: dc15 | last post by:
For an intro to VB project I have to write a program which takes an amount of Miles, Yards, and Inches.....and converts it to metric (KM, M, and CM) when all values are entered to the input text boxes it works fine, but if there is a number missing I get the following error: An unhandled exception of type 'System.InvalidCastException' occurred in microsoft.visualbasic.dll Additional information: Cast from string "" to type 'Double' is...
10
13641
by: =?Utf-8?B?RWxlbmE=?= | last post by:
I am surprised to discover that c# automatically converts an integer to a string when concatenating with the "+" operator. I thought c# was supposed to be very strict about types. Doesn't it seem like c# is breaking its own rules? This works: int b = 32; string a = "ABC " + b; Result: a = "ABC 32"
3
5033
by: Ady1 | last post by:
Hi, I'm getting this error intermitantly in a custom configuration section in my ASP.NET website. From what I can see 0.175 is a valid string to be converted to a decimal! And most of the time it works, so why is it that about once a week for about half an hour I get this error? Any Ideas? Thanks, Ady
6
4593
by: =?Utf-8?B?SmVmZg==?= | last post by:
I thought this would already be covered here, but my search turned up nothing. In VS2005, if I use "String" to define a new variable/class, it colors it in the Aqua color as it does other classes. But if I use "string", it colors it in Navy blue as in C# reserved words (e.g. private, void, foreach, etc). What is the diff?
10
26909
by: Dave griffiths | last post by:
Hi all Using VB2005 on Vista with a Norwegian locale setup. The test program has 3 textboxes the sum held in txt3. Using the code below, txt2 conversion causes an error when it is left empty. The code in txt1 works OK but I am asking is there a better way of coding this Public Class Main
3
52523
by: satyakarvvk | last post by:
Hi everybody! Please help me to overcome below runtime exception. Actually it is a simple program on basics. I want to print odd nos upto which the user asks and after printing the task, again i will ask user whether he want to continue again and the process is repeated. My code is working first time normally but after user says yes(y) for continuing again my code producing an error. The Integer.parseInt taking space as default...
0
9576
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9407
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10175
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9843
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8840
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, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6656
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 then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5283
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
3932
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 we have to send another system
2
3534
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.