473,595 Members | 2,442 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Proper fgets

Hey everyone,

Taken the following code; is there a "proper" or dynamic way to
allocate the length of line[]?

#include <stdio.h>
#include <errno.h>

int main(int argc, char **argv) {
FILE *fp;
char line[4096];

if(argc < 2) {
printf("usage: %s <file>\n", argv[0]);
return(1);
}

if((fp = fopen(argv[1], "r")) == NULL) {
perror("fopen") ;
return(1);
}

while(fgets(lin e, sizeof(line), fp)) {
printf("%s", line);
}

return(0);
}

Mar 12 '07 #1
9 3414
On Mar 12, 10:22 am, "uidzer0" <ben.lemasur... @gmail.comwrote :
Hey everyone,

Taken the following code; is there a "proper" or dynamic way to
allocate the length of line[]?

#include <stdio.h>
#include <errno.h>

int main(int argc, char **argv) {
FILE *fp;
char line[4096];

if(argc < 2) {
printf("usage: %s <file>\n", argv[0]);
return(1);
}

if((fp = fopen(argv[1], "r")) == NULL) {
perror("fopen") ;
return(1);
}

while(fgets(lin e, sizeof(line), fp)) {
printf("%s", line);
}

return(0);

}- Hide quoted text -

- Show quoted text -
Do a web search for getline

Mar 12 '07 #2
That's perfect, however, it appears to be a GNU extension. Is there a
ANSI C way to do this?

Thanks again,

Ben

On Mar 12, 12:44 pm, "user923005 " <dcor...@connx. comwrote:
On Mar 12, 10:22 am, "uidzer0" <ben.lemasur... @gmail.comwrote :
Hey everyone,
Taken the following code; is there a "proper" or dynamic way to
allocate the length of line[]?
#include <stdio.h>
#include <errno.h>
int main(int argc, char **argv) {
FILE *fp;
char line[4096];
if(argc < 2) {
printf("usage: %s <file>\n", argv[0]);
return(1);
}
if((fp = fopen(argv[1], "r")) == NULL) {
perror("fopen") ;
return(1);
}
while(fgets(lin e, sizeof(line), fp)) {
printf("%s", line);
}
return(0);
}- Hide quoted text -
- Show quoted text -

Do a web search for getline

Mar 12 '07 #3
uidzer0 wrote:
Hey everyone,

Taken the following code; is there a "proper" or dynamic way to
allocate the length of line[]?

#include <stdio.h>
#include <errno.h>

int main(int argc, char **argv) {
FILE *fp;
char line[4096];

if(argc < 2) {
printf("usage: %s <file>\n", argv[0]);
argv[0] need not point to the program's invocation name. Some
environments do not provide this information.
return(1);
This is a non-portable return values. The portable ones are 0 and
EXIT_SUCCESS to indicate success and EXIT_FAILURE to indicate abnormal
termination. For both the macros, stdlib.h must be included.
}

if((fp = fopen(argv[1], "r")) == NULL) {
perror("fopen") ;
fopen is not guaranteed to set errno. It's a quality-of-implementation
issue.
return(1);
}

while(fgets(lin e, sizeof(line), fp)) {
printf("%s", line);
You should include a newline to immediately flush the output to the
connected device.
}

return(0);
Parenthesis not necessary.
}
Now coming to your main question, yes, the most portable method to do
what you want is to use malloc to allocate an array which you can
resize, with realloc, on the fly, as you read in more input.
CBFalconer often posts the sources for his 'ggets' function to do
exactly what you want.

<http://cbfalconer.home .att.net/download/ggets.zip>

Note: C99 has also introduced Variable Length Arrays, (VLA), which can
do what you want in a syntactically clean form, but this is poorly
implemented by most compilers and has a serious problem in that an
allocation failure leads to undefined behaviour, with no way of
detection.

Mar 12 '07 #4
On Mar 12, 12:52 pm, "santosh" <santosh....@gm ail.comwrote:
uidzer0 wrote:
Hey everyone,
Taken the following code; is there a "proper" or dynamic way to
allocate the length of line[]?
#include <stdio.h>
#include <errno.h>
int main(int argc, char **argv) {
FILE *fp;
char line[4096];
if(argc < 2) {
printf("usage: %s <file>\n", argv[0]);

argv[0] need not point to the program's invocation name. Some
environments do not provide this information.
return(1);

This is a non-portable return values. The portable ones are 0 and
EXIT_SUCCESS to indicate success and EXIT_FAILURE to indicate abnormal
termination. For both the macros, stdlib.h must be included.
}
if((fp = fopen(argv[1], "r")) == NULL) {
perror("fopen") ;

fopen is not guaranteed to set errno. It's a quality-of-implementation
issue.
return(1);
}
while(fgets(lin e, sizeof(line), fp)) {
printf("%s", line);

You should include a newline to immediately flush the output to the
connected device.
}
return(0);

Parenthesis not necessary.
}

