using fread on stdin

This is a discussion on using fread on stdin within the C Programming forums, part of the General Programming Boards category; is there any way to use "fread" to read a string (up to the first newline) from "stdin" similar to ...

  1. #1
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243

    using fread on stdin

    is there any way to use "fread" to read a string (up to the first newline) from "stdin" similar to how you would with scanf? (i realize that scanf isnt very good for reading strings because you do not know the length). the problem with using fread on stdin seems to be that, as it should, it reads up to the number of characters specfied or until EOF is found. however on a keyboard you cant really type an EOF value (and if so, it isnt user friendly).

    here is an example of what ideally should happen:
    Code:
    #include<stdio.h>
    
    int main()
    {
        char buf[256] = {0};
        
        fread( buf, 1, 255, stdin );
    
        printf("&#37;s\n", buf);
    }
    and on the input string "abc" [enter], this string is printed to the console immediately (ie not waiting for 251 more characters).

    i am using linux with gcc compiler. thanks

    edit: i want to emphasize that i just want to use fread, and if not possible let me know.

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,676
    >> i realize that scanf isnt very good for reading strings because you do not know the length
    scanf() is ok. You can specify buffer sizes. If you want everything up to an [enter], then fgets() is easiest.

    gg

  3. #3
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    Quote Originally Posted by Codeplug View Post
    >> i realize that scanf isnt very good for reading strings because you do not know the length
    scanf() is ok. You can specify buffer sizes.
    i didnt know scanf allows you to specify a max length. how do you do this?

    If you want everything up to an [enter], then fgets() is easiest.
    i know there are a number of ways to read input, however i must use fread. i cant seem to get it with stdin. if this cant be done, thats fine, i just need to know if it can be, because i cant get it to work.

  4. #4
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,671
    > is there any way to use "fread" to read a string (up to the first newline)
    Unless you fread each char in turn, and test it yourself, then no you can't just try and read a whole block at once and stop at \n

    > however on a keyboard you cant really type an EOF value (and if so, it isnt user friendly)
    Easy, just press ctrl-d
    Once if you're at the start of a line, twice if you've already typed something.

    > however i must use fread
    Not until you explain why fgets() can't possibly work, given your description of the problem is exactly what fgets() does.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  5. #5
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by Salem View Post
    > however on a keyboard you cant really type an EOF value (and if so, it isnt user friendly)
    Easy, just press ctrl-d
    Once if you're at the start of a line, twice if you've already typed something.
    Or Ctrl-Z if you're on Windows.
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

  6. #6
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    Quote Originally Posted by Salem View Post
    > is there any way to use "fread" to read a string (up to the first newline)
    Unless you fread each char in turn, and test it yourself, then no you can't just try and read a whole block at once and stop at \n
    ive tried using a loop and just "fread"ing 1 char but it isnt working as id like.

    > however on a keyboard you cant really type an EOF value (and if so, it isnt user friendly)
    Easy, just press ctrl-d
    Once if you're at the start of a line, twice if you've already typed something.
    no, this is not user friendly. by user friendly i mean to the user it is exactly as if scanf is being used (ie type a string press enter and its done)

    > however i must use fread
    Not until you explain why fgets() can't possibly work, given your description of the problem is exactly what fgets() does.
    the requirement is to use fread for input. no scanf, fscanf, fgets, etc.

    thanks for the input though!

  7. #7
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,671
    Post your code for fread'ing 1 char at a time.
    "Tried it and it didn't work" isn't helpful.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  8. #8
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by nadroj View Post
    the requirement is to use fread for input. no scanf, fscanf, fgets, etc.

    ive tried using a loop and just "fread"ing 1 char but it isnt working as id like.
    it works if you do it like this:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main () {
    	short int i=0;
    	char *buffer, chr[1];
    	buffer=malloc(1);
    	while (1) {
    		fread(chr,1,1,stdin);
    		if (chr[0]=='\n') {
    			buffer[i]=0; //terminate line
    			break;}
    		buffer[i]=chr[0];
    		buffer=realloc(buffer,i+2);
    		i++;
    	}
    	printf("\"%s\"\n", buffer);	 
    }
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  9. #9
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    MK27, that worked exactly. awesome, thanks!

  10. #10
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    i did one from scratch and it is a little simpler, and is all i need:
    Code:
    #include<stdio.h>
    
    int main()
    {
        char buf[256] = {0};
        int i = 0;
        char t;
    
        fread( &t, 1, 1, stdin );
        while (t != '\n' )
        {
            buf[i++] = t;
            fread( &t, 1, 1, stdin );
        }
    
        buf[i] = '\0';
        printf("buffer is '&#37;s'\n", buf);
    }

  11. #11
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,671
    So much for
    - checking the return result of fread()
    - preventing buffer overflows

    *shrug*
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  12. #12
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    And in MK27's,
    - preventing memory leaks
    - freeing memory

    Also why use short int for array indexing!??!

    With my old CompSci tutor, you'd both get close to 0

    As for a speed up, did you consider fread()'ing BUFSIZ bytes? Then parsing the buffer / adding / resizing to another buffer? And use the left over on the next line... or push back onto the front of stdin.
    Last edited by zacs7; 10-22-2008 at 10:31 PM.

  13. #13
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    in reply to both salem and zacs comments about how "bad" my code snippet is, i simply posted it as a final note of what i was trying to achieve. i never made any mention or guarantee of its reliability or security. the code is not being used in a "real-world" project for work nor is it being used for a school assignment. if it was for either, of course i would have made it as unbreakable as possible.

    - checking the return result of fread()
    - preventing buffer overflows
    - i could initialize my character t to 0 (or anything except '\n') to solve this
    - buffer overflows would be prevented if i added a condition in my while loop that "i" is not exceeding the given buffer size.

    however, i am not doing anything with the code anymore, i just wanted to figure it out.

    zacs, i dont fread BUFSIZ bytes because this will continue to read until BUFSIZ (normally 256) bytes are entered. (or until newline or CTRL+C is entered, which is not user friendly and therefore not what i wanted). what i wanted (and what my code does) is read up to the given number of bytes, or until the first newline is entered. this is exactly what i want.
    Last edited by nadroj; 10-23-2008 at 11:41 AM.

  14. #14
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by nadroj View Post
    in reply to both salem and zacs comments about how "bad" my code snippet is, i simply posted it as a final note of what i was trying to achieve. i never made any mention or guarantee of its reliability or security. the code is not being used in a "real-world" project for work nor is it being used for a school assignment. if it was for either, of course i would have made it as unbreakable as possible.

    zacs, i dont fread BUFSIZ bytes because this will continue to read until BUFSIZ (normally 256) bytes are entered. what i wanted (and what my code does) is read up to the given number of bytes, or until the first newline is entered. this is exactly what i want.
    The only standard function that delivers either X number of characters or to the first newline is fgets(). The fread() function does only end "early" when it hits end-of-file, nothing else will stop it continuing to read from stdin. Of course, fgets() ultimately is calling something like fread() - but that is a different story.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  15. #15
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    thanks. yes i know that fgets is better to use for what i wanted, but i what i was trying to do was to only use fread. and yes, it only stops when it hits EOF (which must be explicitly typed when reading from STDIN).

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. using fread to read from stdin
    By -EquinoX- in forum C Programming
    Replies: 17
    Last Post: 03-23-2009, 12:41 AM
  2. fread problems or memory problems
    By Lechuza in forum C Programming
    Replies: 1
    Last Post: 03-22-2009, 12:45 PM
  3. Another syntax error
    By caldeira in forum C Programming
    Replies: 31
    Last Post: 09-05-2008, 01:01 AM
  4. Why is fread sometimes taking so long?
    By manugarciac in forum C++ Programming
    Replies: 2
    Last Post: 04-28-2007, 11:25 PM
  5. stdin question
    By oomen3 in forum C Programming
    Replies: 6
    Last Post: 02-19-2003, 01:52 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21