Skip to: Site menu | Main content


Welcome to PSP-Programming.com, a place for developers to get together.

Welcome to the forums. Here you can find other user tutorials as well as homebrew releases and the source code repository. You can also ask for help with your code here and post your own homebrew!

PSP-Programming.com Forums
March 13, 2010, 05:43:01 PM *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length

News: Welcome to PSP-Programming.com
Home Help Search Shop Login Register
Digg This!
Pages: [1] 2 3 ... 6
Print
Author Topic: [Tutorial] File I/O  (Read 36295 times)
harleyg
Give miinaturvat Points!
Hero Member
*****

Karma: +11/-14
Offline Offline

Posts: 715
462.95 points

View Inventory
Send Money to harleyg


View Profile
« on: May 22, 2006, 06:48:00 AM »

In this tutorial we will be covering the basics of file reading and writing in C.
We will be using the following:
Functions: fopen, fread, fseek fclose, fgetc, malloc, fwrite and fprintf.
We will also be using simple maths and variables.


Contents:
(Smile = done, Sad = not done, Cool = working on it)

File Input (Reading)
    1. Printing an entire file. [Smile]
    2. Reading x to y bytes from a file. [Smile]
    3. Searching to a certain point. [Smile]
    [/list]

    File Output (Writing)
      1. Writing a block of data to a file. [Smile]
      2. Writing formatted data to a file. [Smile]
      [/list]

      General file examples and samples (wiki)
        Print file size - Print a file size
        Get configuration - Read a file, search for a string and return whats after '=', great for use with configuration files!
        [/list]

        ---------------------------------------------------------------------------
        If you have read these tutorials and found them helpful, please comment on them in this thread or send an email to me at: harleyg {AT} linuxlabs.co.uk ({AT} = @).
        Also, if you have read these, you will be able to combine certain things, eg. searching to a certain point in a file and writing to it, writing and then reading, putting the contents of a file into an array, reading a file as config, saving users settings into a config file etc. The possibilities are endless!
        ---------------------------------------------------------------------------
        Please note: Any content writen on this site by harleyg, unless stated otherwise belongs to me. You are forbiden to modify, copy or distribute it in any form. If found, credited or not on sites outside the LinuxLabs network or the http://psp-programming.com domain, action will be taken against you. Modification of the content is also prohibited without the authors consent. That is all.
        ---------------------------------------------------------------------------





        File Input (Reading) - 1. Printing an entire file
        What we will learn: How to read an entire file into the memory, printing the contents and then terminating.


        First we will need to make a few includes, so open up your favourite text editor (vim Very Happy) and create a new file, with the extenstion of .c, eg. foo.c. Now inside the text editor, type:
        Code:
        #include <stdio.h>
        #include <stdlib.h>

        These includes do the following:
        stdio.h: "standard input-output header," is the library in C programming language which contain functions for manipulating standard input and output.
        stdlib.h: "general purpose standard", is the library of C programming language which includes functions involving memory allocation, process control, conversions and others.


        Ok, "enough about includes already" i see you saying  Rolling Eyes
        Now start your main function:
        Code:
        int main(void) {

        int, meaning interger is used to refer to any data type which can represent some subset of the mathematical integers.
        void, is used because in earlier versions of C, functions with no specific result defaulted to a return type of "int" and functions with no arguments simply had empty argument lists. Pointers to untyped data were declared as integers or pointers to "char".
        {, is used to show that the function has started!


        Next we will declare some variables:
        Code:
        FILE * pFile;
        long lSize;
        char * buffer;

        FILE, we use this to make the pFile variable a "file pointer".
        long, now this is tricky as int and long int both can be from -2,147,483,648 to +2,147,483,647. I would normally use int, but im just copying this example from a cool site and explaining it to you in english, i hope Wink Oh, and an int is an explained above!
        char, we use this to declare the variable "buffer" contains characters (a-z).

        Next we give the pFile variable some information:
        Code:
        pFile = fopen ( "myfile.txt" , "rb" );

        pFile, this is a variable, already made into a "file pointer" above.
        =, this means foo IS bar (foo = bar).
        fopen, this is a function in c that is used to open a file (duh). In requires 2 parameters, the "filename" and "mode".
        "myfile.txt", this is the first parameter, the "filename".
        rb, this contains 2 modes used:
          -
        r: Open a file for reading. The file must exist.
        - b: Binary mode. End of file is reached at last byte of the file. No conversions.[/list]

        So now we need to check if the file has any data inside, we use the following:
        Code:
        if (pFile==NULL) exit (1);

        if, this is an IF STATEMENT, it can be used to compair things, eg. if foo is bar etc.
        ( + ), this is to show this is where i start, and this is where i close.
        ==, the == means equal to, unlike =, which means the same as.
        NULL, this is the same as empty, or "nothing".
        exit (1), this terminates the process. It also has the number "1", so we can see what point it terminates at.

        So, this entire if statement means in english:
        Quote
        if pFile is empty, terminate/quite



        Next, we are going to check the file size.
        Code:
        fseek (pFile , 0 , SEEK_END);
        lSize = ftell (pFile);
        rewind (pFile);

        fseek, "Reposition stream's position indicator." This requires 3 parameters, the pointer to an open file, the offset (how many bytes from the origin) and the origin.
        ( + ), this is to show this is where i start, and this is where i close.
        pFile, this is the pointer to an open file which we declared earlia.
        0, this is the offset, it is saying we want it to be exactly on the origin.
        SEEK_END, we are saying here that we want the offset to be at the end of the file.
        lSize = ftell (pFile);, this is saying lSize IS ftell (pFile).
        ftell(pFile);, "Return the current position in a stream". ftell only requires one parameter, a pointer to an open file, in this case it is pFile. ftells main function is to tell you how many bytes until the begining from the position you are at.
        rewind (pFile);, rewinds function is to reopen the file back to the begining. It also only requires one parameter, which is a pointer to an open file.

        So, how we find out the file size with this is:
        Open the file, seek the end, then tell how many bytes there are until the begining, so if the file is 10 bytes, it will seek to the end, and count back until the begining, which is 10 bytes. The file size is now in the variable lSize.


        Next we need to free lSize amount of memory to fit the file in (lSize being the size of the file).
        Code:
        buffer = (char*) malloc (lSize);
        if (buffer == NULL) exit (2);

        buffer =, saying buffer IS foo.
        ( + ), this is to show this is where i start, and this is where i close.
        char *, this is telling malloc that it contains characters.
        malloc, this is a function to allocate foo memory. eg, malloc(56); will make sure there is 56 bytes of memory for you to store information in. So malloc (lSize) is allocating the the file size.
        if (buffer == NULL) exit (2);, (ive already explained these, refer above for information).


        Ok, so now we have successfully opened a file, checked its file size and allocated it in the memory.

        Next, we copy the file contents into the buffer (memory).
        Code:
        fread (buffer,1,lSize,pFile)

        fread, " Read block of data from a stream". This function requires 4 parameters.
        buffer, the first parameter, the "buffer", which coincidently is "buffer", by buffer, i mean location to read it to.
        1, this is the second parameter, the "size". This is the size in bytes of each item to be read.
        lSize, this is the third parameter, "count". This is the amount of bytes to read into the buffer, in this case its lSize, the file size.
        pFile, the fourth and final parameter "stream". This is the pointer to an open file, being pFile.


        Ok, so now we have just read the file into the memory.


        Now, we need to close the file as it is not needed anymore!
        Code:
        fclose (pFile);

        fclose (pFile);[/close], "flushes any buffers maintained for the given file and closes the file". I dont really need to explain it, do i?
        ( + ), this is to show this is where i start, and this is where i close.

        Next we are going to print the buffer/file contents to the terminal.
        Code:
        printf("%s\n", buffer);

        printf, "Prints to standard output (stdout) a sequence of arguments formatted as the format argument specifies". Basically, it can print things!
        %s, it is saying that its a variable, and its also a string (characters etc).
        \n, new line.
        "%s\n", buffer, %s refers to a variable, but where do we declare it? When we type buffer after the closed "" we are saying %s = buffer. If we had for example:
        Quote
        "Variable 1: %s, Variable 2: %s\n", foo, bar
        we would be saying the 1st %s is foo and the 2nd %s is bar.
        ( + ), this is to show this is where i start, and this is where i close.


        Next, we free the memory we allocated.
        Quote
        free (buffer);

        Its pretty obvious, but ill explain.
        free, this is a function used to un-allocate memory you allocated. It requires one parameter.
        ( + ), this is to show this is where i start, and this is where i close.

        We now return 0. This shows everything ran fine if it got to this point.
        Code:
        return 0;


        Close the main function.
        Code:
        }


        Here is what your code should look like.
        Code:
        #include <stdio.h>
        #include <stdlib.h>

        int main () {
        FILE * pFile;
        long lSize;
        char * buffer;
        pFile = fopen ( "myfile.txt" , "rb" );
        if (pFile==NULL) exit (1);
        fseek (pFile , 0 , SEEK_END);
        lSize = ftell (pFile);
        rewind (pFile);
        buffer = (char*) malloc (lSize);
        if (buffer == NULL) exit (2);
        fread (buffer,1,lSize,pFile);
        fclose (pFile);
        free (buffer);
        return 0;
        }


        We should also have something inside myfile.txt, try this:
        Code:
        I CAN READ FILES IN C!



        Now, use a compiler (gcc) to compile it:
        Quote
        gcc foo.c
        (replace foo with your filename)

        Now you should be given a binary. Create a file called myfile.txt and type anything inside it. Now, run the binary and it will print the contents.



        Congratulations, you just read a file in C



        I will write up more tutorials when i can be assed, post here if theres any errors or you need help!
        Logged


        kozine
        Newbie
        *

        Karma: +0/-0
        Offline Offline

        Posts: 46
        0.00 points

        View Inventory
        Send Money to kozine

        View Profile WWW
        « Reply #1 on: May 22, 2006, 08:34:08 AM »

        Sweet Very Happy Thanks for this! It will help me alot Smile
        Logged

        harleyg
        Give miinaturvat Points!
        Hero Member
        *****

        Karma: +11/-14
        Offline Offline

        Posts: 715
        462.95 points

        View Inventory
        Send Money to harleyg


        View Profile
        « Reply #2 on: May 22, 2006, 09:32:41 AM »

        File Input (Reading) - 2. Reading x to y bytes from a file.

        Ok, so in this second part we will be looking at reading x to y bytes in a file. If you dont understand what this means i will explain:
        You have a file, its 13 bytes, inside it contains "hello harleyg", say we want to just print the word harleyg, we would want bytes 6 to 13, right?

        So, lets get started!

        Lets make a file we are going to read from, name it myfile.txt again, and inside put:
        Code:
        hello, i can read from a file!

        Note, this file is: 30 bytes.

        Ok, so now open up your favourite text editor (vim!) and save the file as main.c, now lets do some includes!
        Code:
        #include <stdio.h>
        #include <stdlib.h>
        #include <string.h>


        stdio.h: "standard input-output header," is the library in C programming language which contain functions for manipulating standard input and output.
        stdlib.h: "general purpose standard", is the library of C programming language which includes functions involving memory allocation, process control, conversions and others.
        string.h: "standard C library to manipulate C strings."

        Ok, so now we start the main function:
        Code:
        int main(void) {


        Now we decalre some variables:
        Code:
        int i;
        char k[30];
        FILE *f=fopen("myfile.txt", "rb");

        int, this has been explained above!
        char k[30];, char, we use this to declare the variable "k" contains characters (a-z). We also use "[30]" to show it can contain up to 30 bytes.

        Next, we read the file with "fread".
        Code:
        k[fread(k, 1, 30, f)]=0;

        I will explain this in one bit... we are saying k is firstly fread(k, 1, 472, f) (fread explaination in first tutorial)... then we are saying k[number]=0; which terminates the resulting string to the exact amount of bytes read.

        We now can close the file, as the file contents are stored in the variable "k".
        Code:
        fclose(f);


        We are now going to print bytes 7 to 18.
        Code:
        k[18]=0; printf("%s\n",k+7)

        I will also explain this in one bit... we are now saying k is 18 (the end byte), then printf the string from byte 7, this may be a little confusing but youll get the hang of it  Wink

        We now close the main function:
        Code:
        }


        Your whole main.c should look like this:
        Code:
        #include <stdio.h>
        #include <string.h>
        #include <stdlib.h>
        int main(void) {
                int i;
                char k[30];
                FILE *f=fopen("myfile.txt", "rb");
                k[fread(k, 1, 30, f)]=0;
                fclose(f);
                k[18]=0; printf("%s\n",k+7);
        }


        Oh, and your myfile.txt should be like this:
        Code:
        hello, i can read from a file!


        So go ahead and compile it (gcc!)... and run the binary, you should get a message  Laughing

        I have tried to make this less of a noobs tutorial and not repeat what i have said in my last tutorial, once again if you need help or find any errors just post here!

        --harleyg
        Logged
        Yeldarb
        Miinaturvat Rules!
        Administrator
        Hero Member
        *

        Karma: +16/-3
        Offline Offline

        Posts: 602
        4160.65 points

        View Inventory
        Send Money to Yeldarb


        View Profile WWW
        « Reply #3 on: May 22, 2006, 09:39:04 AM »

        Nice =)

        When it's all done, do you mind if I convert it to tutorial form and put it in the tutorials section where it'll get more traffic?
        Logged

        harleyg
        Give miinaturvat Points!
        Hero Member
        *****

        Karma: +11/-14
        Offline Offline

        Posts: 715
        462.95 points

        View Inventory
        Send Money to harleyg


        View Profile
        « Reply #4 on: May 22, 2006, 09:40:14 AM »

        yup, thats why i posted it here Wink
        ill finish it off tomorow or something, took me an hour+ to write it up, i tried making it as noob friendly as possible Smile
        Logged
        Feldor
        Newbie
        *

        Karma: +1/-0
        Offline Offline

        Posts: 47
        0.00 points

        View Inventory
        Send Money to Feldor


        View Profile
        « Reply #5 on: May 22, 2006, 10:27:10 AM »

        well done, very usefull
        Logged


        All my work is licensed under the Creative Commons (CC) License.
        harleyg
        Give miinaturvat Points!
        Hero Member
        *****

        Karma: +11/-14
        Offline Offline

        Posts: 715
        462.95 points

        View Inventory
        Send Money to harleyg


        View Profile
        « Reply #6 on: May 22, 2006, 01:37:52 PM »

        thanks, ill finish the next one, maybe two tomorow.
        Logged
        phacergei
        Jr. Member
        **

        Karma: +2/-1
        Offline Offline

        Posts: 63
        0.00 points

        View Inventory
        Send Money to phacergei


        View Profile
        « Reply #7 on: May 22, 2006, 02:20:02 PM »

        Very nice tutorial! I was actually about to make a tutorial on this stuff, because I am still fiddling around with PSP c programming. I made a basic text reader thing that does a similar function with outputting a text file. Your tutorial is much better than mine would have been, though.

        Question: can you do "malloc()" on the PSP? I didn't think the PSP had that capability and I didn't want to risk messing it up by trying.

        Also, what do you do if you have a text file that is very large (like an ebook or something), and won't display on the screen?

        I found that the PSP screen is approximately 67 characters by 34 characters



         What I currently have is something like this:
        Code:
        char buffer[33][1000];
        FILE* book;
        int pg_index=0;
        void Next_Page()
        {
            pg_index=0;
            oslCls();
            while (fgets(buffer[pg_index], 67, book) && (pg_index < 33)) pg_index++;
            Show_Text(pg_index);
        }
        void Show_Text(int cmd)
        {
            oslCls();
            int i;    
            oslSetTextColor(RGBA(0,0,0,255));
            oslSetBkColor(RGBA(255,255,255,255));
            if (cmd==0) oslPrintf_xy(30, 10, "No book loaded or end of book. Press square to load a book.\n\n");
            if (cmd) for(i=0; i<cmd; i++) oslPrintf("%s\n", buffer[i]);
        }




        So when I press x, it calls Next_Page, which reads from the file into a 2D char array, and then calls Show_Text with how many lines it read, and Show_Text oslPrintf's the lines...


        It doesn't seem to work right, though


        ergei
        Logged
        SG57
        Sr. Member
        ****

        Karma: +7/-37
        Offline Offline

        Posts: 474
        1140.80 points

        View Inventory
        Send Money to SG57


        View Profile
        « Reply #8 on: May 22, 2006, 03:36:08 PM »

        well... just setup a function...  have it 'check' to see if the string has reached 64 characters or not, then just inject a '\n' into it on the 64th char and ur done Smile  Unless you want the whole word to be carried... that requires parsing and searching from 1 ' ' to the next ' ' which would drag what ever is between down with it...

        I know my string manipulation Wink
        Logged
        phacergei
        Jr. Member
        **

        Karma: +2/-1
        Offline Offline

        Posts: 63
        0.00 points

        View Inventory
        Send Money to phacergei


        View Profile
        « Reply #9 on: May 22, 2006, 03:47:19 PM »

        well, yeah its an array of 33 strings and each is up to 67 chars long. I will make it 64 by 32 to make it even, but it should work anyway... The first page of the book displays perfectly fine, but when I press x to go to the next page, it looks fine, but It has skipped a bunch of lines.  It could be that it's skipping an entire page, I will check my code again.



        ergei
        Logged
        harleyg
        Give miinaturvat Points!
        Hero Member
        *****

        Karma: +11/-14
        Offline Offline

        Posts: 715
        462.95 points

        View Inventory
        Send Money to harleyg


        View Profile
        « Reply #10 on: May 22, 2006, 10:35:06 PM »

        thanks ^^
        i will be writing up a few tutorials in the next week so i might touch on that.
        Logged
        harleyg
        Give miinaturvat Points!
        Hero Member
        *****

        Karma: +11/-14
        Offline Offline

        Posts: 715
        462.95 points

        View Inventory
        Send Money to harleyg


        View Profile
        « Reply #11 on: May 23, 2006, 09:04:04 AM »

        ok i cant post this, can you do a few things yeldarb...
        1. insert this: http://harleyg.linuxlabs.co.uk/tut.txt into this thread
        2. make it the 2nd post, by me
        3. delete this Smile
        Logged
        Yeldarb
        Miinaturvat Rules!
        Administrator
        Hero Member
        *

        Karma: +16/-3
        Offline Offline

        Posts: 602
        4160.65 points

        View Inventory
        Send Money to Yeldarb


        View Profile WWW
        « Reply #12 on: May 23, 2006, 09:17:21 AM »

        Not sure what's wrong :-\

        I don't have access to the apache2.conf, nor do I know what I'd need to change.

        Umm, I put it directly into mysql but it doesn't display correctly.
        Logged

        harleyg
        Give miinaturvat Points!
        Hero Member
        *****

        Karma: +11/-14
        Offline Offline

        Posts: 715
        462.95 points

        View Inventory
        Send Money to harleyg


        View Profile
        « Reply #13 on: May 23, 2006, 09:18:54 AM »

        it runs through the bbcode system before it gets to mysql, you need to change the bbcode tags to the html ones, you should be able to tell them by the 1st tutorial Wink

        oh, and in the apache2 settings you would be looking for a bandwidth post limit, or something, its probably a gay plugin... is your server yours or in a datacenter?
        Logged
        Yeldarb
        Miinaturvat Rules!
        Administrator
        Hero Member
        *

        Karma: +16/-3
        Offline Offline

        Posts: 602
        4160.65 points

        View Inventory
        Send Money to Yeldarb


        View Profile WWW
        « Reply #14 on: May 23, 2006, 01:08:05 PM »

        It's a shared server.
        Logged

        Pages: [1] 2 3 ... 6
        Print
        Jump to:  

        Powered by MySQL Powered by PHP Powered by SMF 1.1.11 | SMF © 2006-2009, Simple Machines LLC Valid XHTML 1.0! Valid CSS!
        Page created in 0.333 seconds with 38 queries.
        Sister Sites: Guitar Hero 4   BrokeniTouch.com