Now coming to your main question, yes, the most portable method to do
what you want is to use malloc to allocate an array which you can
resize, with realloc, on the fly, as you read in more input.
CBFalconer often posts the sources for his 'ggets' function to do
exactly what you want.

<http://cbfalconer.home .att.net/download/ggets.zip>

Note: C99 has also introduced Variable Length Arrays, (VLA), which can
do what you want in a syntactically clean form, but this is poorly
implemented by most compilers and has a serious problem in that an
allocation failure leads to undefined behaviour, with no way of
detection.
Perfect, thanks.

Mar 12 '07 #5
uidzer0 wrote:
Hey everyone,

Taken the following code; is there a "proper" or dynamic way to
allocate the length of line[]?

#include <stdio.h>
#include <errno.h>

int main(int argc, char **argv) {
FILE *fp;
char line[4096];

if(argc < 2) {
printf("usage: %s <file>\n", argv[0]);
return(1);
}

if((fp = fopen(argv[1], "r")) == NULL) {
perror("fopen") ;
return(1);
}

while(fgets(lin e, sizeof(line), fp)) {
printf("%s", line);
}

return(0);
}
The allocation looks fine as it stands, since the program
works even if line[] holds just a fragment of a line instead
of an entire line. The code could be improved in a number of
small ways, but there's nothing irretrievably wrong with it.

--
Eric Sosman
es*****@acm-dot-org.invalid
Mar 12 '07 #6
On 12 Mar 2007 10:51:14 -0700, in comp.lang.c , "uidzer0"
<be************ @gmail.comwrote :
>That's perfect, however, it appears to be a GNU extension. Is there a
ANSI C way to do this?
Look at the source for getline() ?
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Mar 12 '07 #7
uidzer0 wrote:
>
Taken the following code; is there a "proper" or dynamic way to
allocate the length of line[]?
.... snip code ...

Yes. One example can be found in the ggets package, found at:

<http://cbfalconer.home .att.net/download/>

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home .att.net>

--
Posted via a free Usenet account from http://www.teranews.com

Mar 12 '07 #8
On Mar 13, 6:52 am, "santosh" <santosh....@gm ail.comwrote:
uidzer0 wrote:
Taken the following code; is there a "proper" or dynamic way to
allocate the length of line[]?

while(fgets(lin e, sizeof(line), fp)) {
printf("%s", line);

Now coming to your main question, yes, the most portable method to do
what you want is to use malloc to allocate an array which you can
resize, with realloc, on the fly, as you read in more input.

Note: C99 has also introduced Variable Length Arrays, (VLA), which can
do what you want in a syntactically clean form
I don't see how VLA can be used to solve this problem. The VLA
must be declared with a size, which cannot be altered subsequently.

Mar 12 '07 #9
>uidzer0 wrote:
[edited slightly, and trimmed heavily]
> while(fgets(lin e, sizeof(line), fp))
printf("%s", line);
In article <11************ *********@n33g2 000cwc.googlegr oups.com>,
santosh <sa*********@gm ail.comwrote:
>You should include a newline to immediately flush the output to the
connected device.
Actually, in this case, there *is* an included newline (usually):
it is in the string stored in "line". Remember that fgets()
keeps the newline at the end of the input line. There are only
two cases in which the newline is omitted:

1) The input line was so long that it had to be split. The
fgets() function writes the initial part of the input
line into the array ("line", in this case), and leaves
the remaining part of the input line in the input stream.[%]
Subsequent fgets() calls will read and consume more of
that line, up to and including the newline that terminates
it. Those partial-and-eventually-complete lines (including
the single terminating newline) will be passed to the
printf() call, so the output will re-construct the original
input.

2) The input file ended without a terminating newline, and the
underlying implementation chooses to handle such files by
reporting the final line without a terminating newline. In
this case, the next fgets() call will return NULL, with the
reason for failure being "reached end of file" (i.e., this
will set feof(fp)). In this case, it is usually probably best
to output an unterminated text line, so as to mimic the input.
There is no guarantee that the implementation will be able
to produce that output line (perhaps the input file is
coming from a file system that supports partial final lines,
while the output file is being written on one that does
not), but unless you have something specific in mind, adding
a newline terminator (to make the output "valid") is, at the
least, changing the input. :-)

