< C++ .NET System::IO - Files 3 | Main | C++ .NET System::IO - Files 5 >


 

 

Working with Files 4

 

 

What we have in this page?

 

 

  1. Using TextReader...continue

 

 

The exercise that follows shows you how to write a program similar in functionality to the UNIX more command, which will read a file and echo its contents to the screen a few lines at a time. After it has displayed some lines, the user has the choice of pressing the Enter key to continue or pressing Q to quit.

 

1.        Create a new Visual C++ CLR Console Application project named CppReader.

 

Creating a new Visual C++ CLR Console Application project named CppReader

 

2.        Include a using declaration for System::IO at the top of the project.

using namespace System::IO;

 

Include a using namespace System::IO; declaration for System::IO at the top of the project

 

3.        Because the user is going to enter the name of the file to be listed on the command line, change the declaration of the main() function by deleting the argument managed array and use Environment::GetCommandLineArgs() to include the command line parameter arguments (that include the argc and argv), as shown here:

// Get the command line arguments

array<String^>^args = Environment::GetCommandLineArgs();

 

Using Environment::GetCommandLineArgs() to include the command line parameter arguments

 

If you haven’t met command-line arguments in a C or C++ program before, the main() function can optionally take two arguments. The first - traditionally named argc (argument counter) - is the number of command-line arguments, and the second - traditionally named argv (argument vector) - is an array of strings.

 

4.        Add code to main() to ensure that the user has entered a file name.

// Check for required arguments number...

if (args->Length < 2)

{

   Console::WriteLine(L"Usage: CppReader path");

    return 0;

}

// args[0] is the executable (filename)

String^ path = gcnew String(args[1]);

 

Adding code to main() to ensure that the user has entered a file name

 

If the user hasn’t given two arguments, an error message is printed and the program exits. If the user has, the second argument is saved for later use.

 

 

 

 

5.        Build and run your program at command prompt to test the command line argument. Test for single and double arguments.

 

Running a VC++ .NET program at command prompt to test the command line argument

 

6.        It’s wise to check that the path represents an existing file before continuing, so add the following code:

 

if (!File::Exists(path))

{

   Console::WriteLine(L"Invalid filename!");

   return -1;

}

else

   Console::WriteLine("The file exist!");

 

Checking that the path represents an existing file before continuing code

 

The File::Exists method checks whether a file with the specified name exists, returning false if it doesn’t. It will also return false if you give the name of a directory rather than a file. Note the return value of -1. It’s a common convention for C/C++ applications to return 0 to indicate success, with negative values being used to denote error conditions.

 

7.        Build and run your program to test the functionalities. Use any file name that exists in your current directory (the project’s debug directory).

 

Program output example to check a file existence

 

8.        Next, start to list the file. The first step is to create a FileStream and then connect it to a StreamReader.

try

{

   FileStream^ fs = gcnew FileStream(path, FileMode::Open);

   StreamReader^ sr = gcnew StreamReader(fs);

}

catch(System::Exception^ pe)

{

   Console::WriteLine(pe->ToString());

}

Code to list the files

 

In this case, you’re opening the file using FileMode::Open, which will throw an exception if the file doesn’t already exist.

 

9.        Listing the file content is done in this loop, which you should place after creating the StreamReader object, like the following. Add the code inside the try block.

 

int count = 0;

for(;;)

{

   String^ line  = sr->ReadLine();

   count++;

 

   // If there are no more lines, break out of the loop

   if (line == nullptr) break;

   Console::WriteLine(line);

 

   if (count % 20 == 0)

   {

         Console::Write(L"--more--");

         String^ response = Console::ReadLine();

         if (response->Equals(L"q")) break;

               count = 0;

   }

}

Console::WriteLine("-- end --");

 

Code for file content listing

 

The count variable is going to be used to count the lines as they’re read so that the program knows where to break. The loop reads a line into a String using the ReadLine function of StreamReader; if there are no more lines to read, a null pointer will be returned. The line is then echoed to the console and the count checked. We’ve set the number of lines displayed at one time to an arbitrary value of 20; when the count is exactly divisible by 20, the program writes “-- more--” to the console and waits for the user to input something. If the user presses a lowercase q, the program stops; otherwise, it outputs the next set of lines.

 

 

 

 

The complete main() code is given below.

int main()

{

   // Get the command line arguments

   array<String^>^args = Environment::GetCommandLineArgs();

 

    // Check for required arguments number...

   if (args->Length < 2)

   {

         Console::WriteLine(L"Usage: CppReader path");

       return 0;

   }

   // args[0] is the executable (filename)

   String^ path = gcnew String(args[1]);

 

   if (!File::Exists(path))

   {

         Console::WriteLine(L"Invalid filename!");

         return -1;

   }

   else

         Console::WriteLine("The file exist!");

 

   try

         {

               FileStream^ fs = gcnew FileStream(path, FileMode::Open);

               StreamReader^ sr = gcnew StreamReader(fs);

 

               int count = 0;

               for(;;)

               {

                     String^ line  = sr->ReadLine();

                     count++;

 

                     // If there are no more lines, break out of the loop

                     if (line == nullptr) break;

                     Console::WriteLine(line);

 

                     if (count % 20 == 0)

                     {

                           Console::Write(L"--more--");

                           String^ response = Console::ReadLine();

                           if (response->Equals(L"q")) break;

                           count = 0;

                     }

               }

               Console::WriteLine("-- end --");

         }

   catch(System::Exception^ pe)

         {

               Console::WriteLine(pe->ToString());

         }

   return 0;

}

 

10.     Build and run your program, giving the name of a suitable text file as the argument from any location (by providing full path to the file). The following example shows opening a setup.log file under the C:. Don’t forget to try text files that having larger content.

 

Displaying file content output program example

 

 

Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6 | Part 7

 

 


< C++ .NET System::IO - Files 3 | Main | C++ .NET System::IO - Files 5 >