Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > stdin (keyboard) to file

Reply
Thread Tools

stdin (keyboard) to file

 
 
Peter Blues
Guest
Posts: n/a
 
      02-06-2008
I'm trying to write from keyboard input to a txt file. I don't understand
why the while loop below doesn't achieve this.
I..
1: open the file for writing through FILE pointer outstream
2: I get chars one at a time as ints(ascii) through fd using getchar()
3: Copy from fd to FILE *outstream using fputc()
4: Finally close outstream.

I feel the problem lies in step 2 and 3. Can someone please explain
where the following code is wrong.

#include <stdio.h>

int main(void) {

int fd;
char file_name[80];
FILE *outstream;

printf("File Name: \n");
scanf("%79s", file_name);

if((outstream = fopen(file_name, "w")) == NULL) {
fprintf(stderr, "open %s for writing failed ", file_name);
perror("because");
return 1;
}

while((fd = getchar()) != EOF)
fputc(fd, outstream);

fclose(outstream);

return 0;
}
 
Reply With Quote
 
 
 
 
vippstar@gmail.com
Guest
Posts: n/a
 
      02-06-2008
On Feb 6, 3:14 am, Peter Blues <(E-Mail Removed)> wrote:
> I'm trying to write from keyboard input to a txt file. I don't understand
> why the while loop below doesn't achieve this.
> I..
> 1: open the file for writing through FILE pointer outstream
> 2: I get chars one at a time as ints(ascii) through fd using getchar()
> 3: Copy from fd to FILE *outstream using fputc()
> 4: Finally close outstream.

You are a bit confused about what int and ascii is.
> I feel the problem lies in step 2 and 3. Can someone please explain
> where the following code is wrong.
>
> #include <stdio.h>
>
> int main(void) {
>
> int fd;

'fd' as a name for an int object is a bad name, because 'int fd;' is
commonly used in UNIX programming where fd stands for file descriptor.
> char file_name[80];

You could change that to FILENAME_MAX
> FILE *outstream;
>
> printf("File Name: \n");
> scanf("%79s", file_name);

You read at most 79 characters but the last character of file_name is
not initialized.
Either do file_name[79] = 0; or define file_name as char file_name[80]
= {0};
You also don't check the return value of scanf but I don't think that
is importand for such small code.
(althought if this code is part of a bigger project, I suggest you do
check the return value)
>
> if((outstream = fopen(file_name, "w")) == NULL) {
> fprintf(stderr, "open %s for writing failed ", file_name);
> perror("because");

How about this
fprintf(stderr, "open %s for writing failed because %s\n", file_name,
strerror(errno));
You need to include <string.h> for strerror().
> return 1;

It is not portable to return 1 from main.
The portable values are 0, EXIT_SUCCESS and EXIT_FAILURE, again, for a
small snippet it does not matter much.
If it's a bigger project change it.
> }
>
> while((fd = getchar()) != EOF)
> fputc(fd, outstream);

This seems alright to me.
>
> fclose(outstream);
> return 0;
>
> }


I believe your problem lies in your confusion about keyboard being
stdin.
stdin is just an input file stream.
C does not define a 'keyboard'. If you expect the above snippet to
capture keystrokes.. then you are out of luck as far as ISO C is
concerned.
You can, however use a system specific function to capture them, which
is off-topic for this newsgroup.
try a newsgroup whose subject is relevant to your system.
 
Reply With Quote
 
 
 
 
Ben Bacarisse
Guest
Posts: n/a
 
      02-06-2008
Peter Blues <(E-Mail Removed)> writes:

> I'm trying to write from keyboard input to a txt file. I don't understand
> why the while loop below doesn't achieve this.


It does. You need to say what you think is wrong. It is likely to do
with getting both the file name and the data from the same place
(stdin) but I won't say more until you say what you think is wrong!

> I..
> 1: open the file for writing through FILE pointer outstream
> 2: I get chars one at a time as ints(ascii) through fd using getchar()
> 3: Copy from fd to FILE *outstream using fputc()
> 4: Finally close outstream.


