472,372 Members | 2,315 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

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

writing alibrary funtion ssprintf()

hi

overview:
function sprintf(<buffername>,<format string>, .....)
in this function you need to allocate the size of buffername before
hand.

question:
function ssprintf(<buffername>,<format string>, .....)
i need to write a funtion in time and space optimized way so that i
should allocate buffername after getting the string.(ignore the time of
mallocing the memory...there is a different strategy for mallocing...it
won't take much time)
i have thought of a strategy:
1. writing the format string to /dev/null or to memory and get the
length of the string and then again malloc(not exactly malloc ....there
is a different optimized strategy) the required string.
problem: a call to printf takes time if the string is long
note:calling string functions like strlen also takes time.
can you suggest me a better optimized strategy.

Apr 26 '06 #1
3 4969
ji************@gmail.com wrote:
question:
function ssprintf(<buffername>,<format string>, .....)
i need to write a funtion in time and space optimized way so that i
should allocate buffername after getting the string.(ignore the time of
mallocing the memory...there is a different strategy for mallocing...it
won't take much time)
i have thought of a strategy:
1. writing the format string to /dev/null or to memory and get the
length of the string and then again malloc(not exactly malloc ....there
is a different optimized strategy) the required string.
problem: a call to printf takes time if the string is long
note:calling string functions like strlen also takes time.
can you suggest me a better optimized strategy.


A portable approach would involve allocating a buffer with a default
large size, and calling snprintf and (your) realloc on it. Snprintf
will return the size of the buffer required for printing the whole
string, so you can always adjust the default size upwards to match that
number, and keep it that way in subsequent calls. For the first few
calls your implementation will call snprintf multiple times to establish
the size needed, but this overhead will be amortized over time.

One other more cumbersome approach is to take an open-source sprintf
implementation and modify it to make it work in the way you want. You
will find that most printf implementations keep track of the size of the
resulting string, in order to implement functions like snprintf. For
example, the FreeBSD/NetBSD implementation keeps the distinct elements
to be printed in an iov vector of output objects, and tallies their
length. This is done by a call to a PRINT macro for each distinct element.

#define PRINT(ptr, len) { \
iovp->iov_base = (ptr); \
iovp->iov_len = (len); \
uio.uio_resid += (len); \
iovp++; \
if (++uio.uio_iovcnt >= NIOV) { \
if (__sprint(fp, &uio)) \
goto error; \
iovp = iov; \
} \
}

You can thus take uio.uio_resid and use it to allocate the string's
buffer, before flushing the buffer to it. For an example on how this is
done, look at the FreeBSD asprintf implementation, which allocates the
buffer memory with malloc.

A different (non-portable) approach is to create an stdio object that
will write to a dynamically growing buffer. Nowadays many stdio
implementations are object-oriented, and provide you a (non-portable and
sometimes undocumented) way to supply your own underlying I/O functions.
For example, the FreeBSD implementation's fwopen function takes as an
argument a pointer to a write function.

FILE *fwopen(void *cookie, int (*writefn)(void *, const char *, int));

I assume that your optimized malloc implementation can grow objects
dynamically. If not, look at the GNU Obstack facility
<http://gcc.gnu.org/onlinedocs/libiberty/Growing-Objects.html#Growing-Objects>.

Also, keep in mind that I/O processing is seldom a program's bottleneck:
the underlying I/O operations (for example disk writes) are orders of
magnitude more expensive. Therefore be sure to profile your program to
establish the need for implementing the more exotic solutions I described.

--
Diomidis Spinellis
Code Quality: The Open Source Perspective (Addison-Wesley 2006)
http://www.spinellis.gr/codequality?clc
Apr 26 '06 #2
ji************@gmail.com wrote:
overview:
function sprintf(<buffername>,<format string>, .....)
in this function you need to allocate the size of buffername before
hand.

question:
function ssprintf(<buffername>,<format string>, .....)
i need to write a funtion in time and space optimized way so that i
should allocate buffername after getting the string.(ignore the time of
mallocing the memory...there is a different strategy for mallocing...it
won't take much time)
i have thought of a strategy:
1. writing the format string to /dev/null or to memory and get the
length of the string and then again malloc(not exactly malloc ....there
is a different optimized strategy) the required string.
problem: a call to printf takes time if the string is long
note:calling string functions like strlen also takes time.
can you suggest me a better optimized strategy.


You can see the Better String Library ( http://bstring.sf.net/ ) for an
implementation of how to do this in the bformat() function. Basically
you leverage the compiler's vsnprintf capabilities as much as possible,
to determine the length and then allocate and output to the result in a
final pass. For compilers that don't have a compliant vsnprintf, they
usually have a variant with which you can do the operation over and
over again for predetermined lengths guessed in a sequence of powers of
2 to zero in on the correct length.

As an alternative, yes, you can use vfprintf, then determine the size
of the output file, however, this assumes you have disk space, write
access, etc and its insanely slow.

Of course an alternative is to get the source for a portable snprintf (
http://www.ijs.si/software/snprintf/ ) and hack on the code to make it
do what you want.

--
Paul Hsieh
http://www.pobox.com/~qed/
http://bstring.sf.net/

Apr 26 '06 #3

In article <e2**********@volcano1.grnet.gr>, Diomidis Spinellis <dd*@aueb.gr> writes:

A portable approach would involve allocating a buffer with a default
large size, and calling snprintf and (your) realloc on it. Snprintf
will return the size of the buffer required for printing the whole
string, so you can always adjust the default size upwards to match that
number, and keep it that way in subsequent calls.


Note this requires an snprintf that conforms to C99 (or another
standard that specifies Chris Torek's New Improved snprintf Return
Semantics [TM]; I think they might have been required by POSIX prior
to 1999). Earlier versions of snprintf were not required to return
the formatted length of the string if the buffer was too small.

I know of three fairly prominent implementations which are broken in
this regard: Compaq C for Tru64, HP C for HP-UX, and most importantly
Microsoft Visual C++ (when using its C implementation, of course). I
suspect the most recent Compaq/HP products have been fixed (because I
believe they now claim C99 compliance), but I believe MSVC is still
broken. (Note that MSVC technically does not supply an snprintf
implementation; they supply something called _snprintf, which is
almost but not quite completely unlike tea. Microsoft's approach to
improving C's string handling has been to invent their own APIs and
then try to force them on everyone else.)

All of these return -1 for any failure, whether its a malformed
format string or a too-short buffer.

Consequently, the portability of any solution involving snprintf has
quite a caveat: it only applies to implementations with conforming
snprintf, and there are notable exceptions.

--
Michael Wojcik mi************@microfocus.com

Aw, shucks. And I was just trying to be rude. -- P.J. Plauger
Apr 28 '06 #4

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

Similar topics

6
by: Marian Aldenhövel | last post by:
Hi, I am using the FMOD audio-library with the pyFMOD python bindings. pyFMOD uses ctypes. It is possible to register callback functions with FMOD that are called at certain points in the...
0
by: yang | last post by:
Deal all: I want to call the funtion of cryptapi (such as cryptaccquirecontext etc) in asp, and if it runat at client, it's ok,but if it run at server in IIS(as the same machine), it return...
3
by: Ye Liu | last post by:
Hi, Folks. If I have table create table t1(col1 number getnumber()) // getnumber is a funtion to generate default value of col1. How I can get this function string by a query on data...
1
by: Jaime Montes | last post by:
I have found that adding in the start of the file the character '-1' and '-2' I can read the file as a Unicode, and to write any character I have to write pairs of character so for 'a' I write '0'...
6
by: | last post by:
Say we have the following code defining TMyMsgHandler and TMyClass typedef void (*TOnMsgReceive) (TMyMessage Msg); class TMyMsgHandler { public: TMyMsgHandler(); virtual ~TMyMsgHandler();...
1
by: Chifo | last post by:
I try to connect postgres database but browser showme a error"Fatal error undefined funtion pg_connect()" somebody can helpme ? i dont know whats means, all conection string its ok this is an...
5
by: Lee Xuzhang | last post by:
/* from SICP -- Exercise 4.21: ((lambda (n) ((lambda (fact) (fact fact n)) (lambda (ft k) (if (= k 1) 1 (* k (ft ft (- k 1))))))) 10) */
6
by: Fazana | last post by:
I was doing one of the question but my program was not working properly. Can anyone help me with it pliz........ Here is the question for the program Question. Part 1. Add the function...
1
by: sridhard2406 | last post by:
Hi All, I am new to c++, please find my program below and my doubt as mentioned below. #include <iostream> using namespace std; class base { public:
2
by: Kemmylinns12 | last post by:
Blockchain technology has emerged as a transformative force in the business world, offering unprecedented opportunities for innovation and efficiency. While initially associated with cryptocurrencies...
0
by: Naresh1 | last post by:
What is WebLogic Admin Training? WebLogic Admin Training is a specialized program designed to equip individuals with the skills and knowledge required to effectively administer and manage Oracle...
0
by: antdb | last post by:
Ⅰ. Advantage of AntDB: hyper-convergence + streaming processing engine In the overall architecture, a new "hyper-convergence" concept was proposed, which integrated multiple engines and...
0
Oralloy
by: Oralloy | last post by:
Hello Folks, I am trying to hook up a CPU which I designed using SystemC to I/O pins on an FPGA. My problem (spelled failure) is with the synthesis of my design into a bitstream, not the C++...
0
by: Carina712 | last post by:
Setting background colors for Excel documents can help to improve the visual appeal of the document and make it easier to read and understand. Background colors can be used to highlight important...
0
by: Rahul1995seven | last post by:
Introduction: In the realm of programming languages, Python has emerged as a powerhouse. With its simplicity, versatility, and robustness, Python has gained popularity among beginners and experts...
2
by: Ricardo de Mila | last post by:
Dear people, good afternoon... I have a form in msAccess with lots of controls and a specific routine must be triggered if the mouse_down event happens in any control. Than I need to discover what...
1
by: Johno34 | last post by:
I have this click event on my form. It speaks to a Datasheet Subform Private Sub Command260_Click() Dim r As DAO.Recordset Set r = Form_frmABCD.Form.RecordsetClone r.MoveFirst Do If...
0
DizelArs
by: DizelArs | last post by:
Hi all) Faced with a problem, element.click() event doesn't work in Safari browser. Tried various tricks like emulating touch event through a function: let clickEvent = new Event('click', {...

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.