element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Code Exchange
  • Technologies
  • More
Code Exchange
Blog C++ Tutorial - File I/O
  • Blog
  • Forum
  • Documents
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Code Exchange to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: oneleggedredcow
  • Date Created: 1 May 2013 1:19 AM Date Created
  • Views 2077 views
  • Likes 2 likes
  • Comments 4 comments
  • raspbpi
  • code_exchange
  • Code Exchange
  • learn++
  • programming
  • raspberry_pi
  • code
  • rpi
  • c++
  • learnc++
Related
Recommended

C++ Tutorial - File I/O

oneleggedredcow
oneleggedredcow
1 May 2013

Introduction

In the previous tutorial, we talked about inheritance which is a way to reuse variables and methods that are common to multiple classes. It also allows for a class hierarchy to be set up so that methods can work on the most generic class possible.

 

In this tutorial, we are going to discuss reading and writing data to a file.  Reading and writing to a file is a required aspect of most programs since it will usually need to interface with external data.

Code

Let’s start by writing a file.  This file will have a small header on it that describes how many values are stored in the file.  Then comes that number of doubles:

 

const double PI = 3.14159;


int main()

{

// Create some data

int points = 11;

double *data = new double[points]();

for(int i = 0; i < points; i++)

{

data[i] = sin(i/((double) points - 1)*2*PI);

}

 

// Write the file

FILE* file = fopen("file.dat", "wb");

fwrite(&points, sizeof(int), 1, file);

fwrite(data, sizeof(double), points, file);

fclose(file);

 

// Print out what was written

for(int i = 0; i < points; i++)

{

cout << data[i] << endl;

}

delete[] data;

 

return 0;

}

 

In order to make the data stored in the file a little more interesting, a sine wave was generated. This has the benefit of being easily checked for accuracy, but not so simple that we could trick ourselves into thinking that the code to read the file was working when it was not.  (An example of this might be writing a file of all zeros, and then trying to read it back it.)

 

Now, that we have some data generated, we are on to the new and exciting part: writing data to the file. The first order of business is to open up a file to write to.  To do this we use the fopen (File OPEN) command.  The first argument is the name of the file to open.  The second is how to open the file.  “wb” means to open the file in write mode and that the data that will be written to it is binary.

 

The fwrite command does the actual writing of data to the file.  The first thing that we want to write to the file is the number of data points that will be stored in the file, which we have stored in the points variable. Looking at the arguments for fwrite, it wants a pointer to the data that we wish to write.  At first this seems like a problem.  We have an integer, we don’t have a pointer to an integer. Remembering back to the pointers tutorial, we can easily get the address of the integer, by using the & operator.  The next two arguments describe the data to be written.  The first one is how big each value is, and the second is how many values there are.  The last argument is the file to write the data to.

 

Writing the data to the file is very similar to writing the header.  In fact it is a little easier because we have a pointer to the data that we want to write.

 

The last part of writing the data to the file is closing it when we are done.  This is extremely important!  Just like deleting the data that has been allocated from new, this should be done every time.  It is staggering how many programs I have seen crash because they hit the limit of the number of simultaneously open files that the OS would allow.  In every case, the program was done with the file, but they forgot to close the file.

 

The last section just writes the data out to the screen.  This way we know what was in the file without having to dig through the binary data with a tool like od.

 

Now, that we have a file to read in, let’s read that file in:

 

int main()

{

// Read the file

FILE* file = fopen("file.dat", "rb");

int points = 0;

fread(&points, sizeof(int), 1, file);

 

double *data = new double[points];

fread(data, sizeof(double), points, file);

 

fclose(file);

 

// Print out file contents

for(int i = 0; i < points; i++)

{

cout << data[i] << endl;

}

delete[] data;

 

return 0;

}

 

Just like writing a file, the first thing that we need to do is open up the file.  This time we will open the file for reading binary data by setting the second parameter to “rb”.  For more information about the various modes that a file can be opened into, check out this link.

 

Now before we can allocate an array to store the data into, we need to know how much data is going to be in the file.  Luckily, when we wrote the data, the first thing that we wrote out was how much data is stored in the file.  So, we read this in.  Notice that we are using a trick very similar to how we wrote it out.  We declare a plain old integer and then we get the address of it by using the & operator.  The arguments to the fread function are very similar to the fwrite function as well.

 

Once we have the size of the array, we allocate enough memory to store it using the new operator. After we have a place to store it, we read the data in using the fread function.  Always remembering to close the file after we are done with it.

 

The last section of code writes out the values that are read into the program, so that we can check against the values that we wrote out.  Everything checks out, so we know that we were successfully able to read and write data to a file.

 