All good.

> #include <stdio.h>
>
> int main(void) {


Note that you have avoided lots of the beginner errors that are so
common so it seems almost churlish to comment, but...

> int main(void) {
>
> int fd;


Not an obvious name for an input character!

> char file_name[80];
> FILE *outstream;
>
> printf("File Name: \n");
> scanf("%79s", file_name);


You should check the return from scanf. You can't (safely) use the
file name if the input operation failed.

>
> if((outstream = fopen(file_name, "w")) == NULL) {
> fprintf(stderr, "open %s for writing failed ", file_name);
> perror("because");
> return 1;


Better is 'return EXIT_FAILURE;' (you need to #include <stdlib.h>).

> }
>
> while((fd = getchar()) != EOF)
> fputc(fd, outstream);
>
> fclose(outstream);
>
> return 0;
> }


--
Ben.
 
Reply With Quote
 
santosh
Guest
Posts: n/a
 
      02-06-2008
Peter Blues wrote:

> I'm trying to write from keyboard input to a txt file. I don't
> understand why the while loop below doesn't achieve this.
> I..
> 1: open the file for writing through FILE pointer outstream
> 2: I get chars one at a time as ints(ascii) through fd using getchar()
> 3: Copy from fd to FILE *outstream using fputc()
> 4: Finally close outstream.
>
> I feel the problem lies in step 2 and 3. Can someone please explain
> where the following code is wrong.
>
> #include <stdio.h>
>
> int main(void) {
>
> int fd;


This is a confusing name for a variable that is supposed to store a
character value or EOF.

> char file_name[80];
> FILE *outstream;
>
> printf("File Name: \n");
> scanf("%79s", file_name);


scanf is a tricky function to use safely. I suggest using fgets() to
capture lines (or partial lines) and then processing as necessary.

if (fgets(file_name, FILENAME_MAX, stdin) == NULL) printf("Error.\n");
else if (strchr(file_name, '\n') == NULL) {
/* fgets() has got only a partial line. You might want to retrieve
the rest of the line, but one thing at a time.
*/
}

> if((outstream = fopen(file_name, "w")) == NULL) {
> fprintf(stderr, "open %s for writing failed ", file_name);
> perror("because");
> return 1;


One is not a strictly portable return status. Use 0 or EXIT_SUCCESS or
EXIT_FAILURE. Both the symbolic constants are in stdlib.h.

> }
>
> while((fd = getchar()) != EOF)
> fputc(fd, outstream);


fputc() can fail too, returning EOF if so.

> fclose(outstream);
>
> return 0;
> }


It's not immediately obvious what your problem is. In what way does your
program fail?

 
Reply With Quote
 
Peter Nilsson
Guest
Posts: n/a
 
      02-06-2008
(E-Mail Removed) wrote:
> Peter Blues <(E-Mail Removed)> wrote:>
> > I'm trying to write from keyboard input to a txt file.
> > I don't understand why the while loop below doesn't
> > achieve this.
> > I..
> > 1: open the file for writing through FILE pointer outstream
> > 2: I get chars one at a time as ints(ascii) through fd
> > using getchar()
> > 3: Copy from fd to FILE *outstream using fputc()
> > 4: Finally close outstream.

>
> You are a bit confused about what int and ascii is.
>
> > I feel the problem lies in step 2 and 3. Can someone
> > please explain where the following code is wrong.
> >
> > #include <stdio.h>
> >
> > int main(void) {
> >
> > * * * * int fd;

>
> 'fd' as a name for an int object is a bad name,
> because 'int fd;' is commonly used in UNIX programming
> where fd stands for file descriptor.
>
> > * * * * char file_name[80];

>
> You could change that to FILENAME_MAX


You mean change the magic constant 80. Also, switch to
fgets over scanf.

> > * * * * FILE *outstream;

>
> > * * * * printf("File Name: \n");
> > * * * * scanf("%79s", file_name);

>
> You read at most 79 characters but the last character of
> file_name is not initialized.


%s will null terminate the string. The problem may be that
%s will stop reading after the first whitespace character.

> Either do file_name[79] = 0; or define file_name as char
> file_name[80] = {0};


Neither is necessary.

> You also don't check the return value of scanf but I
> don't think that is importand for such small code.


I do.

> (althought if this code is part of a bigger project,
> I suggest you do check the return value)


Given that it's not clear what the error actually is,
checking the return value will rule out certain
candidates.

> >* if((outstream = fopen(file_name, "w")) == NULL) {
> > * fprintf(stderr, "open %s for writing failed ", file_name);
> > * perror("because");

>
> How about this
> fprintf(stderr, "open %s for writing failed because %s\n", file_name,
> strerror(errno));
> You need to include <string.h> for strerror().> * * * * * * * * return 1;
>
> It is not portable to return 1 from main.
> The portable values are 0, EXIT_SUCCESS and EXIT_FAILURE,
> again, for a small snippet it does not matter much.


Either it matters or it doesn't. False lazyness is preventable
and it starts with the small.

> If it's a bigger project change it.
> * * * * }
>
> > * * * * while((fd = getchar()) != EOF)
> > * * * * * * * * fputc(fd, outstream);

>
> This seems alright to me.


Check the return value from fputc. Apart from that, it
looks ok.

> > * * * * fclose(outstream);


Checking the result here is waranted too.

> > * * * * return 0;

>
> > }


--
Peter
 
Reply With Quote
 
Peter Blues
Guest
Posts: n/a
 
      02-06-2008
On Wed, 06 Feb 2008 07:13:43 +0530, santosh wrote:

>> while((fd = getchar()) != EOF)
>> fputc(fd, outstream);

>
> fputc() can fail too, returning EOF if so.
>
>> fclose(outstream);
>>
>> return 0;
>> }

>
> It's not immediately obvious what your problem is. In what way does your
> program fail?


An example: I open an empty filename.txt, when code is run I
enter filename.txt file. I then enter arbitrary characters from the
keyboard then exit with control c. I then return to the gedit which gives
the message filename.txt has changed do you want to reload which I do but
no characters appear in the file.
 
Reply With Quote
 
Walter Roberson
Guest
Posts: n/a
 
      02-06-2008
In article <47a922aa$0$13262$(E-Mail Removed)> ,
Peter Blues <(E-Mail Removed)> wrote:

>An example: I open an empty filename.txt, when code is run I
>enter filename.txt file. I then enter arbitrary characters from the
>keyboard then exit with control c. I then return to the gedit which gives
>the message filename.txt has changed do you want to reload which I do but
>no characters appear in the file.


Control-C seldom signals end-of-file. Usually control-C signals
interruption. When you interrupt the program, by default you
would be requesting to abort the program -- in which case flushing
of the output buffers is not certain to happen. Indeed, if you
interrupt the program, transfering the entered data from the
operating system to the program is not certain to happen.

--
"All is vanity." -- Ecclesiastes
 
Reply With Quote
 
Jack Klein
Guest
Posts: n/a
 
      02-06-2008
On Tue, 5 Feb 2008 17:28:46 -0800 (PST), http://www.velocityreviews.com/forums/(E-Mail Removed) wrote in
comp.lang.c:

> On Feb 6, 3:14 am, Peter Blues <(E-Mail Removed)> wrote:
> > I'm trying to write from keyboard input to a txt file. I don't understand
> > why the while loop below doesn't achieve this.
> > I..
> > 1: open the file for writing through FILE pointer outstream
> > 2: I get chars one at a time as ints(ascii) through fd using getchar()
> > 3: Copy from fd to FILE *outstream using fputc()
> > 4: Finally close outstream.

> You are a bit confused about what int and ascii is.
> > I feel the problem lies in step 2 and 3. Can someone please explain
> > where the following code is wrong.
> >
> > #include <stdio.h>
> >
> > int main(void) {
> >
> > int fd;

> 'fd' as a name for an int object is a bad name, because 'int fd;' is
> commonly used in UNIX programming where fd stands for file descriptor.
> > char file_name[80];

> You could change that to FILENAME_MAX
> > FILE *outstream;
> >
> > printf("File Name: \n");
> > scanf("%79s", file_name);

> You read at most 79 characters but the last character of file_name is
> not initialized.


What is the source of the incorrect information you have been coming
up with lately? Where did you get the idea that scanf() will not
terminate any successful input with '\0'?

However many characters scanf() reads from the standard input stream,
up to and including 79, it will place a '0' terminator at the end.

> Either do file_name[79] = 0; or define file_name as char file_name[80]
> = {0};


Your second suggestion is good advice, not because it is needed if the
scanf() succeeds, because however many characters it retrieves will
have a '0' terminator added at the end. It is a good idea in case
scanf() fails to read any characters at all, due encountering an
end-of-file condition, if will call fopen() with "", instead of an
uninitialized array of characters.

Your first suggestion, file_name[79] = 0; (prefer '\0' myself), does
not protect against this problem.

--
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
 
Reply With Quote
 
santosh
Guest
Posts: n/a
 
      02-06-2008
Peter Blues wrote:

> On Wed, 06 Feb 2008 07:13:43 +0530, santosh wrote:
>
>>> while((fd = getchar()) != EOF)
>>> fputc(fd, outstream);

>>
>> fputc() can fail too, returning EOF if so.
>>
>>> fclose(outstream);
>>>
>>> return 0;
>>> }

>>
>> It's not immediately obvious what your problem is. In what way does
>> your program fail?

>
> An example: I open an empty filename.txt, when code is run I
> enter filename.txt file. I then enter arbitrary characters from the
> keyboard then exit with control c.


In most systems CONTROL-C usually leads to the OS terminating the
program, which might result in the file not being properly written. Use
CONTROL-D under UNIX or CONTROL-Z under DOS to signal end-of-file which
is what you want to exit the read loop.

> I then return to the gedit which
> gives the message filename.txt has changed do you want to reload which
> I do but no characters appear in the file.


 
Reply With Quote
 
CBFalconer
Guest
Posts: n/a
 
      02-06-2008
Peter Blues wrote:
>
> I'm trying to write from keyboard input to a txt file. I don't
> understand why the while loop below doesn't achieve this.
> I..
> 1: open the file for writing through FILE pointer outstream
> 2: I get chars one at a time as ints(ascii) through fd using
> getchar()
> 3: Copy from fd to FILE *outstream using fputc()
> 4: Finally close outstream.


On most systems you can simply use the redirection of stdin and
stdout, as follows:

#include <stdio.h>

int main(void) {

int ch; /* note int, not char */

while (EOF != (ch = getc(stdin))} putc(ch);
return 0;
}

and you run it with:

progname > outfile

followed by typing the required data. End with a ctrl-Z (for
windoze) or ctrl-D (for linux) to signal end-of-file.

Later, if you wish, you can investigate using the file open/close
statements, and get the necessary information from the command
line. Then the main parameters will no longer be void.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.



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

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
peek at stdin, flush stdin Johnathan Doe C Programming 5 05-17-2013 04:30 PM
How to pass stdin of a C++ program to the stdin of a process createdwith ShellExecute() Ben C Programming 2 08-29-2009 09:47 PM
STDIN, OUT, ERR and $stdin, out, err - Differences? Terry Cooper Ruby 7 06-09-2009 05:48 AM
Reading from stdin then launching a program that reads from stdin strange behaviour Stefano Sabatini Perl Misc 6 07-29-2007 10:38 PM
Reading stdin once confuses second stdin read Charlie Zender C Programming 6 06-21-2004 01:39 PM



Advertisments