Thread: Reading a file using fgets

  1. #1
    Registered User
    Join Date
    Dec 2010
    Posts
    5

    Reading a file using fgets

    Hey all,

    For a few days now I've been trying on and off to figure out a problem while using fgets, and I can't seem to crack it. The issue is I want to use fgets to read a line, dump that output into a char array, and read the array character by character. However, when I try to do so, the output I get instead is the string from that character onwards.
    Here's a tiny bit of code I wrote specifically to test this:

    Code:
    int main()
    {
        FILE *infile;
        char buffer[25];
        infile = fopen("testfile", "r");
        fgets(buffer, 50, infile);
        puts(&buffer[1]);
    }
    testfile contains a single line: 'This is a test'. The output of this code is 'his is a test', or, in other words, the char array from the first index onwards. I know I'm probably doing something wrong that's rather simple, but I can't seem to get it to work, and I would be very grateful for any help.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    You should have written:
    Code:
    puts(&buffer[0]);
    or more simply:
    Code:
    puts(buffer);
    By taking the address of the char at index 1 instead, you are skipping the char at index 0, i.e., the first character.

    By the way, since you set the size of buffer as 25, it does not make sense to use 50 as the second argument to fgets.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Dec 2010
    Posts
    5
    Thanks for your reply!

    Perhaps I should have clarified this a bit more. I don't want to read the entire string, that I can do. What I want to do is read a single character from it. I would have expected the output of puts(&buffer[1]) to be simply 'h', and nothing more, but this is not the case. Even putting the output into a single char (no array) still outputs all the characters in the original string from there onwards. I would like to know why this happens, as it is confusing the hell out of me, and how I am supposed to read a single character.

    You are correct on the 25/50 thing, that's inconsistent, mainly due to this being copied code from another project I was working on. I will correct that, but my other problem still stands, unfortunately!

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Ferris
    I don't want to read the entire string, that I can do. What I want to do is read a single character from it.
    Use fgetc instead of fgets.

    Quote Originally Posted by Ferris
    I would have expected the output of puts(&buffer[0]) to be simply 'h', and nothing more, but this is not the case.
    Suppose you wanted to read the entire string. What would you write?

    Quote Originally Posted by Ferris
    Even putting the output into a single char (no array) still outputs all the characters in the original string from there onwards.
    That sounds unlikely. For example:
    Code:
    #include <stdio.h>
    
    int main()
    {
        FILE *infile;
        char buffer[25];
        infile = fopen("testfile", "r");
        fgets(buffer, 25, infile);
        putchar(buffer[0]);
        return 0;
    }
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    Dec 2010
    Posts
    5
    Quote Originally Posted by laserlight View Post
    Use fgetc instead of fgets.
    I know of the existence of fgetc, but it is cumbersome for my application, since it needs read a line, and then perform multiple operations on it. Using fgetc would mean reading, rewinding, skipping to the part I was before, then reading again if I don't use an intermediate variable. And it's also become somewhat of a issue of principle now: I don't know how to get a single character out of a string, and that's pretty basic, and it's bugging me.

    Quote Originally Posted by laserlight View Post
    Suppose you wanted to read the entire string. What would you write?
    puts(buffer);.

    Quote Originally Posted by laserlight View Post
    That sounds unlikely. For example:
    Code:
    #include <stdio.h>
    
    int main()
    {
        FILE *infile;
        char buffer[25];
        infile = fopen("testfile", "r");
        fgets(buffer, 25, infile);
        putchar(buffer[0]);
        return 0;
    }
    This code works to output a single character, however, I would like to perform operations using that character, instead of pass it to standard output. What I meant by my original comment is that the following code acts weird:

    Code:
    int main()
    {
        FILE *infile;
        char buffer[25];
        char output;
        infile = fopen("testfile", "r");
        fgets(buffer, 25, infile);
        output = buffer[1];
        puts(&output);
        return 0;
    }
    puts(&output), even though output should be a single char, outputs 'hThis is a test'. That's no typo, there is that 'h' at the front. Again, this is probably a simple error due to my incomplete understanding of pointers, but I still cannot figure out how to get a single character from a char array like this one.

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Ferris
    And it's also become somewhat of a issue of principle now: I don't know how to get a single character out of a string, and that's pretty basic, and it's bugging me.
    If the string is stored in an array named buffer, then you access it as buffer[i], where i is the index of the given character. You apparently know this, but you are over-complicating the issue.

    Quote Originally Posted by Ferris
    Suppose you wanted to read the entire string. What would you write?
    puts(buffer);.
    Err... sorry, but that does not make sense. puts is for output, not input.

    Quote Originally Posted by Ferris
    puts(&output), even though output should be a single char
    puts is used to print a string, not a single char. Your attempted use of puts to print a single char is simply incorrect. The output you get is because, coincidentally, the contents of the buffer array is stored right after the variable named output, so when puts attempts to print, it keeps reading until it finds the null character that terminates the string. The output could very well have been something else, or the program could have crashed, etc (the effects of undefined behaviour).

    It seems to me that it really is very simple. If you want to print buffer[1], just print it:
    Code:
    putchar(buffer[1]);
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User
    Join Date
    Dec 2010
    Posts
    5
    Quote Originally Posted by laserlight View Post
    If the string is stored in an array named buffer, then you access it as buffer[i], where i is the index of the given character. You apparently know this, but you are over-complicating the issue.
    Yes, this is what I thought, but I don't get the desired behaviour when I try to use it as such. Perhaps my use of puts is wrong, however, changing the code to printf still outputs 'his is a test' given this code, instead of outputting a single character:

    Code:
    {
        FILE *infile;
        char buffer[25];
        infile = fopen("testfile", "r");
        fgets(buffer, 25, infile);
        printf(&buffer[1]);
        return 0;
    }
    The reason this problem occurred is because I had a file that was formatted as such:
    Code:
    1 2 3
    4 5 6
    7 8 9
    I used fgets to read the first line, put it into an array, then tried to access the first character with array[0], the second character with array[1], etc. This led to some unexpected behaviour, so I decided to use printf to print the output of array[0], array[1], etc, and what I got was this:
    Code:
    array[0]: '1 2 3'
    array[1]: ' 2 3'
    array[2]: '2 3'
    Instead of getting the first character and printing that, printf printed the first character and then the rest of the string. This led me to believe this was the cause of my unexpected behaviour. Or is this simply a function of printf?

  8. #8
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Like many other things, you should use printf only as directed. Putting the thing you want to print inside the parens of printf is not how you are directed to do it -- you need a conversion specifier first, and then the thing you want to print later:
    Code:
    printf("%c", buffer[1]);

  9. #9
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Quote Originally Posted by Ferris
    Code:
    printf(&buffer[1]);
    You can't pass the address of a char as the first argument to printf(); it requires a string. If you want to just print the first character than use putchar() (without the &) as laserlight already suggested. If you want to use printf() to print a character than do it like this:
    Code:
    printf("%c", buffer[1]);
    If you want to print the address of buffer[1] then do this:
    Code:
    printf("%p", (void*)&buffer[1]);
    If you understand what you're doing, you're not learning anything.

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Ferris
    Perhaps my use of puts is wrong, however, changing the code to printf still outputs 'his is a test' given this code, instead of outputting a single character:
    What did you expect it to print?

    I suggest that you compile and run this program:
    Code:
    #include <stdio.h>
    
    int main(void)
    {
        const char *text = "hello world!";
        puts(text);
        puts(text + 6);
        puts(&text[6]);
        return 0;
    }
    I expect the output to be:
    Code:
    hello world!
    world!
    world!
    The reason is that puts(text + 6) prints the substring starting from the character at index 6, i.e., the substring "world!". &text[6] yields the same address as text + 6, hence puts(&text[6]) prints the same substring.

    What you did with printf is to use the string (or substring starting from index 1) as a format string. By right, you should have used:
    Code:
    printf("%s", &buffer[1]);
    But if you really want to print a single character, then write:
    Code:
    printf("%c", buffer[1]);
    All the confusion that you have right now is due to the fact that whenever you claimed that you printed a single character, you didn't. You printed a string, or a substring thereof, or simply attempted to print a character as a string.
    Last edited by laserlight; 12-06-2010 at 03:32 PM. Reason: Copy and paste error for printing single char.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #11
    Registered User
    Join Date
    Dec 2010
    Posts
    5
    Thanks laserlight and itme86! I think I understand. Make a mental note: when debugging, make sure you actually properly code your debugging code.

    Indeed, I used printf incorrectly, causing all sorts of weird output, which made me expect that this was what made my program error out. In fact, I was just an idiot :P Thanks again for the help! I'll go bughunting using proper code this time.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Can you help me about tolower() in file
    By nctar in forum C Programming
    Replies: 7
    Last Post: 05-12-2010, 10:04 AM
  2. opening empty file causes access violation
    By trevordunstan in forum C Programming
    Replies: 10
    Last Post: 10-21-2008, 11:19 PM
  3. sequential file program
    By needhelpbad in forum C Programming
    Replies: 80
    Last Post: 06-08-2008, 01:04 PM
  4. Can we have vector of vector?
    By ketu1 in forum C++ Programming
    Replies: 24
    Last Post: 01-03-2008, 05:02 AM
  5. System
    By drdroid in forum C++ Programming
    Replies: 3
    Last Post: 06-28-2002, 10:12 PM