Another thing to mention is that the data contained in the file doesn’t have to be basic data types. Structures are another great option. Here’s a slightly modified version of the program where we write the header out using a struct:

 

const double PI = 3.14159;

 

typedef struct FileHeader

{

int Points;

 

int Year;

int Month;

int Day;

} FileHeader;

 

int main()

{

// Create some data

FileHeader header;

header.Points = 11;

header.Year = 2013;

header.Month = 4;

header.Day = 30;

 

double *data = new double[header.Points]();

for(int i = 0; i < header.Points; i++)

{

data[i] = sin(i/((double) header.Points - 1)*2*PI);

}

 

// Write the file

FILE* file = fopen("structFile.dat", "wb");

fwrite(&header, sizeof(FileHeader), 1, file);

fwrite(data, sizeof(double), header.Points, file);

fclose(file);

 

// Print out what was written

for(int i = 0; i < header.Points; i++)

{

cout << data[i] << endl;

}

delete[] data;

 

return 0;

}

 

The reader code would need similar modifications.

Summary

In this tutorial, we learned about reading and writing data to a file.

 

In the next tutorial, we will learn about strings.  Strings are a way to store text.  Strings can be thought of arrays of characters, but since they are so common, we give them a special name.  It might be surprising to realize, but we have been using strings since the very first tutorial, when we wrote “Hello Raspberry Pi!”.

 

If you have any questions or comments about what was covered here, post them to the comments.  I watch them closely and will respond and try to help you out.

Tutorial Index

01 - Hello Raspberry Pi

02 - Reading User Input

03 - If Statement

04 - For Loops

05 - While Loops

06 - Functions

07 - Data Types

08 - Arrays

09 - Structures

10 - Classes

11 - Pointers

12 - Dynamic Arrays

13 - Linked List

14 - Linked List Operations

15 - STL List/Vector

16 - Templates

17 - Inheritance

18 - File I/O

19 - Strings

20 - Constants

21 - Hash Tables

Attachments:
18_FileIO.zip
  • Sign in to reply

Top Comments

  • oneleggedredcow
    oneleggedredcow over 10 years ago in reply to Former Member +1
    Interesting, I just tried it and I was able to get it to work. Maybe you are using the wrong reader/writer combo. The first code snippet writes a header with just an int. The second code snippet reads…
  • oneleggedredcow
    oneleggedredcow over 10 years ago in reply to Former Member

    Interesting, I just tried it and I was able to get it to work.  Maybe you are using the wrong reader/writer combo.  The first code snippet writes a header with just an int.  The second code snippet reads that file that was written.  The third code snippet writes a different file format (that the second code snippet reader cannot handle).  So, maybe that was the problem.

     

    The third code snippet was showing how to write a struct, but I can see how that would be confusing.  I've added an attachment with all of the code and changed the name of the third code snippet's output file to be structFile.dat to make this more clear.

     

    And yes, fopen/fwrite/fread are all the older more C style to write/read a file.  The comment from shabaz above gives more information about how to do it in a more C++ style way.

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Former Member
    Former Member over 10 years ago

    Your code that writes a file gives a "segmentation fault" in Raspbian, and also some sort of run time error on Windows 7 in Visual Studio 2013. Would you be able to correct this?

     

    Edit: the solution for Windows 7 in Visual Studio 2013 is found here: http://stackoverflow.com/questions/16883037/remove-secure-warnings-crt-secure-no-warnings-from-projects-by-default-in-vis --apparently your fopen method is considered deprecated.

    Debugging your tutorial is really quite a bit of work!

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • oneleggedredcow
    oneleggedredcow over 12 years ago

    Thanks, excellent comment!  fstream is definitely the more "c++" way to go about things, whereas what I described was the more "c" way.  Personally, I tend to use fopen/fread/fwrite much more, especially for binary files.  The only time I use fstream is for reading/writing text files.  (And since I haven't given proper treatment to strings - which is coming next article, I was hesitant to go that route.)

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • shabaz
    shabaz over 12 years ago

    Hi Shaun,

    It's a very useful post as always, the whole tutorial is a great reference.

    Another file handling method (useful on Linux/Windows platforms) is to use the fstream library, although this may not be possible on microcontrollers not running Linux.

     

    #include <fstream>


    using std::ofstream;

    using std::ifstream;

    using std::endl;


    int

    main(void)

    {

      char line[1024];

      ofstream out;


      ifstream in("infile.txt");

      out.open("outfile.txt");


      while (in.getline(line, 1024))

      {

          out << line << endl;

      }


      return 0;

    }

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube