How to determine the size of an output buffer

C

Chad

Okay, let's say I have an exotic os that limits how much goes to
stdout. When I go like..

#include <stdio.h>

int main(void) {
int i=0;

for(i=0; i< 10; i++) {
printf("a \n");
}
return 0;
}


I get this....
[cdalten@localhost ~]$ ./out
a
a
a
a
a
a
a
a
a
a

BUT Now, I change the printf() to
printf("a test\n");

Now when I run
#include <stdio.h>

int main(void) {
int i=0;

for(i=0; i< 10; i++) {
printf("a test\n");
}
return 0;
}


I get....

[cdalten@localhost ~]$ ./out
a test
a test
a test
a test
a test

As you can see, only the first few lines get printed out.

Is there anyway I can determine the size of this output buffer without
restorting to trial and error to guess how large the output buffer
might be?

Chad
 
L

Logan Shaw

Chad said:
Okay, let's say I have an exotic os that limits how much goes to
stdout. When I go like..

#include <stdio.h>

int main(void) {

This being cross-posted to comp.lang.c, I'll save the c-l-c people
the trouble: it's not a valid a C program if main has the wrong
number of arguments.

It could be that stdio has a bug, but strictly speaking, if you're
not giving the system a valid C program, it doesn't have to have
correct output.

- Logan
 
D

Dave Vandervies

This being cross-posted to comp.lang.c, I'll save the c-l-c people
the trouble: it's not a valid a C program if main has the wrong
number of arguments.

Uhh... what? That's a perfectly valid set of arguments for main();
one of the two that are specifically described as acceptable, in fact.

It could be that stdio has a bug, but strictly speaking, if you're
not giving the system a valid C program, it doesn't have to have
correct output.

I don't seem to recall the OP claiming that the described behavior was
observed anywhere; he was asking about how to determine the details
given an implementation that *did* act that way.


dave
(stdio output functions are supposed to report failure, aren't they?
Don't forget to flush.)
 
P

Peter Nilsson

Logan Shaw said:
This being cross-posted to comp.lang.c, I'll save the c-l-c people
the trouble: it's not a valid a C program if main has the wrong
number of arguments.

Since clc wouldn't have said that about the OP's code, I'm not sure
what trouble you're saving clc from. The signature for main is not
only valid, but any conforming hosted implementation must support it.

Perhaps you were thinking of void main(void)?
 
P

Peter Nilsson

Okay, let's say I have an exotic os that limits how much goes to
stdout.

Many systems allow stdout to be redirected, and many systems allow
user file limits. So, such a system isn't as exotic as you might
think.
When I go like..

#include <stdio.h>

int main(void) {
int i=0;

for(i=0; i< 10; i++) {
printf("a \n");

Note that implementations are allowed to strip trailing whitespace
from text stream lines. [In other words, behave as if you had
written printf("a\n");]
}
return 0;

}

I get this....
[cdalten@localhost ~]$ ./out
a
a
a
a
a
a
a
a
a
a

BUT Now, I change the printf() to
printf("a test\n");

Now when I run
I get....

[cdalten@localhost ~]$ ./out
a test
a test
a test
a test
a test

As you can see, only the first few lines get printed out.

Is there anyway I can determine the size of this output buffer
without restorting to trial and error to guess how large the
output buffer might be?

No, but you can always check the return value of printf for
error (or ferror) as you can with other output functions.
 
C

Chad

Since clc wouldn't have said that about the OP's code, I'm not sure
what trouble you're saving clc from. The signature for main is not
only valid, but any conforming hosted implementation must support it.

Perhaps you were thinking of void main(void)?

--

Trying not to get to far off topic, here is what happens when I change
int main(void)

to

void main(void)

[cdalten@localhost ~]$ gcc --version
gcc (GCC) 4.1.1 20061011 (Red Hat 4.1.1-30)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There
is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.

[cdalten@localhost ~]$ gcc -Wall out.c -o out
out.c:3: warning: return type of 'main' is not 'int'
out.c: In function 'main':
out.c:9: warning: 'return' with a value, in function returning void
 
J

Jack Klein

Since clc wouldn't have said that about the OP's code, I'm not sure
what trouble you're saving clc from. The signature for main is not
only valid, but any conforming hosted implementation must support it.

Perhaps you were thinking of void main(void)?

--

Trying not to get to far off topic, here is what happens when I change
int main(void)

to

void main(void)

[cdalten@localhost ~]$ gcc --version
gcc (GCC) 4.1.1 20061011 (Red Hat 4.1.1-30)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There
is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.

[cdalten@localhost ~]$ gcc -Wall out.c -o out
out.c:3: warning: return type of 'main' is not 'int'
out.c: In function 'main':
out.c:9: warning: 'return' with a value, in function returning void

No, don't do that. Logan Shaw either had a brain fart or he doesn't
know as much about C as he thinks he does.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
 
L

Logan Shaw

Since clc wouldn't have said that about the OP's code, I'm not sure
what trouble you're saving clc from. The signature for main is not
only valid, but any conforming hosted implementation must support it.

Well, that is embarrassing.

I could've sworn that I was told by somebody at one point that only
the other form was valid. Or maybe I misunderstood someone's statement
at some point in the past.

At any rate, I regret spreading wrong information.

On the other hand, I am glad to have found out the real story, because
I have often found it irritating thinking I had to declare arguments
when actually there was a perfectly legal alternative...

- Logan
 
M

Martin Ambuhl

Logan said:
This being cross-posted to comp.lang.c, I'll save the c-l-c people
the trouble: it's not a valid a C program if main has the wrong
number of arguments.

That's true, but
int main(void) {
has the right number of arguments, being one of the two forms that a
compiler is _required_ to handle properly.
What was your point?
 
B

Bill Pursell

Okay, let's say I have an exotic os that limits how much goes to
stdout.

Be clear about what you're asking. Is this hypothetical
limit the result of a limit imposed on the tty to which
your particular program's stdout is attached? Remember,
stdout is *not* your screen and stdin is *not* your
keyboard. Often, shells will invoke a program so
that stdout is associated with the screen and
stdin is associated with the keyboard, but it
is a horrible thing to ruin your mind by conflating
them.

In other words: on this hypothetical platform, do
you expect the same behavior when you redirect your
output to different file types?
 
C

Chris Uppal

Chad said:
Okay, let's say I have an exotic os that limits how much goes to
stdout. When I go like.. [.;..]
Is there anyway I can determine the size of this output buffer without
restorting to trial and error to guess how large the output buffer
might be?

Since you are supposing an exotic OS, why not also suppose that it has
a sensible API which allows you to discover its operating parameters ?

If your question is really about C stdio buffering, then that has
nothing to do with the OS, and (as far as I remember -- it's years
since I used C stdio in non-trivial ways) you have control over the
buffer sizes used for any stdio stream.

-- chris
 
D

David Mathog

Peter said:
for(i=0; i< 10; i++) {
printf("a \n");

Note that implementations are allowed to strip trailing whitespace
from text stream lines. [In other words, behave as if you had
written printf("a\n");]

I've never heard of that before. If true it's a bit daft, why would
the language make it impossible to reliably generate a line of spaces?
There may be instances where a line of spaces is required, and if this
statement is true, one could not write a standards conforming C program
to produce one. Can somebody please quote chapter and verse from some
standards document to support this assertion?

Regards,

David Mathog
 
C

CBFalconer

David said:
Peter said:
for(i=0; i< 10; i++) {
printf("a \n");

Note that implementations are allowed to strip trailing whitespace
from text stream lines. [In other words, behave as if you had
written printf("a\n");]

I've never heard of that before. If true it's a bit daft, why would
the language make it impossible to reliably generate a line of spaces?
There may be instances where a line of spaces is required, and if this
statement is true, one could not write a standards conforming C program
to produce one. Can somebody please quote chapter and verse from some
standards document to support this assertion?

He isn't. Note the \n in the output. That is only removing spaces
at the end of a line.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>

"A man who is right every time is not likely to do very much."
-- Francis Crick, co-discover of DNA
"There is nothing more amazing than stupidity in action."
-- Thomas Matthews
 
K

Keith Thompson

David Mathog said:
Peter said:
for(i=0; i< 10; i++) {
printf("a \n");
Note that implementations are allowed to strip trailing whitespace
from text stream lines. [In other words, behave as if you had
written printf("a\n");]

I've never heard of that before. If true it's a bit daft, why would
the language make it impossible to reliably generate a line of spaces?
There may be instances where a line of spaces is required, and if this
statement is true, one could not write a standards conforming C program
to produce one. Can somebody please quote chapter and verse from some
standards document to support this assertion?

C99 7.19.2p2:

Whether space characters that are written out immediately before a
new-line character appear when read in is implementation-defined.

I think this is intended to allow for a text file format consisting of
fixed-width records padded with blanks (think about punch cards).
 
D

David Mathog

Keith said:
David Mathog said:
Peter said:
for(i=0; i< 10; i++) {
printf("a \n");
Note that implementations are allowed to strip trailing whitespace
from text stream lines. [In other words, behave as if you had
written printf("a\n");]
I've never heard of that before. If true it's a bit daft, why would
the language make it impossible to reliably generate a line of spaces?
There may be instances where a line of spaces is required, and if this
statement is true, one could not write a standards conforming C program
to produce one. Can somebody please quote chapter and verse from some
standards document to support this assertion?

C99 7.19.2p2:

Whether space characters that are written out immediately before a
new-line character appear when read in is implementation-defined.

I think this is intended to allow for a text file format consisting of
fixed-width records padded with blanks (think about punch cards).

I'm trying to parse that section and it still doesn't make sense to me.
It says "whether space characters that ARE written out immediately
before a new-line character", which to me clearly says that the spaces
must land in the output file. Then it continues "appear when READ IN is
implementation-defined". So according to this C99 doesn't guarantee
that it can read all the characters in a line like

foo(space)(space)\n

and is free to return any of these:

foo(space)(space)\n
foo(space)\n (presumably, the spec doesn't exclude this)
foo\n

This seems even more daft than not writing the spaces out in the
first place! For instance, it means that getc() may return EITHER
(space) or \n following the foo and still be standard compliant??? And
what does this do to fsetpos() or especially fseek()? If an
implementation that drops trailing spaces is fseek'd to the first or
second space, does it return a \n in both cases?

I'm still very confused. What exactly was the reason for this clause
in the standard? I use fixed width text fields all the time and having
the the language nip off the trailing spaces at will would wreck a
heck of a lot of code. For programs which expect a
series of strings of width N, it is common to check that each read
has in fact returned a string of that length, and if not to blow up
as that's a read error, not an acceptable variation induced by the compiler.

Regards,

David Mathog
 
C

Chris Torek

(I dropped comp.programming from the newsgroups line, since this
is not an algorithm question.)

I'm trying to parse [C99 7.19.2p2] and it still doesn't make sense to me.
It says "whether space characters that ARE written out immediately
before a new-line character", which to me clearly says that the spaces
must land in the output file. Then it continues "appear when READ IN is
implementation-defined". So according to this C99 doesn't guarantee
that it can read all the characters in a line like

foo(space)(space)\n

and is free to return any of these:

foo(space)(space)\n
foo(space)\n (presumably, the spec doesn't exclude this)
foo\n

This seems even more daft than not writing the spaces out in the
first place! For instance, it means that getc() may return EITHER
(space) or \n following the foo and still be standard compliant???
Yes.

And what does this do to fsetpos() or especially fseek()?

Nothing in particular. The values from fgetpos() and ftell() are
"magic cookies", so whether spaces appear or disappear is irrelevant:
there need be no correlation between a value you get at the "beginning
of line" and a value you get at "end of line". You cannot (portably)
compute a value to pass to fseek(): you must use one of the values
returned by a previous ftell().
I'm still very confused. What exactly was the reason for this clause
in the standard?

There are file systems that have fixed-length blank-padded records.
If you write:

"foo\n"

to a an IBM-like "FIXED,RECLEN=80" (or however they like to spell
it) file, this actually writes an 80 byte record consisting of the
word "foo" followed by 77 blanks. (If you try to write a 90-character
line, either the last 80 are deleted, or an artificial line break
is inserted to make one 80-character line followed by a second
80-character line: 10 characters plus 70 blanks.)

When you read a FIXED,LREC=80 (or however it is denoted) on one of
these systems, some "friendly" I/O routines tend to remove the
trailing blanks. Since there is no way to distinguish between
"trailing blanks added by the file system" from "trailing blanks
originally written by an application", they just remove *all*
trailing blanks.

If you do not like such behavior, stay away from IBM mainframes. :)
 
D

David Mathog

Chris said:
(I dropped comp.programming from the newsgroups line, since this
is not an algorithm question.)
That's fine with me.

There are file systems that have fixed-length blank-padded records.
If you write:

"foo\n"

to a an IBM-like "FIXED,RECLEN=80" (or however they like to spell
it) file, this actually writes an 80 byte record consisting of the
word "foo" followed by 77 blanks.

Understood. This is to support file types consisting of fixed
length text records that do not support internal EOL characters.
(Ie, implicit EOL at end of the fixed length buffer.)
When you read a FIXED,LREC=80 (or however it is denoted) on one of
these systems, some "friendly" I/O routines tend to remove the
trailing blanks.

Awfully presumptive of the OS to assume the application
doesn't care about trailing spaces. I guess when working in this
environment one could always pad it back out again.
If you do not like such behavior, stay away from IBM mainframes. :)

Will do.

Still, nothing in the quoted section restricted the "drop the trailing
spaces" behavior to such an OS or such a file type. It would be nuts
to do this on a typical stream file, but the quoted section of the
standard does seem to allow it. Or is there some other section of
the standard that says the language must retain trailing spaces
when dealing with variable length or stream records, that is either
counted length records or terminated records?

Regards,

David Mathog
 
K

Keith Thompson

David Mathog said:
Keith Thompson wrote: [...]
C99 7.19.2p2:
Whether space characters that are written out immediately
before a new-line character appear when read in is
implementation-defined.

I think this is intended to allow for a text file format consisting
of fixed-width records padded with blanks (think about punch
cards).

I'm trying to parse that section and it still doesn't make sense to
me. It says "whether space characters that ARE written out immediately
before a new-line character", which to me clearly says that the spaces
must land in the output file. Then it continues "appear when READ IN
is implementation-defined". So according to this C99 doesn't
guarantee that it can read all the characters in a line like

foo(space)(space)\n

and is free to return any of these:

foo(space)(space)\n
foo(space)\n (presumably, the spec doesn't exclude this)
foo\n
Right.

This seems even more daft than not writing the spaces out in the
first place! For instance, it means that getc() may return EITHER
(space) or \n following the foo and still be standard compliant???

Yes. It means that trailing spaces may be ignored on input.

On output, it's not possible to tell whether a printed space is a
trailing space or not until the line is terminated with a new-line.
If you've printed the characters 'f', 'o', 'o', ' ', ' ', the system
doesn't know whether the next character you print will be another
space, a new-line, or some other character. If trailing spaces are
going to be ignored on input, the system has to keep track of spaces
as they're printed. But as soon as you print the new-line, the system
can drop your trailing spaces.

Or, more likely, the output line is always padded with trailing spaces
anyway. On input, the system can't tell whether those trailing spaces
were actually part of your output, or were just system-imposed
padding. The system is allowed to assume that they were
system-imposed padding and ignore them. (If you printed "foo\n", you
wouldn't want to see "foo \n" when you read the file.)
And what does this do to fsetpos() or especially fseek()? If an
implementation that drops trailing spaces is fseek'd to the first or
second space, does it return a \n in both cases?

On a system that ignores trailing spaces on input, you *can't* fseek()
to the first space, at least not using portable code. The input file
(which could have been an output file created by the same program)
will consistently appear to be a text file with no trailing spaces.
Remember that the result of fseek() for a text file doesn't
necessarily have a consistent physical meaning; it needn't be a count
of characters or bytes.
I'm still very confused. What exactly was the reason for this
clause in the standard? I use fixed width text fields all the time
and having the the language nip off the trailing spaces at will
would wreck a heck of a lot of code. For programs which expect a
series of strings of width N, it is common to check that each read
has in fact returned a string of that length, and if not to blow up
as that's a read error, not an acceptable variation induced by the
compiler.

You're not likely to run into a system that actually ignores trailing
spaces. If you do, your code that uses fixed-width text fields might
break, but only if you actually have spaces at the very end of a line.
 
C

Chris Torek

(It has been a while but I meant to reply to this...)

Understood. This is to support file types consisting of fixed
length text records that do not support internal EOL characters.
(Ie, implicit EOL at end of the fixed length buffer.)

Right. (Specifically, these things are "card image" files, on the
theory that you want your on-disk data to look as though it came
directly from a punched-card deck. There is no way to distinguish
between a card column that was "not punched at all" from one that
"was punched but with a blank, which pushes out no chads".)
Awfully presumptive of the OS to assume the application
doesn't care about trailing spaces. I guess when working in this
environment one could always pad it back out again.

Typically either the IO system removes all trailing blanks, so that
the input never has any; or it removes none, so that the input has
some that were never really written. It is not clear which one is
worse.
Still, nothing in the quoted section restricted the "drop the trailing
spaces" behavior to such an OS or such a file type. It would be nuts
to do this on a typical stream file, but the quoted section of the
standard does seem to allow it.

Indeed.

The main problem is that the C standards do not require "stream
files" to exist at all. It might be nice if there were some text
in the standard to suggest that, if at all possible, text files
"ought to" preserve trailing whitespace. (I might also note here
that it was not until VMS version 5, I think, that VMS acquired
"stream-LF" files, which can handle arbitrary text. Earlier versions
would mangle *some* kinds of text files, no matter what you did,
if you pushed the limits too hard. So some of these restrictions
are not just specific to IBM DOS/VS or equivalent. In fact, some
of the binary-file restrictions apply not only to VMS but also
to CP/M and MS-DOS.)
Or is there some other section of the standard that says the
language must retain trailing spaces when dealing with variable
length or stream records, that is either counted length records or
terminated records?

These are just not required at all (even though they usually exist
now).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top