So in this *particular* case -- reading an input file and copying
it to the standard output -- using printf with "%s" and no newline
is probably right. (Or, equivalently, one can use fputs(line,stdo ut)
in the loop body. The fputs() and puts() functions have the same
newline relationship, in this case, as the fgets() and gets()
functions: the old, less-thought-out, less-usable[$] gets() and
puts() fiddle with the data, while the newer, more-thought-out
fgets() and fputs() functions leave it unchanged, as much as
possible. In less precise, but more memorable, words, "gets and
puts delete and add a newline respectively; fgets and fputs do
not.")

-----
[%] This assumes the implementation is actually capable of handling
very long lines. Text files, on some systems, have line length
restrictions. If the line[] array has size 4096, but the
underlying system never has lines longer than 1023 characters,
there can never be a line long enough to split. In some
particularly old and klunky systems, it is even possible that
the input file might have lines longer than the input methods
can handle, in which case overlong input lines might be truncated
before the C system ever really "sees" them. In both cases, the
C compiler is effectively hobbled by the system. There is no
portable way around this problem, though, so one might as well
ignore it, in general. (In specific cases, one might be able
to open the text file as a "binary" file and decode the "true
intent" from the raw record-data. If the raw data is encoded
-- e.g., some form of ISAM or VSAM -- doing this can be rather
complex.)

[$] In the case of gets(), "nearly unusable". While its newline
removal is sometimes handy, you can only use it safely if you
can somehow verify the input data before reading it. On some
systems you could do a pre-scan of the entire file, with the
file somehow locked against changes, but this is nonportable
and, if not a bad idea for other reasons, at the least, I would
call it "icky". :-) One might as well just use fgets(), or
code similar to Chuck Falconer's ggets(), or some such.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Mar 13 '07 #10

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

Similar topics

6
12396
by: Tanel | last post by:
Hello, I need to read a result of the first script (that takes some time to run) from the second script so that the first script doesn't block the second. Here is a short example. do_smth_else() should be called during test.php's sleep, instead the first fgets blocks the processing of the parent script and do_smth_else is called only once. How can I do a non-blocking fgets()? I use php 4.3.4 on windows xp $process = popen("c:\php\php...
5
7231
by: Rob Somers | last post by:
Hey all I am writing a program to keep track of expenses and so on - it is not a school project, I am learning C as a hobby - At any rate, I am new to structs and reading and writing to files, two aspects which I want to incorporate into my program eventually. That aside, my most pressing problem right now is how to get rid of the newline in the input when I use fgets(). Now I have looked around on the net, not so much in this group...
20
7887
by: TTroy | last post by:
Hello, I have found some peculiar behaviour in the fgets runtime library function for my compiler/OS/platform (Dev C++/XP/P4) - making a C console program (which runs in a CMD.exe shell). The standard says about fgets: synopsis #include <stdio.h> char *fgets(char *s, int n, FILE *stream);
35
9945
by: David Mathog | last post by:
Every so often one of my fgets() based programs encounters an input file containing embedded nulls. fgets is happy to read these but the embedded nulls subsequently cause problems elsewhere in the program. Since fgets() doesn't return the number of characters read it is pretty tough to handle the embedded nulls once they are in the buffer. So two questions: 1. Why did the folks who wrote fgets() have a successful
17
3487
by: Lefty Bigfoot | last post by:
Hello, I am aware that a lot of people are wary of using scanf, because doing it improperly can be dangerous. I have tried to find a good tutorial on all the ins and outs of scanf() but been unsuccessful. Is there a well-respected (by the c.l.c crowd) book or tutorial that really covers scanf in detail?
11
3655
by: santosh | last post by:
Hi, A book that I'm currently using notes that the fgets() function does not return until Return is pressed or an EOF or other error is encountered. It then at most (in the absence of EOF/error), returns n-1 characters plus a appended null character.
48
2228
by: Michel Rouzic | last post by:
I know it must sound like a newbie question, but I never really had to bother with that before, and I didn't even find an answer in the c.l.c FAQ I'd like to know what's the really proper way for input a string in an array of char that's dynamically allocated. I mean, I wish not to see any such things as char mystring; I don't want to see any number (if possible) I just want to declare something like char *mystring; and then I don't...
32
3864
by: FireHead | last post by:
Hello C World & Fanatics I am trying replace fgets and provide a equavivalant function of BufferedInputReader::readLine. I am calling this readLine function as get_Stream. In the line 4 where default_buffer_length is changed from 4 --24 code works fine. But on the same line if I change the value of default_buffer_length from 4 --10 and I get a memory error. And if the change the value of the same variable from 4 --1024 bytes;
285
8761
by: Sheth Raxit | last post by:
Machine 1 : bash-3.00$ uname -a SunOS <hostname5.10 Generic_118822-30 sun4u sparc SUNW,Sun-Fire-280R bash-3.00$ gcc -v Reading specs from /usr/local/lib/gcc-lib/sparc-sun-solaris2.8/2.95.3/ specs gcc version 2.95.3 20010315 (release)
0
8262
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
8379
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8020
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8252
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...
1
5839
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5421
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
3915
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2391
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
0
1226
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.