Thread: C program file read/write help

  1. #1
    Registered User
    Join Date
    Sep 2008
    Posts
    22

    C program file read/write help

    Here is the psuedocode my teacher gave us.

    void list(FILE *fp) {
    /* move the file pointer to the beginning using fseek() */
    get a line using fgets()
    print the line to the console using puts()
    until end of file is reached
    }

    I am having trouble getting my code to work. Here is what i have in my main and what i have in my function, respectively. Keep in mind I am only on case 2 so far so ignore the other cases... I keep getting syntax errors, what am i doing wrong?

    Code:
    #include <stdio.h>
    #include "list.h"
    
    int main() {
    	int user_input;
    	printf("1. insert\n2. list\n3. delete\n4. update\n5. exit\nKey in 1-5:\n");
    	scanf("%d", &user_input);
    	while (user_input > 0) {
    		switch(user_input) {
    			case 1:
    				//insert();
    				break;
    			case 2:
    				list(FILE *fp);
    				break;
    			case 3:
    				//delete();
    				break;
    			case 4:
    				//update();
    				break;
    			case 5:
    				/* close file and exit */
    			    fclose(fp);
    				break;
    			default:
    				break;
    				/* error inputs handling */
    		}
    		printf("1. insert\n2. list\n3. delete\n4. update\n5. exit\nKey in 1-5, -1 to exit:\n");
    		scanf("%d", &user_input);
    	}
    } /* end of main() */
    and now the function list...
    Code:
    #include <stdio.h>
    
    void list(FILE *fp);
    
    int main()
    {
       FILE * fp;
       char mystring [100];
    
       fp = fopen("file.txt" , "w+");
       if (fp == NULL) perror ("Opening File");
       else {
         fgets (mystring , 100 , fp);
         puts (mystring);
         fclose (fp);
       }
       return 0;
    }

  2. #2
    Registered User
    Join Date
    Jan 2008
    Posts
    290
    Quote Originally Posted by BobDole11 View Post
    and now the function list...
    Code:
    #include <stdio.h>
    
    void list(FILE *fp);
    
    int main()
    {
       FILE * fp;
       char mystring [100];
    
       fp = fopen("file.txt" , "w+");
       if (fp == NULL) perror ("Opening File");
       else {
         fgets (mystring , 100 , fp);
         puts (mystring);
         fclose (fp);
       }
       return 0;
    }
    That is not the function list. That is a function prototype for the list function, followed by a main() function. I think you are a little confused on how to define functions.

    Code:
    int list(FILE *fp)
    {
       char mystring [100];
    
       fp = fopen("file.txt" , "w+");
       if (fp == NULL) perror ("Opening File");
       else {
         fgets (mystring , 100 , fp);
         puts (mystring);
         fclose (fp);
       }
       return 0;
    }
    THAT defines the function list. Typically you would put this definition somewhere above your main function. Alternatively, you could put a function prototype for list above main(), and define list below main. (or you could put it in a totally separate file, but that's a different - and more complicated - story).

    I.E.
    Code:
    int list(FILE* fp) {
     .....
    }
    
    int main() {
     .....
    }
    
    - OR -
    
    int list(FILE*);
    
    int main() {
     .....
    }
    
    int list(FILE* fp) {
     .....
    }
    Furthermore, when you actually CALL the list function, you need to pass it a valid FILE to read from. This also means that you shouldn't be opening and closing the file in the list function (it should already be open when you pass it in).
    Code:
    FILE *fp;
    
    switch (user_input) {
    ...
       case 2:
          fp = fopen("file.txt", "w+");
          list(fp);
          fclose(fp);
          break;
    ...
    }
    (I omitted the error-checking for simplicity - you should still check to make sure the file opened ok)

  3. #3
    Registered User
    Join Date
    Sep 2008
    Posts
    22
    Thanks a lot, I was having trouble understanding the code. Can you clarify a few things for me too?

    When it opens the file it always creates a new one or deletes the old one so I lose the data, how would I have it keep the data?

    How do i use fseek() to get to the first line of code, is each line just numbered from 1 to n?

    how exactly does the mystring(is this just the variable name?) work, I used 100 in my code randomly, so does that mean it gets 100 characters from a string in the .txt file?

    Sorry if these questions sound stupid, my book hasn't helped me clarify these points although im probably looking in the wrong chapter.

  4. #4
    Registered User
    Join Date
    Jan 2008
    Posts
    290
    To figure out how standard library functions work, you really need to find a good reference. I absolutely LOVE the documentation at cplusplus.com. Their reference is very well done.

    In particular, check out:

    fopen to learn about other modes besides "w+" and fseek to learn how fseek works and how you should use it.

    How do i use fseek() to get to the first line of code, is each line just numbered from 1 to n?
    I'm not sure what you mean by "get to the first line of code". Think of a file as nothing more than a sequence of bytes (or if you're in text mode, a sequence of characters). The first character would be at offset 0 from the beginning of the file. "Lines" of text are really just sequences of characters with a special line-terminator character between them. For example, a file containing this text:
    Code:
    Hello.
    I am
    an example.
    is really stored as this:
    Code:
    Hello.\nI am\nan example.
    where the \n should be thought of as a single character called a line-terminator, or newline character.

    Code:
       char mystring [100];
       ...
       fgets (mystring , 100 , fp);
       puts (mystring);
    Yes, 'mystring' is the name of a variable. 'mystring' has the type 'array of 100 chars'. The fgets() function reads characters from the file until it either encounters a line-terminator ('\n'), reaches the end of the file, or reads however many characters you said your array could store. It stores these characters in the array that you pass to it. puts() just prints the array of characters to stdout (which is usually the console).

    So putting this all together - if you opened the file I mentioned earlier ("Hello.\nI am..."), fseeked to the beginning of the file, and then called fgets(mystring, 100, fp) this is what would happen:

    Code:
    * You fseek to the beginning of the file (^ is your current position in the file) *
    Hello.\nI am\nan example.
    ^
    
    * You call fgets(mystring, 100, fp) *
    Hello.\nI am\nan example.
            ^
    
    * mystring now contains these characters: "Hello.\n\0" *
    Notice a couple things that usually trip up beginning programmers. fgets() reads the '\n' and stores it in your array of characters, it doesn't remove it. Also, it adds a special character to the end of the array called a null terminator ('\0' - that's a slash followed by a zero). This special character signifies the end of a string. This sets it apart from a normal array of characters.

    Yes, a "string" in C is nothing more than an array of characters with a special null-terminator at the end. Without that special null terminator, you no longer have a string, which means you can't pass your array to functions that expect a string, like strlen(), strcpy(), strtok(), puts() etc...

    (Wow this post got long, sorry about that - I started typing and I guess I got a little carried away...)

  5. #5
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    "a single character called a line-terminator, or newline character"

    This always seems oxymoronic to me, as something that terminates a line and something that starts a new one are not the same thing, altho doing the later may imply the former.

    It also could perhaps lead to confusion with the null terminator (\0) amongst newbies. Probably the use of the term "null terminator" stems from the fact that we already have an inaptly named "line-terminator".

    \0 terminates a line
    \n starts a new one, in the sense of a carriage return

    nb. that \n is actually part of the text file you are reading whereas \0 never is (as arpsmack points out, it is added by fgets and serves the important function of signaling the end of a string. For example, if I insert a \n into your hello string with string[2]='\n' (actually this doen't insert, it replaces the first 'l'), printing the string will look like this:

    Code:
    He
    lo.
    (next line would start here)
    But if I replace it with a null terminator -- string[2]='\0' --

    Code:
    He(next line would start here)
    Anything in string after \0 gets ignored.

    "Without that special null terminator, you no longer have a string"

    This is NOT true. You could replace the \0 in the hello string with string[7]=' ';. Now there is a string with no null terminator, which might look like this when printf'd:

    Code:
    Hello.
    �G$[�G��G
    Because the remaing 92 characters in string have not been defined.
    Last edited by MK27; 10-13-2008 at 08:44 AM.
    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

  6. #6
    Registered User
    Join Date
    Jan 2008
    Posts
    290
    Quote Originally Posted by MK27 View Post
    "Without that special null terminator, you no longer have a string"

    This is NOT true. You could replace the \0 in the hello string with string[7]=' ';. Now there is a string with no null terminator, which might look like this when printf'd:

    Code:
    Hello.
    �G$[�G��G
    Because the remaing 92 characters in string have not been defined.
    It is commonly known that in the C language a string consists of a sequence of characters in an array terminated by a special null-terminator character. Thus in the C language the terms "string" and "null-terminated string" are referring to the same concept.

    There is a very important distinction between a string, and a simple array of characters. A string stores its length along with the characters that compose it, a simple array does not. In a C string, the length is implicitly stored using the null-terminator, rather than a more explicit method like Pascal would use.

    The reason your example looks like garbage when passed to printf is because it is NOT a null-terminated string, and thus not a C string. All you are passing printf is an array of characters, and thus you cannot expect proper behavior.

    If still not convinced, please read the wikipedia article on C-strings: http://en.wikipedia.org/wiki/C_string The very first sentence gives the exact definition.

    Your statements only hold true if you are referring to the term "string" in some sort of theoretical sense, where it means "a sequence of characters", and this really has no place in this particular discussion of the C language.

    IMO, you only served to make this conversation more confusing for the OP by
    1. Complaining about nomenclature that neither you, I, or the OP can change. (and furthermore, I have no problem calling '\n' a line-terminator. It does, in fact, terminate a line)
    2. Posting false information. A "C string" is a null-terminated string. Done. End of story. You can't change this, and shouldn't be telling new programmers otherwise.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. To find the memory leaks without using any tools
    By asadullah in forum C Programming
    Replies: 2
    Last Post: 05-12-2008, 07:54 AM
  2. Encryption program
    By zeiffelz in forum C Programming
    Replies: 1
    Last Post: 06-15-2005, 03:39 AM
  3. Simple File encryption
    By caroundw5h in forum C Programming
    Replies: 2
    Last Post: 10-13-2004, 10:51 PM
  4. fopen();
    By GanglyLamb in forum C Programming
    Replies: 8
    Last Post: 11-03-2002, 12:39 PM
  5. My program, anyhelp
    By @licomb in forum C Programming
    Replies: 14
    Last Post: 08-14-2001, 10:04 PM