<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">\documentclass[onecolumn,letterpaper,11pt]{article}

%===================================================================
% Include common packages, environments, counters etc
\input{common_latex/common_latex_packages}
\input{common_latex/common_latex_lab_format}
\input{common_latex/common_latex_definitions}
%===================================================================

\begin{document}
\wikidoc{file=Lab.CPPIOVectors}
\wikidoc{auth=mikerb@mit.edu}

%===================================================================
% Build the Cover Page in an environment style easy for wiki parsing
\begin{labcover}
\labtitle{C++ Lab 04 - File I/O, Arrays and Vectors}
\vspace{0.1in}
\labcourse{2.680 Unmanned Marine Vehicle Autonomy, Sensing and Communications}
\vspace{0.2in}
\labpng{0.775}{figures/tsl.png}
\vspace{0.3in}
\labdate{IAP 2024}
\vspace{0.1in}
\labauth{Michael Benjamin, mikerb@mit.edu}
\labauth{Department of Mechanical Engineering}
\labauth{MIT, Cambridge MA 02139}
\vspace{0.2in}
\labtoc{small}
\end{labcover}

%======================================================================
% Add a blank page so first body page is on the right when doubleside
\blankpage

%======================================================================
% Begin the body of the text

%======================================================================
\section{Lab Four Overview and Objectives}
%======================================================================

This lab covers two topics that tie together to produce a nice utility function
we will use in later labs. We cover C-style {\em arrays} and their more 
modern counterpart {\em vectors} commonly used C++. Along the way we 
introduce file input/output (I/O) to give us the power of reading to and
from files. In the end we build a simple utility for reading the contents
of a file into a vector of strings.

\begin{labinfo}
\begin{packed_itemize}[2]
\item C-Style Arrays
\item C-Style File Input and Formatted Output
\item C++ Vectors
\end{packed_itemize}
\end{labinfo}

%=======================================================================
\section{C-Style Arrays}
%=======================================================================

The C language provides a robust mechanism for representing and using
{\em arrays}, which are contiguous blocks of memory holding elements
of the same data type. This is a fundamental concept underpinning C
and C++ and commonly found in most if not all programming
languages. C++ now provides alternative data structures such as the
\var{vector} which is simpler to use and less prone to programmer
error. So an array in typical modern C++ code is more likely to be
implemented using a \var{vector} and for this reason we refer to
simple memory arrays as "C-style" arrays.

\pskip
\noindent
Since C-style arrays are still commonly found in legacy and even newer
C++ code, we take a look at these before introducing and advocating
the use of the \var{vector} later in the lab. We will do a short
exercise with C-style arrays, but first, read the page(s) below on
C-style arrays.

