Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #78166 > unrolled thread
| Started by | "Morten W. Petersen" <morphex@gmail.com> |
|---|---|
| First post | 2015-12-08 06:18 +0100 |
| Last post | 2015-12-10 08:00 +0100 |
| Articles | 20 on this page of 23 — 9 participants |
Back to article view | Back to comp.lang.c
snprintf alternatives in iso9899 "Morten W. Petersen" <morphex@gmail.com> - 2015-12-08 06:18 +0100
Re: snprintf alternatives in iso9899 Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-12-08 02:13 -0800
Re: snprintf alternatives in iso9899 Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-12-08 10:38 +0000
Re: snprintf alternatives in iso9899 Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-12-08 14:52 +0000
Re: snprintf alternatives in iso9899 supercat@casperkitty.com - 2015-12-08 07:15 -0800
Re: snprintf alternatives in iso9899 Tim Rentsch <txr@alumni.caltech.edu> - 2015-12-09 13:14 -0800
Re: snprintf alternatives in iso9899 Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-12-09 16:28 -0500
Re: snprintf alternatives in iso9899 Ian Collins <ian-news@hotmail.com> - 2015-12-10 10:35 +1300
Re: snprintf alternatives in iso9899 Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-12-09 16:49 -0500
Re: snprintf alternatives in iso9899 Ian Collins <ian-news@hotmail.com> - 2015-12-10 11:00 +1300
Re: snprintf alternatives in iso9899 supercat@casperkitty.com - 2015-12-09 14:02 -0800
Re: snprintf alternatives in iso9899 Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-12-10 02:41 -0800
The FILE * pattern [was Re: snprintf alternatives in iso9899] Richard Heathfield <rjh@cpax.org.uk> - 2015-12-09 22:02 +0000
Re: snprintf alternatives in iso9899 Keith Thompson <kst-u@mib.org> - 2015-12-09 14:49 -0800
Re: snprintf alternatives in iso9899 Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-12-08 16:47 +0000
Re: snprintf alternatives in iso9899 Keith Thompson <kst-u@mib.org> - 2015-12-08 09:18 -0800
Re: snprintf alternatives in iso9899 Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-12-08 17:27 +0000
Re: snprintf alternatives in iso9899 Keith Thompson <kst-u@mib.org> - 2015-12-08 08:41 -0800
Re: snprintf alternatives in iso9899 "Morten W. Petersen" <morphex@gmail.com> - 2015-12-09 02:56 +0100
Re: snprintf alternatives in iso9899 Ian Collins <ian-news@hotmail.com> - 2015-12-09 15:04 +1300
Re: snprintf alternatives in iso9899 Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-12-09 02:16 +0000
Re: snprintf alternatives in iso9899 Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-12-09 04:49 -0800
Re: snprintf alternatives in iso9899 "Morten W. Petersen" <morphex@gmail.com> - 2015-12-10 08:00 +0100
Page 1 of 2 [1] 2 Next page →
| From | "Morten W. Petersen" <morphex@gmail.com> |
|---|---|
| Date | 2015-12-08 06:18 +0100 |
| Subject | snprintf alternatives in iso9899 |
| Message-ID | <n45p5d$hmp$1@speranza.aioe.org> |
Hi there. I'm wondering what the alternatives for snprintf are in ISO 9899, as it looks like C99 is the earliest standard that includes it. What I'm trying to do, is print an ASCII string to the console, and I need to generate the entire string first, before I convert it to for example UTF-8 wide char. In other words, replace the printf things that are already in a program with something that can output Unicode. Any suggestion here? Thanks, Morten
[toc] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2015-12-08 02:13 -0800 |
| Message-ID | <1867ab17-5739-44f2-850d-76f3fc7d28e8@googlegroups.com> |
| In reply to | #78166 |
On Tuesday, December 8, 2015 at 5:17:52 AM UTC, Morten W. Petersen wrote: > Hi there. > > I'm wondering what the alternatives for snprintf are in ISO 9899, as > it looks like C99 is the earliest standard that includes it. > > What I'm trying to do, is print an ASCII string to the console, and > I need to generate the entire string first, before I convert it to > for example UTF-8 wide char. In other words, replace the printf > things that are already in a program with something that can output > Unicode. > snprintf() should work with UTF-8, except that any %c calls will only accept ascii, and you get the number of bytes not the number of characters (which is probably what you want). If you use a wide encoding, I can't find a standard equivalent of wnsprintf(), which is the Microsoft function - I've found that the wide sprints don't support floating point, presumably on the basis that Europeans use a comma as a decimal point, however.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-12-08 10:38 +0000 |
| Message-ID | <87r3ix6x8h.fsf@bsb.me.uk> |
| In reply to | #78171 |
Malcolm McLean <malcolm.mclean5@btinternet.com> writes: > On Tuesday, December 8, 2015 at 5:17:52 AM UTC, Morten W. Petersen wrote: >> Hi there. >> >> I'm wondering what the alternatives for snprintf are in ISO 9899, as >> it looks like C99 is the earliest standard that includes it. >> >> What I'm trying to do, is print an ASCII string to the console, and >> I need to generate the entire string first, before I convert it to >> for example UTF-8 wide char. In other words, replace the printf >> things that are already in a program with something that can output >> Unicode. >> > snprintf() should work with UTF-8, except that any %c calls will only > accept ascii, Not with the l modifier. > and you get the number of bytes not the number of characters > (which is probably what you want). > > If you use a wide encoding, I can't find a standard equivalent of wnsprintf(), > which is the Microsoft function swprintf? > - I've found that the wide sprints don't > support floating point, presumably on the basis that Europeans use a > comma as a decimal point, however. swprintf does floating point correctly on my system. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-12-08 14:52 +0000 |
| Message-ID | <87lh956li9.fsf@bsb.me.uk> |
| In reply to | #78166 |
"Morten W. Petersen" <morphex@gmail.com> writes: > I'm wondering what the alternatives for snprintf are in ISO 9899, as > it looks like C99 is the earliest standard that includes it. snprintf was implemented "in the wild" before standardisation, so some pre-C99 systems had it. You could just assume C90+snprintf. But there are alternatives. Some systems have an allocating printf (for example asprintf) and you can always fprintf to a temp file and then read back only 'n' bytes. > What I'm trying to do, is print an ASCII string to the console, and > I need to generate the entire string first, before I convert it to > for example UTF-8 wide char. I don't follow this at all. When you say "to the console" do you mean "to the standard output stream"? If so, printing ASCII is usually trivial (just use printf). If you mean something else by the console, you'll need to ask in a system-specific group (for example, on a Unix-like system you will probably be advised to use syslog rather than the actual console). And what is UTF-8 wide char? Those two terms are at odds with each other in that UTF-8 is usually an alternative to "wide char" output. > In other words, replace the printf > things that are already in a program with something that can output > Unicode. You can't output Unicode -- you need to output some enconding or Unicode. I know this will sound like a nit-pick answer but I'm trying to find the actual question that is obscured by you use of words. It can't be what you seems to be saying, because if you are printing ASCII, and you are using UTF-8 as the Unicode encoding, then there is no conversion to do. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-12-08 07:15 -0800 |
| Message-ID | <db3c4d4c-60da-4383-808f-573821b7778a@googlegroups.com> |
| In reply to | #78174 |
On Tuesday, December 8, 2015 at 8:52:31 AM UTC-6, Ben Bacarisse wrote: > snprintf was implemented "in the wild" before standardisation, so some > pre-C99 systems had it. You could just assume C90+snprintf. It's too bad there's no standard for a general-purpose printf which takes a pointer to a structure with one or two function pointers and a void*, and uses one of the passed-in functions for output (passing the void* to the function, which can then use it as it sees fit). While there may be some question as to whether it's better to use one function pointer for a function that takes a char, or have separate versions that take individual characters or a pointer+length combo, a general-purpose function could absorb all the functions of sprintf, vprintf, fprintf, etc. plus other system-specific variations; given such an arrangement, things like snprintf could easily be built on top of them. Efficiency would be better if ANSI C had allowed a pointer to one structure type to point to any other with the same initial sequence (saving a level of indirection, since the wrapper function could simply pass one pointer to a structure containing the functions and the information they needed, rather than having to have a single structure type with the pointers and a void* which then had to be indirected to get the necessary info) but such a system would work decently in any event.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2015-12-09 13:14 -0800 |
| Message-ID | <kfnfuzbtjdp.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #78176 |
supercat@casperkitty.com writes: > On Tuesday, December 8, 2015 at 8:52:31 AM UTC-6, Ben Bacarisse wrote: >> snprintf was implemented "in the wild" before standardisation, so some >> pre-C99 systems had it. You could just assume C90+snprintf. > > It's too bad there's no standard for a general-purpose printf > which takes a pointer to a structure with one or two function > pointers and a void*, and uses one of the passed-in functions for > output (passing the void* to the function, which can then use it > as it sees fit). [...] If the lack bothers you, why don't you write one? I did.
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2015-12-09 16:28 -0500 |
| Message-ID | <n4a699$mcv$1@dont-email.me> |
| In reply to | #78296 |
On 12/9/2015 4:14 PM, Tim Rentsch wrote:
> supercat@casperkitty.com writes:
>
>> On Tuesday, December 8, 2015 at 8:52:31 AM UTC-6, Ben Bacarisse wrote:
>>> snprintf was implemented "in the wild" before standardisation, so some
>>> pre-C99 systems had it. You could just assume C90+snprintf.
>>
>> It's too bad there's no standard for a general-purpose printf
>> which takes a pointer to a structure with one or two function
>> pointers and a void*, and uses one of the passed-in functions for
>> output (passing the void* to the function, which can then use it
>> as it sees fit). [...]
>
> If the lack bothers you, why don't you write one? I did.
It seems to me that a more flexible and powerful approach would
be to implement such things at the FILE* level. It's easy to imagine
things along the lines of
FILE *stream = fopen("http://www.c-faq.com/", "r");
... and it wouldn't be a huge departure to offer something like
FILE *funcopen(int (*)reader(void*), int (*)writer(void*),
void *userarg);
FILE *stream = funcopen(NULL, mywriter, buffptr);
Something in this vein would be, I think, superior to running around
endlessly adding capabilities to printf(), scanf(), fseek(), ...
--
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2015-12-10 10:35 +1300 |
| Message-ID | <dcrl4dFo5q0U3@mid.individual.net> |
| In reply to | #78298 |
Eric Sosman wrote:
> On 12/9/2015 4:14 PM, Tim Rentsch wrote:
>> supercat@casperkitty.com writes:
>>
>>> On Tuesday, December 8, 2015 at 8:52:31 AM UTC-6, Ben Bacarisse wrote:
>>>> snprintf was implemented "in the wild" before standardisation, so some
>>>> pre-C99 systems had it. You could just assume C90+snprintf.
>>>
>>> It's too bad there's no standard for a general-purpose printf
>>> which takes a pointer to a structure with one or two function
>>> pointers and a void*, and uses one of the passed-in functions for
>>> output (passing the void* to the function, which can then use it
>>> as it sees fit). [...]
>>
>> If the lack bothers you, why don't you write one? I did.
>
> It seems to me that a more flexible and powerful approach would
> be to implement such things at the FILE* level. It's easy to imagine
> things along the lines of
>
> FILE *stream = fopen("http://www.c-faq.com/", "r");
>
> ... and it wouldn't be a huge departure to offer something like
>
> FILE *funcopen(int (*)reader(void*), int (*)writer(void*),
> void *userarg);
> FILE *stream = funcopen(NULL, mywriter, buffptr);
>
> Something in this vein would be, I think, superior to running around
> endlessly adding capabilities to printf(), scanf(), fseek(), ...
This is similar in spirit to the C++ approach of associating a stream
buffer object with a stream. Both provide a convenient decoupling
between the internal and external representation of data as well as the
external source.
--
Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2015-12-09 16:49 -0500 |
| Message-ID | <n4a7fv$reb$1@dont-email.me> |
| In reply to | #78300 |
On 12/9/2015 4:35 PM, Ian Collins wrote:
> Eric Sosman wrote:
>> On 12/9/2015 4:14 PM, Tim Rentsch wrote:
>>> supercat@casperkitty.com writes:
>>>
>>>> On Tuesday, December 8, 2015 at 8:52:31 AM UTC-6, Ben Bacarisse wrote:
>>>>> snprintf was implemented "in the wild" before standardisation, so some
>>>>> pre-C99 systems had it. You could just assume C90+snprintf.
>>>>
>>>> It's too bad there's no standard for a general-purpose printf
>>>> which takes a pointer to a structure with one or two function
>>>> pointers and a void*, and uses one of the passed-in functions for
>>>> output (passing the void* to the function, which can then use it
>>>> as it sees fit). [...]
>>>
>>> If the lack bothers you, why don't you write one? I did.
>>
>> It seems to me that a more flexible and powerful approach would
>> be to implement such things at the FILE* level. It's easy to imagine
>> things along the lines of
>>
>> FILE *stream = fopen("http://www.c-faq.com/", "r");
>>
>> ... and it wouldn't be a huge departure to offer something like
>>
>> FILE *funcopen(int (*)reader(void*), int (*)writer(void*),
>> void *userarg);
>> FILE *stream = funcopen(NULL, mywriter, buffptr);
>>
>> Something in this vein would be, I think, superior to running around
>> endlessly adding capabilities to printf(), scanf(), fseek(), ...
>
> This is similar in spirit to the C++ approach of associating a stream
> buffer object with a stream. Both provide a convenient decoupling
> between the internal and external representation of data as well as the
> external source.
If it's "similar to C++", I withdraw the suggestion. C++, ick! ;)
*I* thought I was following Unix style, where all manner of non-I/O
things have file-ish interfaces: /dev/null, /dev/random, /proc, ...
These interfaces make it possible to employ all existing file-using
tools on the non-file thingummies, at a stroke and without (much)
additional effort. I've always thought the FILE* abstraction could be
used in much the same way.
--
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2015-12-10 11:00 +1300 |
| Message-ID | <dcrmk7Fo5q0U4@mid.individual.net> |
| In reply to | #78303 |
Eric Sosman wrote:
> On 12/9/2015 4:35 PM, Ian Collins wrote:
>> Eric Sosman wrote:
>>>
>>> It seems to me that a more flexible and powerful approach would
>>> be to implement such things at the FILE* level. It's easy to imagine
>>> things along the lines of
>>>
>>> FILE *stream = fopen("http://www.c-faq.com/", "r");
>>>
>>> ... and it wouldn't be a huge departure to offer something like
>>>
>>> FILE *funcopen(int (*)reader(void*), int (*)writer(void*),
>>> void *userarg);
>>> FILE *stream = funcopen(NULL, mywriter, buffptr);
>>>
>>> Something in this vein would be, I think, superior to running around
>>> endlessly adding capabilities to printf(), scanf(), fseek(), ...
>>
>> This is similar in spirit to the C++ approach of associating a stream
>> buffer object with a stream. Both provide a convenient decoupling
>> between the internal and external representation of data as well as the
>> external source.
>
> If it's "similar to C++", I withdraw the suggestion. C++, ick! ;)
:)
> *I* thought I was following Unix style, where all manner of non-I/O
> things have file-ish interfaces: /dev/null, /dev/random, /proc, ...
> These interfaces make it possible to employ all existing file-using
> tools on the non-file thingummies, at a stroke and without (much)
> additional effort. I've always thought the FILE* abstraction could be
> used in much the same way.
C++ is following Unix style! In C++, iostreams handle the formatting of
data for I/O and the stream buffer associated with the stream handles
the low level raw I/O. Thus in C++ you can employ standard I/O on the
non-file thingummies.
--
Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-12-09 14:02 -0800 |
| Message-ID | <6c720a4b-e763-421d-8c56-655337aafbb7@googlegroups.com> |
| In reply to | #78298 |
On Wednesday, December 9, 2015 at 3:28:44 PM UTC-6, Eric Sosman wrote: > It seems to me that a more flexible and powerful approach would > be to implement such things at the FILE* level. It's easy to imagine > things along the lines of The difficulty with that is that the C Standard regards FILE as an opaque type. While many implementations provide means of creating a FILE object with callback functions, they all do so differently. I would propose a single type which would behave like an output file, but have a defined format to allow application code to extend its capabilities in a standard way.
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2015-12-10 02:41 -0800 |
| Message-ID | <88ab070f-1825-41e0-8fe1-7b103c23c6a9@googlegroups.com> |
| In reply to | #78305 |
On Wednesday, December 9, 2015 at 10:02:26 PM UTC, supe...@casperkitty.com wrote:
> On Wednesday, December 9, 2015 at 3:28:44 PM UTC-6, Eric Sosman wrote:
> > It seems to me that a more flexible and powerful approach would
> > be to implement such things at the FILE* level. It's easy to imagine
> > things along the lines of
>
> The difficulty with that is that the C Standard regards FILE as an opaque
> type. While many implementations provide means of creating a FILE object
> with callback functions, they all do so differently. I would propose a
> single type which would behave like an output file, but have a defined
> format to allow application code to extend its capabilities in a standard
> way.
/*
Create a user FILE object
putch - function for writing character to stream (can be null)
getch - function fro reading character from stream (can be null)
close - function to destroy user context
userpointer - context pointer for callbacks
*/
FILE *userfp( int (*putch)(int ch, void *ptr), int (*getch)(void *ptr), void (*close)(void *ptr),
void *userpointer);
However you're adding a check to every stdio call if you add this function.
[toc] | [prev] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2015-12-09 22:02 +0000 |
| Subject | The FILE * pattern [was Re: snprintf alternatives in iso9899] |
| Message-ID | <n4a89b$ut7$1@dont-email.me> |
| In reply to | #78298 |
[Tangent!] On 09/12/15 21:28, Eric Sosman wrote: <snip> > It seems to me that a more flexible and powerful approach would > be to implement such things at the FILE* level. In general, the FILE * interface for streams makes a good general pattern for resource management (although I would have preferred for fclose to take FILE **, such that after fclose(&fp) fp would have a null pointer value). The pattern can be adapted for all kinds of things. For example: canvas *canvas_create(size_t width, size_t height, int bgcol); canvas *canvas_load(const char *filename, int type); int canvas_setpixel(canvas *c, size_t x, size_t y, unsigned long colour); int canvas_setpixelrgb(canvas *c, size_t x, size_t y, int r, int g, int b); int canvas_linedraw(canvas *c, size_t left, size_t top, size_t right, size_t bottom); /* etc */ void canvas_destroy(canvas **pc); This method can be adapted to use constructors, iterators, and destructors (C style, not C++ style!), and works well with opaque types. -- Richard Heathfield Email: rjh at cpax dot org dot uk "Usenet is a strange place" - dmr 29 July 1999 Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-12-09 14:49 -0800 |
| Message-ID | <ln37vbkzkw.fsf@kst-u.example.com> |
| In reply to | #78298 |
Eric Sosman <esosman@comcast-dot-net.invalid> writes:
> On 12/9/2015 4:14 PM, Tim Rentsch wrote:
>> supercat@casperkitty.com writes:
>>
>>> On Tuesday, December 8, 2015 at 8:52:31 AM UTC-6, Ben Bacarisse wrote:
>>>> snprintf was implemented "in the wild" before standardisation, so some
>>>> pre-C99 systems had it. You could just assume C90+snprintf.
>>>
>>> It's too bad there's no standard for a general-purpose printf
>>> which takes a pointer to a structure with one or two function
>>> pointers and a void*, and uses one of the passed-in functions for
>>> output (passing the void* to the function, which can then use it
>>> as it sees fit). [...]
>>
>> If the lack bothers you, why don't you write one? I did.
>
> It seems to me that a more flexible and powerful approach would
> be to implement such things at the FILE* level. It's easy to imagine
> things along the lines of
>
> FILE *stream = fopen("http://www.c-faq.com/", "r");
The string "http://www.c-faq.com/" could *also* be a valid local file
name. On a POSIX system, there could be a directory named "http:" with
a subdirectory name "www.c-faq.com". The trailing "/" means that the
whole thing refers to a directory, but "http://www.c-faq.com/index.html"
could be an ordinary file.
You could set up a "/url" directory, for example, so a file name like
"/url/http://www.c-faq.com/" would unambiguously refer to that URL.
I haven't heard of anyone actually doing that. The POSIX popen()
function, along with a command like "curl", can do pretty much the same
thing.
One issue is that the things URLs refer to only partially act like
files.
> ... and it wouldn't be a huge departure to offer something like
>
> FILE *funcopen(int (*)reader(void*), int (*)writer(void*),
> void *userarg);
> FILE *stream = funcopen(NULL, mywriter, buffptr);
>
> Something in this vein would be, I think, superior to running around
> endlessly adding capabilities to printf(), scanf(), fseek(), ...
There's the GNU-specific fopencookie().
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-12-08 16:47 +0000 |
| Message-ID | <87fuzc7uq3.fsf@bsb.me.uk> |
| In reply to | #78174 |
ram@zedat.fu-berlin.de (Stefan Ram) writes: > Ben Bacarisse <ben.usenet@bsb.me.uk> writes: >>But there are alternatives. Some systems have an allocating printf (for >>example asprintf) and you can always fprintf to a temp file and then >>read back only 'n' bytes. > > I have published the source code for an allocating printf here: > > www.purl.org/stefan_ram/pub/c_faq_de > > (in case of a 403 HTTP error, one can try a Google referrer). > > The function is called »salfmt«. An example client: Did you ever show it to a compiler? There's no way that code got through one! (Note that since it's just a wrapper around vsnprintf, it won't help Morten.) <snip> -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-12-08 09:18 -0800 |
| Message-ID | <lnegewoo3n.fsf@kst-u.example.com> |
| In reply to | #78181 |
ram@zedat.fu-berlin.de (Stefan Ram) writes:
> Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
>>Did you ever show it to a compiler? There's no way that code got
>
> The last version of salfmt was not tested, indeed.
> (I think, after I inserted »va_copy«, I did not
> test again.)
>
> But previous versions were tested, and I hope to
> find the time to one day maintain that page again.
>
> If you refer to a specific location in the code,
> feel free to point out where you see the problem.
www.purl.org/stefan_ram/pub/c_faq_de
I haven't tried compiling it myself, but a couple of things jump out.
s_type salfmt( s_type const f, ... )
{ va_list a;
char * b = 0;
va_copy(a,f); { int const s = vsnprintf( 0, 0, f, a ); va_end(a); }
if( s >= 0 )
{ size_t const k = 1 + s; if( b = malloc( k ))
{ va_start(a,f); { vsprintf( b, f, a ); va_end(a); }}}
return b; }
The code layout makes it difficult to read.
s_type is a typedef for char*. (IMHO the code would be much easier to
read if it used char* directly.)
You call va_copy with an argument of type char*. That might happen to
compile depending on how va_list is defined, but it's clearly wrong.
You define `s` inside a block and then refer to it outside the block.
(Personally I wouldn't publish code on a web page without at least
compiling it first.)
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-12-08 17:27 +0000 |
| Message-ID | <874mfs7svt.fsf@bsb.me.uk> |
| In reply to | #78181 |
ram@zedat.fu-berlin.de (Stefan Ram) writes: > Ben Bacarisse <ben.usenet@bsb.me.uk> writes: >>Did you ever show it to a compiler? There's no way that code got > > The last version of salfmt was not tested, indeed. > (I think, after I inserted »va_copy«, I did not > test again.) > > But previous versions were tested, and I hope to > find the time to one day maintain that page again. > > If you refer to a specific location in the code, > feel free to point out where you see the problem. I couldn't see the problem. I'm usually good at that, but I find your layout almost unreadable. gcc spotted the two main problems but I can now fill in some details. The va_copy is wrong in various ways: the second argument must be a va_list, you need to call va_start in order to have something to copy, and you need a separate va_list to copy into. I'm sure, though, that you need va_copy at all. There is also an unused int (s) and an undeclared name (s) which are obviously intended to be the same thing. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-12-08 08:41 -0800 |
| Message-ID | <lnio48optn.fsf@kst-u.example.com> |
| In reply to | #78166 |
"Morten W. Petersen" <morphex@gmail.com> writes:
> I'm wondering what the alternatives for snprintf are in ISO 9899, as
> it looks like C99 is the earliest standard that includes it.
ISO 9899 is the C standard. The current edition was published in 2011.
That edition supersedes the 1990 and 1999 editions.
I think you meant to ask about C90.
> What I'm trying to do, is print an ASCII string to the console, and
> I need to generate the entire string first, before I convert it to
> for example UTF-8 wide char. In other words, replace the printf
> things that are already in a program with something that can output
> Unicode.
C90 didn't have snprintf; that's why it was added to the language
in 1999. If you need to use snprintf, you can probably just go
ahead and use it. Most C implementations provide it, even if they
don't fully support C99.
If you can't use snprintf, you might be able to compute a maximum
size for the target array. sprintf doesn't check for a buffer
overrun but you can get away without that check if you're *very*
careful.
But I think you're a bit confused about UTF-8. There's no such
thing as a "UTF-8 wide char". UTF-8 is a representation of
Unicode that uses one to four octets for each Unicode code point.
ASCII is a 7-bit character set, usually represented using one
octet per character. ASCII text *is* UTF-8 text (that was a major
requirement for the design of UTF-8). If you have an ASCII string
that you want to print to the console, just print it.
You'll need to be more specific about what you're trying to do.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | "Morten W. Petersen" <morphex@gmail.com> |
|---|---|
| Date | 2015-12-09 02:56 +0100 |
| Message-ID | <n481m1$lpf$1@speranza.aioe.org> |
| In reply to | #78179 |
On 08.12.2015 17:41, Keith Thompson wrote: > "Morten W. Petersen" <morphex@gmail.com> writes: >> I'm wondering what the alternatives for snprintf are in ISO 9899, as >> it looks like C99 is the earliest standard that includes it. > > ISO 9899 is the C standard. The current edition was published in 2011. > That edition supersedes the 1990 and 1999 editions. > > I think you meant to ask about C90. > >> What I'm trying to do, is print an ASCII string to the console, and >> I need to generate the entire string first, before I convert it to >> for example UTF-8 wide char. In other words, replace the printf >> things that are already in a program with something that can output >> Unicode. > > C90 didn't have snprintf; that's why it was added to the language > in 1999. If you need to use snprintf, you can probably just go > ahead and use it. Most C implementations provide it, even if they > don't fully support C99. > > If you can't use snprintf, you might be able to compute a maximum > size for the target array. sprintf doesn't check for a buffer > overrun but you can get away without that check if you're *very* > careful. > > But I think you're a bit confused about UTF-8. There's no such > thing as a "UTF-8 wide char". UTF-8 is a representation of > Unicode that uses one to four octets for each Unicode code point. > ASCII is a 7-bit character set, usually represented using one > octet per character. ASCII text *is* UTF-8 text (that was a major > requirement for the design of UTF-8). If you have an ASCII string > that you want to print to the console, just print it. > > You'll need to be more specific about what you're trying to do. Ah yes. Well I want to output the parsed XML on stdout, to aid in the development and debugging process. I have been a bit confused by this whole console/stdout/encoding/ character type thing yes, and my thought initially was that it was better to use the same function to output all kinds of strings, and that converting something that is only ASCII characters to a wide char and then printing it was better than mixing the (C) types of characters that are sent to stdout. Have I understood it correctly when I say that to output what is UTF-32 internally, I need to break down each 32-bit character to a sequence of 1-4 regular char and send those to stdout using for example putc, if the encoding used in stdout is UTF-8? I guess this printing function will be used to output XML to files as well, so might just as well do it properly. -Morten
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2015-12-09 15:04 +1300 |
| Message-ID | <dcpgguFo5q0U2@mid.individual.net> |
| In reply to | #78212 |
Morten W. Petersen wrote: > > Ah yes. Well I want to output the parsed XML on stdout, to aid > in the development and debugging process. > > I have been a bit confused by this whole console/stdout/encoding/ > character type thing yes, and my thought initially was that it was > better to use the same function to output all kinds of strings, and > that converting something that is only ASCII characters to a wide char > and then printing it was better than mixing the (C) types of characters > that are sent to stdout. > > Have I understood it correctly when I say that to output what is UTF-32 > internally, I need to break down each 32-bit character to a sequence > of 1-4 regular char and send those to stdout using for example putc, > if the encoding used in stdout is UTF-8? I guess that's what c32rtomb() is there for... -- Ian Collins
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.c
csiph-web