A. Files:
For storage of data for later use, files are used.
Files are stored on the Hard Disk Drive (HDD). There are two types of files:
1.
Text files - in which all
data is stored as ASCII characters, and
2.
Binary files - in which data
is stored as is in main memory.
Every
file type has its own merits and demerits. However, we will only use 'text'
files in this lab/course.
1. Writing data to 'text' files:
There are five (5) steps associated with writing to a
file:
1.
Include fstream library.
2.
Declare a variable (actually
an object) of output file stream, i.e., of type ofstream.
3.
Attach the ofstream object to an existing or new
file in text (default) mode.
4.
Write to the output file
stream using insertion operator (<<).
5.
Close the file stream.
Look at the code below to understand these five steps,
highlighted in statements in bold.
#include <iostream>
#include
<fstream> /*step 1: include lib*/
using namespace std;
int main()
{
ofstream fout; //step 2: create
ofstream obj
fout.open("lab14data.txt");
//step 3: attach to file
fout << "Student Record\n";
//step 4: write to file
char
rollno[6];
cout
<< "Enter your roll no: ";
cin
>> rollno;
cout
<< "Roll Number: " << rollno << endl;
fout << "Roll Number: "
<< rollno << endl; //step 4
fout.close(); //step 5: close stream
return 0;
}
The choice of '.txt'
extension is to facilitate viewing of the file in Notepad. Otherwise extension
can be left or other extensions can be used.
Run the code, enter your roll no. It will display your
roll number and also create a file named lab14data.txt
in the same folder as your .cpp file.
Go to the folder, open the lab14data.txt file and see its contents. They should be the same as
displayed one the console window.
Important Note:
Also check the file size. Right click on the filename
(in Windows explorer) and click properties.
Note the file size and match it with the number of
characters displayed in the file. There would be a difference of 2 in the file
size and the number of characters (including newline). The reason is, the
newline character is entered as two characters, a 'carriage return' (CR)
character (ASCII code of 13) and a line feed (LF) character (ASCII code of 10).
This is how you would write to a new file that did not
exist before.
In case you wish to open an already existing file for
writing (output) but you want to overwrite its contents, you will still use the
same code.
To check this, run the code again. Enter a different
roll number.
Check the file now. It should contain the newly
entered roll number.
2. Reading data from 'text'
files:
There are five (5) steps associated with reading from
a file:
1.
Include fstream library.
2.
Declare a variable (actually
an object) of input file stream, i.e., of type ifstream.
3.
Attach the ifstream object to an existing file
(only) in text (default) mode.
4.
Read from the input file
stream using extraction operator (>>).
5.
Close the file stream.
Look at the code below to understand these five steps,
highlighted in statements in bold. The code reads in data from the previously
created filel lab14data.txt and
displays the first roll number.
#include <iostream>
#include <fstream> /*step 1: include lib*/
#include <string>
using namespace std;
int main()
{
ifstream
fin; //step 2: create ifstream obj
fin.open("lab14data.txt");
//step 3: attach to file
char line1[100];
fin.getline(line1,
100); //step 4: read from file
cout
<< line1 << endl;
char
roll[10], no[10], rollnumber[10];
fin
>> roll >> no>>rollnumber; //step 4
cout
<< roll << " " << no << " "
<< rollnumber << endl;
fin.close();
//step 5: close stream
system("pause");
return 0;
}
Experiment with the code and the file contents to read
different types of data from input file.
Task # 1:
Write a code that takes the names and ages of five
students and write them in a text file.
CODE:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ofstream
fout;
int
n=1;
fout.open("Task1_lab14.txt");
fout
<< "Student's Name and Age record !"<<endl;
char
name[50];
int
age;
do
{ cout
<< "Enter Name of student no "<<n<<" : ";
cin>>name;
cout<<"input
age : ";
cin>>age;
fout
<< "Name of student : " << name
<<'\t'<<" Age of student : "<<age<< endl;
n++;
}while
(n<=5);
fout.close();
cout<<endl<<"Thank
you for Entering data..... kindly check Task1_lab14.txt....";
return
0;
}
Task # 2:
Write a code to read the already written names and
ages of the students in the file (done in task 1).
CODE:
#include <iostream>
#include <fstream>
using namespace std;
int main ()
{
ifstream
file;
file.open("lab14t2.txt");
int
count,age;
char
name[20];
for
(count=0;count<=4;count++)
{
file
>> name;
file
>> age;
cout
<< "NAME of student : " << name << endl
<<"AGE of student :
" << age <<
endl;
cout
<< endl;
}
return
0;
}
B.
Reading File
using eof():
The amount of data stored in the file is often unknown. So instead of
manually counting data in a text file, we use C++ built in function eof()
(stands for end of file).
eof(), returns
nonzero (meaning TRUE) when there are no more data to be read from an input
file stream and zero (meaning FALSE) otherwise.
Rules for using eof() are as follow:
a) Always test for the end-of-file condition before processing data read from an input file stream. This
ensures we only process data when available.
b) Use a priming input statement before starting the loop.
c) Repeat the input statement at the bottom of the loop body.
d) Use a while loop for getting data from an input file
stream. A for loop is desirable only when you know the exact
number of data items in the file, which is not the case here.
Following example 1, will read all integer numbers stored in file and sum
them, until end of file is not reached.
Example 1:
#include
<iostream>
#include<fstream>
using
namespace std;
int
main()
{
int data, sum = 0; // declare a variable
that will read each integer from file and initialize the sum
ifstream
fin; // declare stream variable name
fin.open("myfile.txt");
// open file
fin
>> data; //attempt to read data
//
get first number from the file (priming the input statement).You //must
attempt to read data prior to an eof() test.
while
(!fin.eof()) //if not at end of file,
continue reading numbers
{
sum += data; //create a running sum of the incoming data
fin>>data; //get next number from file
}
fin.close( ); //close file
sum += data; //add the last incoming item
cout << "sum of all numbers: "
<< data; //display the sum
return 0;
}
|
C. Functions
A function is
a group of statements that together perform a task. Every C++ program has at least one function, which is main(), and
programs can define additional functions.
You can divide up your code into separate functions.
Passing an array
to a function:
When you need to pass an array to a function, C++ does not allow passing it
by value, only passing by reference (address) is allowed. Remember that the
name of the array is a reference to its starting (base) address. Thus, only the
array name is passed to a function as a reference argument. Using a reference
alone, there is no way to tell the size of the array, so the size needs to be
passed separately.
Look at the following example to understand how an array is passed to a
function. Since it is passed by reference, if the function changes the values
in the array, the corresponding values in the array in the main() would also
change.
Example 2:
#include
<iostream>
using
namespace std;
int maxval(int
arr[], int size); // function declaration
int main ()
{
const int SIZE = 5;
int values[SIZE] = {50, 100, -100, 400, 333},
ret;
ret = maxval(values, SIZE); // calling a
function to get max value.
cout << "Max value is: "
<< ret << endl;
return 0;
}
int maxval(int
arr[], int size) { //returns max in the array
int result = arr[0];
for(int i = 1; i < size; i++)
if (arr[i] > result)
result
= arr[i];
return result;
}
There may be other ways of making the size available in both main() and the
function maxval(), for example, by the use of global variables. It is customary
to use ALL CAPS to name the global variables to avoid confusion with local
variables.
Example 3:
#include
<iostream>
using
namespace std;
const int
SIZE = 5; //global variable, visible in all funcs below
int maxval(int
arr[]); // function declaration
int main ()
{
int values[SIZE] = {100, -100, 0, 400, 333},
ret;
ret = maxval(values); // calling a function
to get max value.
cout << "Max value is: "
<< ret << endl;
return 0;
}
// function
returning the max between two numbers
int maxval(int
arr[])
{
int result = arr[0];
for(int i = 1; i < SIZE; i++)
if (arr[i] > result)
result
= arr[i];
return result;
}
Look at the following code and see
how multiple functions with the same name can also be used in the same code.
The compiler has no ambiguity about which function to call since the parameter
list of each is different. This is known as function-overloading.
Try to identify which function call invokes which specific function in the
below example:
Example 4:
#include
<iostream>
using
namespace std;
int maxval(int
num1, int num2);
void maxval(int,
int, int &); //names not needed
in declaration
int maxval(int
arr[]);
int maxval(int
[], int);
const int
SIZE = 2;
int main ()
{
int a = 100, b = 200, ret, array[SIZE] =
{100, 200};
cout << "Max value is : "
<< maxval(a,b) << endl;
maxval(a, b, ret); //note this cannot be
used within cout statement!
cout << "Max value is : "
<< ret << endl;
cout << "Max value is : "
<< maxval(array, SIZE) << endl;
cout << "Max value is : "
<< maxval(array) << endl;
return 0;
}
int maxval(int
num1, int num2) {
return (num1 > num2) ? num1 : num2;
return (num1 > num2) ? num1 : num2;
}
void maxval(int
num1, int num2, int &m) {
m = (num1 > num2) ? num1 : num2;
}
int maxval(int
arr[]) {
int result = arr[0];
for(int i = 1; i < SIZE; i++)
if (arr[i] > result)
result
= arr[i];
return result;
}
int maxval(int
arr[], int size) {
int result = arr[0];
for(int i = 1; i < size; i++)
if (arr[i] > result)
result
= arr[i];
return result; }
Task # 3:
Add a function average() in the following code and shift the code segment
that computes average to it. The function should return the computed value of
average.
Code:
#include <iostream>
using namespace std;
float average(float a[],float s);
int main ()
{
float data[100], n;
float avg;
cout << "How many
values will you enter : ";
cin >> n;
for(int i = 0; i < n; i++)
{ cout<<"Enter value no
"<<i+1<<" : ";
cin
>> data[i];
}
avg=average(data,n);
cout << "Average
value is: " << avg<< endl;
return 0;
}
float average(float a[],float s)
{
float sum=0;
float avg;
for(int i = 0; i < s; i++)
{
sum =sum + a[i];
}
avg = sum/s;
return avg;
}
#include <iostream>
using namespace std;
int main ()
{
int
data[100], n;
double sum =
0, average;
cout <<
"How many values will you enter (<100): ";
cin >>
n;
for(int i =
0; i < n; i++)
cin
>> data[i];
for(int i =
0; i < n; i++)
sum +=
data[i];
average =
sum/n;
cout <<
"Average value is: " << average << endl;
return 0;
}
Task # 4:
Now add a function getdata() in the code you wrote for task 3, which should
get data from file already stored in that folder (manually create a file and
fill with 20 numbers). The main() should first call getdata() to receive all
input from a file and then invoke average() to find average of the values.
Code:
#include <iostream>
#include <fstream>
using namespace std;
float average(float a[],float s);
float getdata(float a[],float s);
int main ()
{
float
data[100],n;
float avg;
cout
<< "How many values do you want to read : ";
cin >>
n;
getdata(data,n);
avg=average(data,n);
cout
<< "Average value is: " << avg<< endl;
return 0;
}
float getdata(float a[] ,float s)
{
int data;
ifstream
fin; // declare stream variable name
fin.open("Task4_lab14.txt");
for (int i=0;i<s;i++)
{
// cout<<data<<endl;
fin >> data; // reading 1st value i.e first line
a[i]=data; //putting
in array
}
fin.close( );
}
float average(float a[],float s)
{
float sum=0;
float avg;
for(int i = 0;
i < s; i++)
{
sum
+= a[i];
}
avg = sum/s;
return avg;
}
Task # 5:
In example 2 code, what happens if the size passed to the function maxval()
is zero (i.e. the actual parameter SIZE is 0)? Would the return value be
a valid max value? Resolve this ambiguity by introducing a mechanism to somehow
warn the caller code that the returned value is a bogus value.
Hint: you may consider passing
an additional parameter by reference and using it as a flag to indicate if the
return value is valid or bogus.
Code:
#include <iostream>
using namespace std;
int maxval(int arr[], int size, int &flag); //
function declaration
int main () {
int SIZE = 5;
int values[ ] =
{50, 100, -100, 400, 333}, ret;
int flag=0;
cout<<"input size : ";
cin>>SIZE;
ret =
maxval(values, SIZE,flag); // calling a function to get max value.
if(flag==1)
{
cout <<"The Size value is out of
bound so bogus value returned !!!!"<<endl;
cout <<
"Max value is: " << ret << endl;
}
else
{
cout <<
"Max value is: " << ret << endl;
}
return 0;
}
int maxval(int arr[], int size, int&flag) {
//returns max in the array
int result =
arr[0];
for(int i = 1;
i < size; i++)
{
if (arr[i]
> result)
result =
arr[i];
}
if (size!=5)
{
flag=1;
}
else if
(size==5)
{
flag=0;
}
return result;
}