\vspace{0.1in}
\begin{packed_itemize}
\item \urlx{http://www.cplusplus.com/doc/tutorial/arrays}
\item \urlx{http://www.tutorialspoint.com/cplusplus/cpp_arrays.htm}
\end{packed_itemize}

%=======================================================================
\refstepcounter{exercise}
\label{ex_arrayone}
\subsection{Exercise \ref{ex_arrayone}: Build a Simple Array from Command Line Arguments }

\noindent
Write a program to read in any number of integers from the command
line, constructing an array of such integers, and printing them out
afterwards. Your array should be exactly the size of the number of
integers read in from the command line. You can assume all arguments
on the command line are valid integers.

\pskip
\noindent

Call your file \var{arrays.cpp} and build it to the executable
\var{arrays}. When your program runs, it should be invocable from the
command line with:

\vspace{0.1in}
\begin{consoleverb}
 $ ./arrays 1 2 3 88 43 26
 Total amount of integers provided: 6
 numbers[0]: 1
 numbers[1]: 2
 numbers[2]: 3
 numbers[3]: 88
 numbers[4]: 43
 numbers[5]: 26
\end{consoleverb}

\vspace{0.12in}
\noindent
The solution to this exercise is in Section \ref{sol_ex_arrayone}.
%-------------------------------------------+


%=======================================================================
\refstepcounter{exercise}
\label{ex_arraytwo}
\subsection{Exercise \ref{ex_arraytwo}: Analyze and Modify a Simple Array}

\noindent
Continuing with the first exercise, write a program to read in any
number of integers from the command line, constructing an array of
such integers, and printing them out afterwards. Your array should be
exactly the size of the number of integers read in from the command
line. Following this scan the array and determine the smallest number
and build a new array of size N-1 removing at most one element of the
first array equal to the smallest element.  You can assume all
arguments on the command line are valid integers.

\pskip
\noindent

Call your file \var{array\_nosmall.cpp} and build it to the executable
\var{array\_nosmall}. When your program runs, it should be invocable
from the command line with:

\vspace{0.1in}
\begin{consoleverb}
 $ ./arrays_nosmall 1 88 43 1 7 26
 Total amount of integers provided: 6
   numbers[0]: 1
   numbers[1]: 88
   numbers[2]: 43
   numbers[3]: 1
   numbers[4]: 7
   numbers[5]: 26
 The new array of integers: 
   numbers[0]: 88
   numbers[1]: 43
   numbers[2]: 1
   numbers[3]: 7
   numbers[4]: 26
\end{consoleverb}

\vspace{0.12in}
\noindent
The solution to this exercise is in Section \ref{sol_ex_arraytwo}.
%-------------------------------------------+



%=======================================================================
\section{C-Style File Input and Formatted Output}
%=======================================================================

The next topic is file I/O, reading from and writing to a file on your computer
from within a C or C++ program. Pretty much everything you need for reading
and writing can be found in the below five functions, which squarely fall in 
the realm of C but supported of course in C++. There are several other options
and functions to do similar things, but the below is pretty complete. Take 
a look at them and follow the examples. Pay special attention to the options
for the \var{fopen()} function. Following this are a couple simple exercises.

\begin{packed_itemize}
 \item \var{fopen()} \newline
   \urlx{http://www.tutorialspoint.com/c_standard_library/c_function_fopen.htm}
 \item \var{fclose()} \newline
   \urlx{http://www.tutorialspoint.com/c_standard_library/c_function_fclose.htm}
 \item \var{fprintf()} \newline
   \urlx{http://www.tutorialspoint.com/c_standard_library/c_function_fprintf.htm}
 \item \var{feof()} \newline
   \urlx{http://www.tutorialspoint.com/c_standard_library/c_function_feof.htm}
 \item \var{fgetc()} \newline
   \urlx{http://www.tutorialspoint.com/c_standard_library/c_function_fgetc.htm}
\end{packed_itemize}

%=======================================================================
\refstepcounter{exercise}
\label{ex_fileout}
\subsection{Exercise \ref{ex_fileout}: Create and Write to a File with Command Line Args}

Write a program that accepts a number of strings on the command line
and creates a new file, also specified as a command line argument. The
new file will contain one line for each provided command line argument
(except for the argument specifying the file name). For this exercise,
you will need to know about the \var{fopen()}, \var{fclose()}, and
\var{fprintf} functions found on the above web pages, plus some of
your knowledge obtained in prior lab exercises for handling command
line arguments.

\pskip
\noindent
Call your file \var{fileout.cpp} and build it to the executable
\var{fileout}.  When your program runs, it should be invocable from the
command line with:

\vspace{0.1in}
\begin{consoleverb}
 $ ./fileout --filename=test.txt one two three four
 $ cat test.txt
 one
 two 
 three
 four
\end{consoleverb}

\vspace{0.12in}
\noindent
The solution to this exercise is in Section \ref{sol_ex_fileout}.

%=======================================================================
\refstepcounter{exercise}
\label{ex_filein}
\subsection{Exercise \ref{ex_filein}: Reading from a File Specified on the Command Line}

Write a program that accepts a given filename on the command line,
opens the file for reading, and reads in each line to a string. The
string will have the format: \var{line: [contents]} where
\var{contents} is the raw contents of the line in the file including
white space.  Your program should then output each string to the
terminal. For this exercise, you will need to know about the
\var{fopen()}, \var{fclose()}, and \var{feof()} and \var{fgetc()}
functions found on the above web pages, plus some of your knowledge
obtained in prior lab exercises for handling command line arguments.

\pskip
\noindent
Call your file \var{filein.cpp} and build it to the executable
\var{filein}.  When your program runs, it should be invocable from the
command line with:

\vspace{0.1in}
\begin{consoleverb}
 $ ./filein --filename=test.txt
 line: [one]
 line: [two]
 line: [three]
 line: [four]
\end{consoleverb}

\vspace{0.12in}
\noindent
The solution to this exercise is in Section \ref{sol_ex_filein}.

%=======================================================================
\section{C++ Vectors}
%=======================================================================

In the situation where one would otherwise use an array in C, code
writers in C++ are more likely to use the \var{vector} class. Even
though we haven't covered C++ classes yet in this lab, this shouldn't
stop us from seeing how a \var{vector} can be used in basic operations
similar to an array. We will point you to a couple on-line tutorials
on the \var{vector} which treat the topic more thoroughly, but first
a description of the minimal things you should know:

%=======================================================================
\subsection{Declaring, building and copying a vector}

\pskip
\noindent
One the best things about the \var{vector} is that, unlike a C-style
array, you don't need to specify the size when it is declared.

\vspace{0.1in}
\begin{fileverb}
 int         my_array[100];   // Declaring an C-style array of integers
 vector&lt;int&gt; my_vector;       // Declaring an array of integers using a vector
\end{fileverb}
\vspace{0.1in}

\noindent
The above \var{my\_vector} is initially empty and elements are added always
to the end with:

\vspace{0.1in}
\begin{fileverb}
  my_vector.push_back(22);
  my_vector.push_back(17);
  my_vector.push_back(43);
\end{fileverb}
\vspace{0.1in}


\noindent
Note that when the vector is initially declared, it is empty, so the following
would not work:

\vspace{0.1in}
\begin{fileverb}
  vector&lt;int&gt; my_vector;
  my_vector[0] = 22;      // error: accessing at an index out-of-bounds 
  my_vector[1] = 17;      //
  my_vector[2] = 43;      // 
\end{fileverb}
\vspace{0.1in}

\noindent
If you would like to declare a \var{vector} with an initial size and default
value for each element, this can be done with:

\vspace{0.1in}
\begin{fileverb}
  vector&lt;int&gt; my_vector(100, 0);    // my_vector has 100 elements all zero
  my_vector[0] = 22;                // Now this is ok. 22 overwrites zero
  my_vector[1] = 17;      
  my_vector[2] = 43;      
\end{fileverb}
\vspace{0.1in}
 
\noindent
As with most all C++ structures like the \var{vector} they can copied very 
simply as you would with fundamental data types like \var{int} or \var{double}:

\vspace{0.1in}
\begin{fileverb}
  vector&lt;int&gt; my_vector(100, 0);    // my_vector has 100 elements all zero
  my_vector[0] = 22;                // Now this is ok. 22 overwrites zero
  my_vector[1] = 17;      
  my_vector[2] = 43;      

  vector&lt;int&gt; his_vector = my_vector;  // his_vector has 100 elements {22,17,43,...,0}
\end{fileverb}
\vspace{0.1in}
 
\noindent
Since a \var{vector} size is not set in stone upon creation, elements may be 
removed too (from the end) with the \var{pop\_back()} function:

\vspace{0.1in}
\begin{fileverb}
  vector&lt;int&gt; my_vector;      // my_vector initially has no elements
  my_vector.push_back(22);    // 
  my_vector.push_back(17);      
  my_vector.push_back(43);    // my_vector now has three element  
  ... 
  my_vector.pop_back();       // my_vector now has two elements {22,17}
\end{fileverb}
\vspace{0.1in}
 
%=======================================================================
\subsection{Accesing and Iterating Through Vectors}

Accessing and iterating through a \var{vector} is very similar to array, 
but since the vector size is not fixed at the outset, we often want to 
know the size of the vector to prevent accessing an index out of bounds.

\vspace{0.1in}
\begin{fileverb}
  vector&lt;int&gt; my_vector;      // my_vector initially has no elements
  my_vector.push_back(22);    // 
  my_vector.push_back(17);      
  my_vector.push_back(43);    // my_vector now has three element  

  unsigned int total_elements = my_vector.size();
\end{fileverb}
\vspace{0.1in}

\noindent
Note the {\em type} returned by the \var{size()} function is of type
\var{unsigned int} since the size can never be less than
zero. Accessing a vector is the same as an array, e.g.,
\var{my\_vector[8]} refers to the 9th element, and can be used on the
left or right side of an assignment operator or passed as a parameter
to a function. In fact the whole vector can be passed as a parameter
in a function. Iterating through an array is also very similar:

\vspace{0.1in}
\begin{fileverb}
  vector&lt;int&gt; my_vector;      // my_vector initially has no elements
  my_vector.push_back(22);    
  my_vector.push_back(17);      
  my_vector.push_back(43);    

  int total = 0;
  for(unsigned int i=0; i&lt;my_vector.size(); i++)
    total += my_vector[i]; 
\end{fileverb}
\vspace{0.1in}

\noindent
A vector may be "reset" or emptied with the \var{clear()} function:

\vspace{0.1in}
\begin{fileverb}
  vector&lt;int&gt; my_vector;      // my_vector initially has no elements
  my_vector.push_back(22);    
  my_vector.push_back(17);      
  my_vector.push_back(43);    // my_vector has three elements

  my_vector.clear();          // my_vector again has no elements
\end{fileverb}
\vspace{0.1in}

\noindent
Lastly, it is often useful to know the last element of a vector
regardless of the index of the last element. For this, use the
\var{back()} function:

\vspace{0.1in}
\begin{fileverb}
  vector&lt;int&gt; my_vector;      // my_vector initially has no elements
  my_vector.push_back(22);    
  my_vector.push_back(17);      
  my_vector.push_back(43);    // my_vector has three elements

  int val = my_vector.back(); // val is set to 43, my_vector still has three elements
\end{fileverb}
\vspace{0.1in}

%=======================================================================
\refstepcounter{exercise}
\label{ex_vectorone}
\subsection{Exercise \ref{ex_vectorone}: Build a Vector from Command Line Arguments}

\noindent
Write a program, similar to Excercise \ref{ex_arraytwo}, to read in
any number of integers from the command line, but constructing this
time a \var{vector} of such integers, and printing them out
afterwards. As before, scan the vector and determine the smallest number
and build a new vector of size N-1 removing at most one element of the
first vector equal to the smallest element.  You can assume all
arguments on the command line are valid integers.

\pskip
\noindent
Call your file \var{vectors\_nosmall.cpp} and build it to the
executable \var{vectors\_nosmall}. When your program runs, it should
be invocable from the command line with similar output:

\vspace{0.1in}
\begin{consoleverb}
 $ ./vectors_nosmall 1 88 43 1 7 26
 Total amount of integers provided: 6
   numbers[0]: 1
   numbers[1]: 88
   numbers[2]: 43
   numbers[3]: 1
   numbers[4]: 7
   numbers[5]: 26
 The new array of integers: 
   numbers[0]: 88
   numbers[1]: 43
   numbers[2]: 1
   numbers[3]: 7
   numbers[4]: 26
\end{consoleverb}

\vspace{0.12in}
\noindent
The solution to this exercise is in Section \ref{sol_ex_vectorone}.
%-------------------------------------------+

%=======================================================================
\refstepcounter{exercise}
\label{ex_filebuff}
\subsection{Exercise \ref{ex_filebuff}: Build a Vector of Strings Input from a File}

\noindent
Completion of this exercise is the primary goal of this lab. This
exercise asks you to build a utility function we will use in later
labs, that essentially reads the contents of a file into a vector of
strings.  We have touched on all the components of this through prior
exercises so far, so this should just pull things together.

\pskip
\noindent
Write a program that reads in one argument from the command line
(\var{--filename=file}), and reads in the contents of this file into a
vector of strings. Afterwards, all non-empty strings will be written
to the terminal on a separate line. An empty line should be indicated
as empty.

\pskip
\noindent
Your program should consist of three files, \var{filebuff\_main.cpp}
containing your \var{main()} function and \var{FileBuffer.h} and
\var{FileBuffer.cpp} containing your utility function.  When your
program runs, it should be invocable from the command line with:

\vspace{0.1in}
\begin{consoleverb}
 $ cat test.txt      // Assuming a test file with five lines, one of them blank
 one 
 two 
 three
 
 four
 $ ./filebuff --filename=test.txt
 line: [one]
 line: [two]
 line: [three]
 line: Empty!
 line: [four]
\end{consoleverb}

\vspace{0.12in}
\noindent
The solution to this exercise is in Section \ref{sol_ex_filebuff}.
%-------------------------------------------+

%===================================================================
\subsection{Links to On-Line Tutorials on Vectors for Further Info}

Here are a few good links for further reading. Feel free to explore
and try some of the things you see.

\begin{packed_itemize}
\item This link provides an example of a matrix with two vectors: \newline
  \urlx{http://www.yolinux.com/TUTORIALS/LinuxTutorialC++STL.html}

\item This link also touches on {\em algorithms} available for operation on
vectors, such as sorting and randomizing: \newline
\urlx{http://www.mochima.com/tutorials/vectors.html}

\item Here you can see all the functions defined on a vector in the
  menu on the lefthand side of the page: \newline
  \urlx{http://www.cplusplus.com/reference/vector/vector/vector/}
\end{packed_itemize}

%===================================================================
\subsection{Behind-the-Scenes Info about Vectors Worth Knowing Now}

Some of the web links above touch on these issues, but in case you didn't read
them or want further emphasis, we discuss a few of these ideas here. 

\pskip
\noindent
{\bf Memory allocation in vectors:}

\pskip
\noindent
The issue of allocating memory is largely hidden from the user when using
a vector. A vector still uses a contiguous block of memory just like an 
array, but the user typically isn't concerned how the vector obtains or 
grows this memory. A vector has a {\em capacity} which is always greater
or equal to the number of elements in the array. The vector will grow
the capacity as needed, behind the scenes without the user needing to be
concerned with the when or how. A good discussion can be found here:

\vspace{0.1in}
\begin{packed_itemize}
\item vector capacity: \urlx{http://www.cplusplus.com/reference/vector/vector/capacity/}
\end{packed_itemize}
\vspace{0.1in}

\noindent
At times the user may want to think about vector capacity. If you are
building a big vector by pushing one element at a time onto the end,
the vector capacity will up-size periodically along the way by
grabbing a bigger chunk of memory and copying the existing contents
into the new memory before proceeding.  However, if you know this
vector will contain say a million elements, you can set the capacity
right at the time of creation so no re-sizing ever needs to be
done. If this operation is a core operation (repeated many times over
and over in a short period) in your program, then the reservation of
vector capacity can make the difference in having a program that runs
sufficiently fast.

\pskip
\noindent
A few things to remember about \var{vector} capacity:

\begin{packed_itemize}
\item There is no way to set capacity at declaration. It is a two step
  process. First the declaration, then the reservation of capacity:

\vspace{0.1in}
\begin{fileverb}
vector&lt;int&gt; vector_a;             
vector_a.reserve(1000000);        // Has size 0. Capacity exactly 1,000,000
...  
vector&lt;int&gt; vector_b(1000000);    // Has size 1,000,000. Capacity &gt;= 1,000,000
\end{fileverb}
\vspace{0.1in}

\item Invoking the \var{clear()} function doesn't change it's
  capacity, but sets the size to zero.
\item You can know the capacity by invoking the \var{capacity()}
  function.
\end{packed_itemize}

%===================================================================
\subsection{A Preview of other STL Containers}

\pskip
\noindent
The \var{vector} is but one type of {\em container} available in C++. 
Below are a few short descriptions of other useful containers we may explore
in later labs. These are all from the \urlx{cplusplus.com} website.

\begin{packed_itemize}
\item {\em deque} (usually pronounced like "deck") is an irregular
  acronym of double-ended queue. Double-ended queues are sequence
  containers with dynamic sizes that can be expanded or contracted on
  both ends (either its front or its back).

\item {\em Maps} are associative containers that store elements formed
  by a combination of a key value and a mapped value, following a
  specific order.  In a map, the key values are generally used to sort
  and uniquely identify the elements, while the mapped values store
  the content associated to this key.

\item {\em Sets} are containers that store unique elements following a
  specific order.  In a set, the value of an element also identifies
  it (the value is itself the key), and each value must be unique. The
  value of the elements in a set cannot be modified once in the
  container, but they can be inserted or removed from the container.

\item {\em Lists} are sequence containers that allow constant time
  insert and erase operations anywhere within the sequence, and
  iteration in both directions.  List containers are implemented as
  doubly-linked lists; Doubly linked lists can store each of the
  elements they contain in different and unrelated storage
  locations. The ordering is kept internally by the association to
  each element of a link to the element preceding it and a link to the
  element following it.
\end{packed_itemize}

%===================================================================
\newpage
\section{Solutions to Exercises}
%===================================================================

%===================================================================
\subsection{Solution to Exercise \ref{ex_arrayone}}
\label{sol_ex_arrayone}

\begin{fileverb}
/*----------------------------------------------------------------------*/
/*  FILE:  arrays.cpp  (Fourth C++ Lab Exercise 1)                      */
/*  WGET:  wget http://oceanai.mit.edu/cpplabs/arrays.cpp               */
/*  BUILD: g++ -o arrays arrays.cpp                                     */
/*  RUN:   ./arrays 23 11 98 32 2 23                                    */
/*----------------------------------------------------------------------*/

#include &lt;iostream&gt;      // For use of the cout function
#include &lt;cstdlib&gt;       // For use of the atoi function

using namespace std;

int main(int argc, char **argv)
{
  int total_numbers = argc - 1;
  if(total_numbers == 0) {
    cout &lt;&lt; "Usage: ./arrays NUMBER [MORENUMBERS]" &lt;&lt; endl;
    return(1);
  }

  // Initialize the array  
  int numbers[total_numbers];

  // Get the numbers from the command line arguments  
  for(int i=1; i&lt;argc; i++)
    numbers[i-1] = atoi(argv[i]);

  // Output the raw numbers provided  
  cout &lt;&lt; "Total amount of integers provided: " &lt;&lt; total_numbers &lt;&lt; endl;
  for(int i=0; i&lt;total_numbers; i++)
    cout &lt;&lt; "numbers[" &lt;&lt; i &lt;&lt; "]: " &lt;&lt; numbers[i] &lt;&lt; endl;

  return(0);
}
\end{fileverb}


%===================================================================
\newpage
\subsection{Solution to Exercise \ref{ex_arraytwo}}
\label{sol_ex_arraytwo}

\begin{fileverbs}
/*----------------------------------------------------------------------*/
/*  FILE:  arrays_nosmall.cpp  (Fourth C++ Lab Exercise 2)              */
/*  WGET:  wget http://oceanai.mit.edu/cpplabs/arrays_nosmall.cpp       */
/*  BUILD: g++ -o arrays_nosmall arrays_nosmall.cpp                     */
/*  RUN:   ./arrays_nosmall 23 11 98 32 2 23                            */
/*----------------------------------------------------------------------*/

#include &lt;iostream&gt;      // For use of the cout function
#include &lt;cstdlib&gt;       // For use of the atoi function

using namespace std;

int main(int argc, char **argv)
{
  int total_numbers = argc - 1;
  if(total_numbers == 0) {
    cout &lt;&lt; "Usage: ./arrays NUMBER [MORENUMBERS]" &lt;&lt; endl;
    return(1);
  }

  // Initialize the array  
  int numbers[total_numbers];

  // Get the numbers from the command line arguments 
  for(int i=1; i&lt;argc; i++)
    numbers[i-1] = atoi(argv[i]);

  // Output the raw numbers provided                                   
  cout &lt;&lt; "Total amount of integers provided: " &lt;&lt; total_numbers &lt;&lt; endl;
  for(int i=0; i&lt;total_numbers; i++)
    cout &lt;&lt; "  numbers[" &lt;&lt; i &lt;&lt; "]: " &lt;&lt; numbers[i] &lt;&lt; endl;

  // Find the smallest number in the array 
  int smallest = numbers[0];
  for(int i=1; i&lt;total_numbers; i++) {
    if(numbers[i] &lt; smallest)
      smallest = numbers[i];
  }

  // make a new array one size smaller
  int new_numbers[total_numbers-1];

  // Populate the new array with all but smallest number       
  int curr_index = 0;
  bool hit_smallest = false;
  for(int i=0; i&lt;total_numbers; i++) {
    if((numbers[i] == smallest) &amp;&amp; !hit_smallest)
      hit_smallest = true;
    else {
      new_numbers[curr_index] = numbers[i];
      curr_index++;
    }
  }

  // Output the new array (minus the smallest of the originals)
  cout &lt;&lt; "The new array of integers: " &lt;&lt; endl;
  for(int i=0; i&lt;total_numbers-1; i++)
    cout &lt;&lt; "  numbers[" &lt;&lt; i &lt;&lt; "]: " &lt;&lt; new_numbers[i] &lt;&lt; endl;

  return(0);
}
\end{fileverbs}


%===================================================================
\newpage
\subsection{Solution to Exercise \ref{ex_fileout}}
\label{sol_ex_fileout}

\begin{fileverb}
/*----------------------------------------------------------------------*/
/*  FILE:  fileout.cpp  (Fourth C++ Lab Exercise 3)                     */
/*  WGET:  wget http://oceanai.mit.edu/cpplabs/fileout.cpp              */
/*  BUILD: g++ -o fileout fileout.cpp                                   */
/*  RUN:   ./fileout --filename=test.txt one two three                  */
/*----------------------------------------------------------------------*/

#include &lt;iostream&gt;      // For the cout function
#include &lt;cstdio&gt;     	 // For the fopen, fclose and fprintf functions

using namespace std;

int main(int argc, char **argv)
{
  string filename;
  for(int i=1; i&lt;argc; i++) {
    string argi = argv[i];
    if(argi.find("--filename=") == 0)
      filename = argi.substr(11);
  }

  if(filename == "") {
    cout &lt;&lt; "Usage: fileout --filename=test.txt one two three" &lt;&lt; endl;
    return(1);
  }

  FILE *f = fopen(filename.c_str(), "w");
  if(!f) {
    cout &lt;&lt; "Unable to open file: " &lt;&lt; filename &lt;&lt; endl;
    return(1);
  }

  for(int i=1; i&lt;argc; i++) {
    string argi = argv[i];
    if(argi.find("--filename=") != 0)
      fprintf(f, "%s\n", argi.c_str());
  }

  fclose(f);
  return(0);
}
\end{fileverb}


%===================================================================
\newpage
\subsection{Solution to Exercise \ref{ex_filein}}
\label{sol_ex_filein}

\begin{fileverbs}
/*----------------------------------------------------------------------*/
/*  FILE:  filein.cpp  (Fourth C++ Lab Exercise 4)                      */
/*  WGET:  wget http://oceanai.mit.edu/cpplabs/filein.cpp               */
/*  BUILD: g++ -o filein filein.cpp                                     */
/*  RUN:   ./filein --filename=test.txt                                 */
/*----------------------------------------------------------------------*/

#include &lt;iostream&gt;      // For the cout function               
#include &lt;cstdio&gt;        // For the fopen, fclose, fgetc, feof functions

using namespace std;

int main(int argc, char **argv)
{
  // Find the name of the file to be read          
  string filename;
  for(int i=1; i&lt;argc; i++) {
    string argi = argv[i];
    if(argi.find("--filename=") == 0)
      filename = argi.substr(11);
  }

  // If no file specified, produce usage information and exit now.
  if(filename == "") {
    cout &lt;&lt; "Usage: filein --filename=test.txt" &lt;&lt; endl;
    return(1);
  }

  // Open the specified file for reading and exit with message if failed
  FILE *f = fopen(filename.c_str(), "r");
  if(!f) {
    cout &lt;&lt; "Unable to open file: " &lt;&lt; filename &lt;&lt; endl;
    return(1);
  }

  // Begin reading in file, ending only when end-of-file detected
  string str = "line: [";
  while(1) {
    int c = fgetc(f);

    if(feof(f))
      break;
    if(c == '\n') {
      str += "]";
      cout &lt;&lt; str &lt;&lt; endl;
      str = "line: [";
    }
    else
      str += c;
  }

  // Make sure we close the file
  fclose(f);
  return(0);
}
\end{fileverbs}
\normalsize

%===================================================================
\newpage
\subsection{Solution to Exercise \ref{ex_vectorone}}
\label{sol_ex_vectorone}

\begin{fileverbs}
/*----------------------------------------------------------------------*/
/*  FILE:  vectors_nosmall.cpp  (Fourth C++ Lab Exercise 5)             */
/*  WGET:  wget http://oceanai.mit.edu/cpplabs/vectors_nosmall.cpp      */
/*  BUILD: g++ -o vectors_nosmall vectors_nosmall.cpp                   */
/*  RUN:   ./vectors_nosmall 23 11 98 32 2 23                           */
/*----------------------------------------------------------------------*/

#include &lt;iostream&gt;      // For use of the cout function
#include &lt;cstdlib&gt;       // For use of the atoi function
#include &lt;vector&gt;        // For use of the STL vector class

using namespace std;

int main(int argc, char **argv)
{
  vector&lt;int&gt; numbers;
  // Get the numbers from the command line arguments
  for(int i=1; i&lt;argc; i++) 
    numbers.push_back(atoi(argv[i]));

  // Check if no numbers provided, exit if so.
  if(numbers.size() == 0) {
    cout &lt;&lt; "Usage: ./arrays NUMBER [MORENUMBERS]" &lt;&lt; endl;
    return(1);
  }

  // Output the raw numbers provided 
  cout &lt;&lt; "Total amount of integers provided: " &lt;&lt; numbers.size() &lt;&lt; endl;
  for(unsigned int i=0; i&lt;numbers.size(); i++)
    cout &lt;&lt; "numbers[" &lt;&lt; i &lt;&lt; "]: " &lt;&lt; numbers[i] &lt;&lt; endl;

  // Find the smallest number in the array
  int smallest = numbers[0];
  for(unsigned int i=1; i&lt;numbers.size(); i++) {
    if(numbers[i] &lt; smallest)
      smallest = numbers[i];
  }
  
  // make a new array one size smaller  // make a new vector
  vector&lt;int&gt; new_numbers;
  bool hit_smallest = false;
  for(unsigned int i=0; i&lt;numbers.size(); i++) {
    if((numbers[i] == smallest) &amp;&amp; !hit_smallest)
      hit_smallest = true;
    else 
      new_numbers.push_back(numbers[i]);
  }
  
  // Output the new array (minus the smallest of the originals) 
  for(unsigned int i=0; i&lt;new_numbers.size(); i++)
    cout &lt;&lt; "  numbers[" &lt;&lt; i &lt;&lt; "]: " &lt;&lt; new_numbers[i] &lt;&lt; endl; 

  return(0);
}
\end{fileverbs}

%===================================================================
\newpage
\subsection{Solution to Exercise \ref{ex_filebuff}}
\label{sol_ex_filebuff}

\begin{fileverb}
/*----------------------------------------------------------------------*/
/*  FILE:  filebuff_main.cpp  (Fourth C++ Lab Exercise 5)               */
/*  WGET:  wget http://oceanai.mit.edu/cpplabs/filebuff_main.cpp        */
/*  BUILD: g++ -o filebuff FileBuffer.cpp filebuff_main.cpp             */
/*  RUN:   ./filebuff --filename=test.txt                               */
/*----------------------------------------------------------------------*/

#include &lt;iostream&gt;      // For use of the cout function
#include &lt;vector&gt;        // For use of the STL vector class
#include "FileBuffer.h"

using namespace std;

int main(int argc, char **argv)
{
  // Find the name of the file to be read
  string filename;
  for(int i=1; i&lt;argc; i++) {
    string argi = argv[i];
    if(argi.find("--filename=") == 0)
      filename = argi.substr(11);
  }
  
  // If no file specified, produce usage information and exit now.
  if(filename == "") {
    cout &lt;&lt; "Usage: filein --filename=test.txt" &lt;&lt; endl;
    return(1);
  }

  vector&lt;string&gt; lines = fileBuffer(filename);
  
  cout &lt;&lt; "Total Lines: " &lt;&lt; lines.size() &lt;&lt; endl;
  for(unsigned int i=0; i&lt;lines.size(); i++) {
    if(lines[i].length() &gt; 0) 
      cout &lt;&lt; "line: [" &lt;&lt; lines[i] &lt;&lt; "]" &lt;&lt; endl; 
    else
      cout &lt;&lt; "line: Empty!" &lt;&lt; endl;
  }
  
  return(0);
}
\end{fileverb}

\begin{fileverb}
/*----------------------------------------------------------------------*/
/*  FILE:  FileBuffer.h                                                 */
/*  WGET:  wget http://oceanai.mit.edu/cpplabs/FileBuffer.h             */
/*----------------------------------------------------------------------*/

#ifndef FILE_BUFFER_HEADER
#define FILE_BUFFER_HEADER

#include &lt;vector&gt;
#include &lt;string&gt;

std::vector&lt;std::string&gt; fileBuffer(std::string);

#endif
\end{fileverb}

\begin{fileverb}
/*----------------------------------------------------------------------*/
/*  FILE:  FileBuffer.cpp                                               */
/*  WGET:  wget http://oceanai.mit.edu/cpplabs/FileBuffer.cpp           */
/*  BUILD: A utility meant to be built with other source code           */
/*         For example: g++ -o myprog FileBuffer.cpp main.cpp           */
/*----------------------------------------------------------------------*/

#include "FileBuffer.h"
#include &lt;cstdio&gt;

using namespace std;

vector&lt;string&gt; fileBuffer(string filename)
{
  // Create a vector of strings. In ANY case this is the return type
  vector&lt;string&gt; fvector;

  // Check that the file can be read. Return empty vector otherwise
  FILE *f = fopen(filename.c_str(), "r");
  if(!f)
    return(fvector);

  // Create a string buffer to hold each line. Reserve a big size to 
  // allow for efficient growth.
  string strbuff;
  strbuff.reserve(50000);

  // Read in the file one character at a time. Stopping only when the 
  // file pointer points to the end of file.
  while(1) {
    int intval = fgetc(f);
    char c = (char) intval;
    if(feof(f)) {
      if(strbuff.length() != 0)
        fvector.push_back(strbuff);
      break;
    }
    else if(c == '\n') {
      fvector.push_back(strbuff);
      strbuff.clear();
    }
    else
      strbuff.push_back(c);
  }

  // Make sure we close the file.
  fclose(f);

  return(fvector);
}
\end{fileverb}

\end{document}

</pre></body></html>