Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   No fread and fwrite for wide characters? (http://www.velocityreviews.com/forums/t805780-no-fread-and-fwrite-for-wide-characters.html)

Lauri Alanko 11-10-2011 05:26 PM

No fread and fwrite for wide characters?
 
It seems that the standard I/O operations for wide characters are
conspicuously lacking functions that read or write an array of
arbitrary wide characters into a stream. E.g. for writing, there's
only fputws, which writes a L'\0'-terminated string, not including the
terminator. So if there's a buffer that may contain L'\0', one has to
iterate it using fputwc, maybe with the assistance of fputws if an
exact count of successfully written characters is not needed.

The workaround is not a big deal, but this seems like a strange
omission, since otherwise there are wide I/O counterparts for all
basic byte I/O operations. Granted, mixing text and null characters is
not very common, but it does happen, e.g. when null characters are
used as field separators.

So does anyone have an idea why "fwwrite" and "fwread" are missing?

Thanks,


Lauri

James Kuyper 11-10-2011 05:34 PM

Re: No fread and fwrite for wide characters?
 
On 11/10/2011 12:26 PM, Lauri Alanko wrote:
> It seems that the standard I/O operations for wide characters are
> conspicuously lacking functions that read or write an array of
> arbitrary wide characters into a stream. E.g. for writing, there's
> only fputws, which writes a L'\0'-terminated string, not including the
> terminator. So if there's a buffer that may contain L'\0', one has to
> iterate it using fputwc, maybe with the assistance of fputws if an
> exact count of successfully written characters is not needed.
>
> The workaround is not a big deal, but this seems like a strange
> omission, since otherwise there are wide I/O counterparts for all
> basic byte I/O operations. Granted, mixing text and null characters is
> not very common, but it does happen, e.g. when null characters are
> used as field separators.
>
> So does anyone have an idea why "fwwrite" and "fwread" are missing?


I'm not sure exactly what behavior you want fwwrite() to have. Here's
how the standard describes fwrite():

> 7.19.8.2 The fwrite function
> Synopsis
> #include <stdio.h>
> size_t fwrite(const void * restrict ptr,
> size_t size, size_t nmemb,
> FILE * restrict stream);
>
> Description
> The fwrite function writes, from the array pointed to by ptr, up to

nmemb elements
> whose size is specified by size, to the stream pointed to by stream. For each object,
> size calls are made to the fputc function, taking the values (in order) from an array of
> unsigned char exactly overlaying the object. The file position indicator for the
> stream (if defined) is advanced by the number of characters successfully written. If an
> error occurs, the resulting value of the file position indicator for the stream is
> indeterminate.
>
> Returns
> The fwrite function returns the number of elements successfully written, which will be
> less than nmemb only if a write error is encountered. If size or nmemb is zero,
> fwrite returns zero and the state of the stream remains unchanged.


Could you modify that description so that it describes what you want for
fwwrite()?

Lauri Alanko 11-10-2011 05:58 PM

Re: No fread and fwrite for wide characters?
 
In article <4EBC0B3D.5040504@verizon.net>,
James Kuyper <jameskuyper@verizon.net> wrote:
> Could you modify that description so that it describes what you want for
> fwwrite()?


Not really, since the "element" concept of fwrite is not applicable to
wide characters (and even in general it's mostly a useless historical
remnant). But I'll do better, and provide a reference implementation:

size_t fwwrite(FILE* file, const wchar_t* wcs, size_t size)
{
for (size_t n = 0; n < size; n++) {
if (fputwc(wcs[n], file) == WEOF) {
return n;
}
}
return size;
}

Not a big deal to write by hand, sure, but the library implementation
could in all likelyhood do the same job more efficiently.


Lauri

James Kuyper 11-10-2011 06:38 PM

Re: No fread and fwrite for wide characters?
 
On 11/10/2011 12:58 PM, Lauri Alanko wrote:
> In article <4EBC0B3D.5040504@verizon.net>,
> James Kuyper <jameskuyper@verizon.net> wrote:
>> Could you modify that description so that it describes what you want for
>> fwwrite()?

>
> Not really, since the "element" concept of fwrite is not applicable to
> wide characters (and even in general it's mostly a useless historical
> remnant).


In most of my fwrite() calls, either the element size is 1 or the number
of elements is one; but for about 10% of my fwrite() calls, the
"element" concept is alive and well.

> ... But I'll do better, and provide a reference implementation:
>
> size_t fwwrite(FILE* file, const wchar_t* wcs, size_t size)
> {
> for (size_t n = 0; n < size; n++) {
> if (fputwc(wcs[n], file) == WEOF) {
> return n;
> }
> }
> return size;
> }


So, this is not at all the wide character equivalent of fwrite(), which
makes more sense, since narrow characters have nothing to do fwrite().
So this really deserves some other name, one which doesn't imply a
non-existent parallel to fwrite().

Which narrow-character function did you consider this to be closest to?
It's similar to fputs(), except for the count, but there's already an
fputws(), which is an exact parallel to fputs().

Lauri Alanko 11-10-2011 11:23 PM

Re: No fread and fwrite for wide characters?
 
In article <4EBC1A22.5090407@verizon.net>,
James Kuyper <jameskuyper@verizon.net> wrote:
> So, this is not at all the wide character equivalent of fwrite(), which
> makes more sense, since narrow characters have nothing to do fwrite().


They certainly do, since as you quoted, fwrite is just a utility for
looping fputc()-calls. "Narrow characters" are bytes, after all.

> Which narrow-character function did you consider this to be closest to?
> It's similar to fputs(), except for the count, but there's already an
> fputws(), which is an exact parallel to fputs().


The problem with fputws is that it cannot be used to output anything
that contains a null wide character. For narrow characters (bytes),
fputs has a similar problem, and that's where fwrite comes handy. So,
again, I'm looking for the X that solves fputs : fwrite :: fputws : X.


Lauri

Harald van Dijk 11-11-2011 05:33 PM

Re: No fread and fwrite for wide characters?
 
On Nov 11, 12:23*am, Lauri Alanko <l...@iki.fi> wrote:
> The problem with fputws is that it cannot be used to output anything
> that contains a null wide character. For narrow characters (bytes),
> fputs has a similar problem, and that's where fwrite comes handy.


Are you trying to write to a text stream or a binary stream? Null
characters are only portably useful for binary streams, but binary
wide-oriented streams are something that, while valid, I've never seen
a real use for before.

Phil Carmody 11-11-2011 10:28 PM

Re: No fread and fwrite for wide characters?
 
Lauri Alanko <la@iki.fi> writes:
> In article <4EBC1A22.5090407@verizon.net>,
> James Kuyper <jameskuyper@verizon.net> wrote:
> > So, this is not at all the wide character equivalent of fwrite(), which
> > makes more sense, since narrow characters have nothing to do fwrite().

>
> They certainly do, since as you quoted, fwrite is just a utility for
> looping fputc()-calls.


What are you gibbering about?

size_t fwrite(const void * restrict ptr,
size_t size, size_t nmemb,
FILE * restrict stream);

There is precisely *nothing* related to the characters one sends to fputc
in that function declaration. End of. Any attempts to counter my argument
are, like *ptr, void.

Phil
--
Unix is simple. It just takes a genius to understand its simplicity
-- Dennis Ritchie (1941-2011), Unix Co-Creator

Ike Naar 11-11-2011 10:58 PM

Re: No fread and fwrite for wide characters?
 
On 2011-11-11, Phil Carmody <thefatphil_demunged@yahoo.co.uk> wrote:
> Lauri Alanko <la@iki.fi> writes:
>> In article <4EBC1A22.5090407@verizon.net>,
>> James Kuyper <jameskuyper@verizon.net> wrote:
>> > So, this is not at all the wide character equivalent of fwrite(), which
>> > makes more sense, since narrow characters have nothing to do fwrite().

>>
>> They certainly do, since as you quoted, fwrite is just a utility for
>> looping fputc()-calls.

>
> What are you gibbering about?
>
> size_t fwrite(const void * restrict ptr,
> size_t size, size_t nmemb,
> FILE * restrict stream);
>
> There is precisely *nothing* related to the characters one sends to fputc
> in that function declaration. End of. Any attempts to counter my argument
> are, like *ptr, void.


7.19.3 p12:
The byte output functions write characters to the stream as if
by successive calls to the fputc function.

fwrite is one of the byte output functions (7.19.1 p5).

James Kuyper 11-11-2011 11:00 PM

Re: No fread and fwrite for wide characters?
 
On 11/11/2011 05:28 PM, Phil Carmody wrote:
> Lauri Alanko <la@iki.fi> writes:
>> In article <4EBC1A22.5090407@verizon.net>,
>> James Kuyper <jameskuyper@verizon.net> wrote:
>>> So, this is not at all the wide character equivalent of fwrite(), which
>>> makes more sense, since narrow characters have nothing to do fwrite().

>>
>> They certainly do, since as you quoted, fwrite is just a utility for
>> looping fputc()-calls.

>
> What are you gibbering about?
>
> size_t fwrite(const void * restrict ptr,
> size_t size, size_t nmemb,
> FILE * restrict stream);
>
> There is precisely *nothing* related to the characters one sends to fputc
> in that function declaration. End of. Any attempts to counter my argument
> are, like *ptr, void.


As I cited earlier in this thread, 7.19.8.2p2 says: "For each object,
size calls are made to the fputc function, taking the values (in order)
from an array of unsigned char exactly overlaying the object."

That sounds a lot like looping over calls to fputc() to me. If you
interpreted "looping fputc() - calls" to mean anything inconsistent with
what 7.19.8.2p2 says, then you've probably misunderstood his intent.

I think that defining his proposed fwwrite() function by the analogy of
fputc():fwrite() :: fputwc():fwwrite() is faulty, but not by reason of
there being no relationship between fputc() and fwrite(). I've failed to
come up with a convincing explanation of what I find objectionable about
it, which is why I've not responded to that message.

Lauri Alanko 11-12-2011 12:09 AM

Re: No fread and fwrite for wide characters?
 
In article <acba8c14-4fb3-4e69-97ce-adf695cc49a1@q16g2000yqn.googlegroups.com>,
Harald van Dijk <truedfx@gmail.com> wrote:
> Are you trying to write to a text stream or a binary stream? Null
> characters are only portably useful for binary streams, but binary
> wide-oriented streams are something that, while valid, I've never seen
> a real use for before.


I don't have an immediate application in mind. I'm writing a
general-purpose library and want to make sure that there are no
corner-cases, so I have to take into consideration even binary
wide-oriented streams, rare as they may be.

But as I mentioned, null characters are commonly used as field
separators, e.g. by "xargs -0" in unix, in order to allow spaces and
newlines within field contents. It's quite conceivable that one might
wish to produce wide characters within these fields, e.g. strings of a
foreign language that xargs would then pass to grep.


Lauri


All times are GMT. The time now is 01:27 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.