All Products | Support | Search | microsoft.com Guide
 MSDN Academic Alliance Home | Facts Page | Contact Us | Worldwide |
MSDNAA Search
Advanced Search
Related Links:
GotDotNet Student
MainFunction
INETA



Visit GotDotNet

Newsgroup Banner

Getting Started with Visual C++.NET


Printer Friendly Version

Table of Contents

Introduction
(1) Starting Projects
(2) Hello, World!
(3) Program Structure
(4) Console Input
(5) Using Arrays
(6) File Input/Output
(7) Creating Functions
(8) Using Debugger
Conclusion


Source Code
Download Project Files
Executable Files

Through the addition of managed extensions, Visual C++ now supports .NET development while also having the power of unmanaged code. C/C++ is still intact but new features have been added to simplify .NET programming in C++. If you want to learn about developing unmanaged code, please see the Getting Started with Visual C++ guide instead.

General Description

This sample application demonstrates how to build a simple C++.NET project that implements the QuickSort algorithm. It covers the basic components of a C++.NET program, reading/writing to the console and files, creating functions, and using basic arrays.

The Getting Started guides are not meant to cover all aspects of the programming language. They are meant to give you a starting point for exploring the language. You are encouraged to follow along as the tutorial covers the different pieces of the QuickSort application. The complete source code and project files are also available.

Suggested Requirements

Visual Studio.NET (Beta 2 or later) is required to compile the sample application. Knowledge of C/C++ would be very helpful but not required.

 

back to top


Step 1. Starting Projects

Development in Visual Studio is organized around solutions, which contain one or more projects. For this tutorial, we will create a solution with a single C++ project.

Creating a New Project

  1. In the Visual Studio.NET environment, select File | New | Project from the menu.

  2. Select Visual C++ on the left and then Managed C++ Application on the right.

  3. Specify the name of your project and enter the location in which to create the project. The project directory will be created automatically by Visual Studio.

  4. Click OK and you're on your way!

Your Visual C++ Solution

Visual Studio.NET has created a solution with one simple Visual C++ project. The project contains several files, including assemblyinfo.cpp and quicksort.cpp.

The next few steps discuss these different files and how to compile the project.

 

back to top


Step 2. Hello, World!

We're sorry but we just couldn't resist the temptation... We just have to do the classic "Hello, World!" application that was first written in the C language.

Source Code Modifications

  1. Double-click the file 'quicksort.cpp' in the Solution Explorer. You can display the Solution Explorer using the View menu.
  2. Make the changes highlighted in red to the pre-generated template (quicksort.cpp).

    // This is the main project file for VC++ application project
    // generated using an Application Wizard.

    #include "stdafx.h"

    #using <mscorlib.dll>

    using namespace System;

    // This is the entry point for this application
    #ifdef _UNICODE
    int wmain(void)
    #else
    int main(void)
    #endif
    {
        // TODO: Please replace the sample code below with your own.
        Console::WriteLine ("Hello, C++.NET World!");
        return 0;
    }

  3. Notice that as you type, Visual Studio will help you with the names of classes and functions, since the .NET Framework publishes the type information.

Compiling Your Application

  1. Now that you have made your modifications, you can compile the Visual C++ project by simplying selecting Build in the Build menu.

  2. Errors and messages from the C++ compiler will be displayed in the Output window. If there were no errors, you can run the Hello World application by clicking Start without Debugging under the Debug menu.

Program Output

This is a screenshot of the output from the Hello World sample application when run from the Visual Studio environment.

Understanding the Changes

The WriteLine() function of the System::Console class prints the string passed to it followed by a single new line character. The function can take a number of other data types including integers and floating-point numbers.

Control passes to the wmain() function after the program has been loaded. That is why we insert the call to WriteLine() in the procedure.

 

back to top


Step 3. Program Structure

Now that we have built a simple Hello World application, let us stop and examine the basic components of a Visual C++ application.

Source Code Comments

The characters // marks the rest of the line as a comment so it is ignored by the C/C++ compiler. In addition, code surrounded by /* and */ are also treated as comments.

// This line is ignored by the compiler.
/* This block of text is also
ignored by the Visual C++ compiler. */

The Using Directive

The .NET Framework provides a number of useful classes to the developer. For instance, the Console class handles input and output to the console window. These classes are organized in a hierarchical tree. The fully qualified name of the Console class is actually System::Console. Other classes include System::IO::FileStream and System::Collections::Queue.

The using namespace directive permits you to reference classes in the namespace without using a fully qualified name. The code highlighted in red applies the using namespace directive.

#include <stdafx.h> // optional in an empty C++ project
#using <mscorlib.dll>
using namespace System;

int wmain ()
{
    System::Console::WriteLine ("Hello, C++.NET World!");
    Console::WriteLine ("Hello, C++.NET World!");
    return 0;
}

Note that the statement #using <mscorlib.dll> is required in all Visual C++.NET files that require the use of managed code.

The wmain() Function

The wmain() function receives control after the application is loaded into memory, so your application startup code should be placed in this function.

 

back to top


Step 4. Console Input

Now we will proceed to develop our QuickSort application. The first thing we will need to do is to prompt the user for the input and output files.

Source Code Modifications

  1. Make the changes highlighted in red to the C++ source file (quicksort.cpp). Other discrepancies such as the class name are insignificant.

    // Import namespaces
    #include <stdafx.h> // optional in empty C++ project
    #using <mscorlib.dll>
    using namespace System;

    // Application initialization
    int wmain ()
    {
        // Describe program function
        Console::WriteLine ("QuickSort C++.NET Sample Application\n");

        // Prompt user for filenames
        Console::Write ("Source: ");
        String* szSrcFile = Console::ReadLine ();
        Console::Write ("Output: ");
        String* szDestFile = Console::ReadLine ();

        // Return success
        return 0;
    }

Reading from Console

The static ReadLine() function of the Console class prompts the user for input and returns the string that was entered. It automatically handles the memory allocation for the string, and with the .NET garbage collector, you do not need to do anything to de-allocate the memory.

Program Output

Run your program by selecting Debug | Start Without Debugging from the menus. This is a screenshot of the output from the QuickSort application so far.

 

back to top


Step 5. Using Arrays

The program will need to store the lines that it reads from the input in an array before sorting them. We will briefly discuss the use of a .NET base class that implements arrays of objects.

Source Code Modifications

  1. Make the changes highlighted in red to the C++ source file (quicksort.cpp). Other discrepancies such as the class name are insignificant.

    // Import namespaces
    #include <stdafx.h> // optional in empty C++ project
    #using <mscorlib.dll>
    using namespace System;
    using namespace System::Collections;

    // Application initialization
    int wmain ()
    {
        // Describe program function
        Console::WriteLine ("QuickSort C++.NET Sample Application\n");

        // Prompt user for filenames
        Console::Write ("Source: ");
        String* szSrcFile = Console::ReadLine ();
        Console::Write ("Output: ");
        String* szDestFile = Console::ReadLine ();

        // TODO: Read contents of source file
        ArrayList* szContents = new ArrayList ();

        // Return success
        return 0;
    }

Using the ArrayList Class

We import the System::Collections namespace so we can directly refer to ArrayList. This class implements a dynamically sizable array of objects. To insert a new element, simply pass the object to the Add() method of the ArrayList class. The new array element will reference the original object and the garbage collector will handle its deallocation.

String* szElement = new String ("insert-me");
ArrayList* szArray = new ArrayList ();
szArray->Add (szElement);

To retrieve an existing element, pass the index of the desired element to the get_Item() method. You cannot use the square brackets operator [] since it would treat szArray as a pointer to an array, which would not correctly call into the .NET framework.

Console::WriteLine (szArray->get_Item (2));

There are many other methods in the ArrayList class, but insertion and retrieval is all we need for this example. Refer to the MSDN Library for the complete reference guide.

 

back to top


Step 6. File Input/Output

Now let us implement the reading of the input file and the writing to the output file. We will read each line into a string array and then output that string array. In the next step, we will use the QuickSort algorithm to sort the array.

Source Code Modifications

  1. Make the changes highlighted in red to the C++ source file (quicksort.cpp). Other discrepancies such as the class name are insignificant.

    // Import namespaces
    #include <stdafx.h> // optional in empty C++ project
    #using <mscorlib.dll>
    using namespace System;
    using namespace System::Collections;
    using namespace System::IO;

    // Application initialization
    int wmain ()
    {
        ... ... ...

        // Read contents of source file
        String* szSrcLine;
        ArrayList* szContents = new ArrayList ();
        FileStream* fsInput = new FileStream (szSrcFile, FileMode::Open,
            FileAccess::Read);
        StreamReader* srInput = new StreamReader (fsInput);
        while (szSrcLine = srInput->ReadLine ())
        {
            // Append to array
            szContents->Add (szSrcLine);
        }
        srInput->Close ();
        fsInput->Close ();

        // TODO: Pass to QuickSort function

        // Write sorted lines
        FileStream* fsOutput = new FileStream (szDestFile, FileMode::Create,
            FileAccess::Write);
        StreamWriter* srOutput = new StreamWriter (fsOutput);
        for (int nIndex = 0; nIndex < szContents->Count; nIndex++)
        {
            // Write line to output file
            srOutput->WriteLine (dynamic_cast<String*>
            (szContents->get_Item (nIndex)));
        }
        srOutput->Close ();
        fsOutput->Close ();

        // Report program success
        Console::WriteLine ("\nThe sorted lines have been written.\n\n");
        return 0;
    }

Reading from Source File

We use the FileStream class to open the source file and then we attach a StreamReader class so that we can use its ReadLine() method. Now we call the ReadLine() method until it returns NULL (zero), which indicates an end-of-file condition. During the loop, we store the read lines into our string array and then close both objects.

Writing to Output File

We assume that the string array has been sorted by QuickSort and proceed to output the contents of the array. In a similar fashion, we attach a StreamWriter object to a FileStream object. This allows us to use the WriteLine() method, which conveniently resembles that of the Console class. Once we've iterated through the array, we close the two objects as before.

 

back to top


Step 7. Creating Functions

The final step is to create a function that runs QuickSort on an array of strings. We will place the function within the application class QuickSortApp.

Source Code Modifications

  1. Make the changes highlighted in red to the C++ source file (quicksort.cpp). Other discrepancies such as the class name are insignificant.

    // Import namespaces
    #include <stdafx.h> // optional in empty C++ project
    #using <mscorlib.dll>
    using namespace System;
    using namespace System::Collections;
    using namespace System::IO;

    // Declare function prototypes
    void QuickSort (ArrayList* szArray, int nLower, int nUpper);
    int Partition (ArrayList* szArray, int nLower, int nUpper);

    // Application initialization
    int wmain ()
    {
        ... ... ...

        // Pass to QuickSort function
        QuickSort (szContents, 0, szContents->Count - 1);

        ... ... ...
    }

    // QuickSort implementation
    void QuickSort (ArrayList* szArray, int nLower, int nUpper)
    {
        // Check for non-base case
        if (nLower < nUpper)
        {
            // Split and sort partitions
            int nSplit = Partition (szArray, nLower, nUpper);
            QuickSort (szArray, nLower, nSplit - 1);
            QuickSort (szArray, nSplit + 1, nUpper);
        }
    }

    // QuickSort partition implementation
    int Partition (ArrayList* szArray, int nLower, int nUpper)
    {
        // Pivot with first element
        int nLeft = nLower + 1;
        String* szPivot = dynamic_cast<String*> (szArray->get_Item (nLower));
        int nRight = nUpper;

        // Partition array elements
        Object* szSwap;
        while (nLeft <= nRight)
        {
            // Find item out of place
            while (nLeft <= nRight)
            {
                String* szFetch = dynamic_cast<String*>
                    (szArray->get_Item (nLeft));
                if (szFetch->CompareTo (szPivot) > 0)
                    break;
                nLeft = nLeft + 1;
            }
            while (nLeft <= nRight)
            {
                String* szFetch = dynamic_cast<String*>
                    (szArray->get_Item (nRight));
                if (szFetch->CompareTo (szPivot) <= 0)
                    break;
                nRight = nRight - 1;
            }

            // Swap values if necessary
            if (nLeft < nRight)
            {
                szSwap = szArray->get_Item (nLeft);
                szArray->set_Item (nLeft, szArray->get_Item (nRight));
                szArray->set_Item (nRight, szSwap);
                nLeft = nLeft + 1;
                nRight = nRight - 1;
            }
        }

        // Move pivot element
        szSwap = szArray->get_Item (nLower);
        szArray->set_Item (nLower, szArray->get_Item (nRight));
        szArray->set_Item (nRight, szSwap);
        return nRight;
    }

The QuickSort() Function

This function requires three parameters: a reference to the array, the lower bound, and upper bound. It calls the Partition() function to divide the array into two pieces, where one contains all strings before a pivot value and the other contains all strings after. And then it calls itself to sort each of the two pieces.

The comments in the modifications above should explain what each block of code does. The only new concept is the use of the CompareTo() method, which is a member of the String class, and that should be self-explanatory.

Running the QuickSort Application

This step completes the QuickSort C++.NET sample application. Now you can build your project and run the application. You will need to provide a sample text file for it to sort. Place that file in the same directory as the EXE file.

If you run the program from within the Visual Studio environment, the current directory will be the project folder. So you must place the sample text file there instead of the 'debug' folder.

Program Output

Here is the output from the completed QuickSort C++.NET sample application. You can view the sample input file 'example.txt' and output file 'output.txt'.

 

back to top


Step 8. Using Debugger

The debugger is an essential tool for diagnosing problems with your programs. We felt that it was important enough to cover in this Getting Started guide. This last step will show you how to walk through your program and use features such as QuickWatch.

Setting Breakpoints

When a program is running in the debugger, a breakpoint will halt execution and give the developer control of the debugger. To set a breakpoint, right-click the line you want the program to halt at and click Insert Breakpoint as shown below.

Lines with a breakpoint are highlighted in red. You can remove a breakpoint by right-clicking the line again and selecting Remove Breakpoint.

Stepping Through a Program

Now with a breakpoint set (preferably on the line shown above), let us run the program in the debugger. In the Debug menu, select Start instead of Start Without Debugging as we did earlier. This starts your program in the debugger, thus breakpoints will enabled.

Once the program hits your breakpoint, the debugger receives control of the program. There will be an arrow pointing to the current line of execution.

To step through one line of code, select Debug | Step Over and watch the cursor move to the next line. The Debug | Step Into command allows you to step into a function that is about to be called. This is what the screen looks like after Step Over two times.

If you want the program to resume execution until it hits another breakpoint, encounters an exception, or exits, select Debug | Continue from the menu.

Inspecting Variable Values

While you have control of the debugger, you can move your mouse cursor over a variable to obtain its basic value.

You can also right-click the variable and select QuickWatch from the context menu. The QuickWatch gives you greater detail for certain variables, such as an ArrayList object.

Other Debugger Tools

The Visual Studio debugger features a number of other tools such as a Call Stack viewer, which you can use to see what functions have been called so far. You can also obtain memory dumps and information on the threads in the process. We encourage you to make use of these very powerful debugging tools.

 

back to top


Conclusion & Further Reading

The intent of this Getting Started guide was to help you build a simple C++ project in Visual Studio. In no way is it comprehensive. We encourage you to seek other resources on C++ and .NET to learn more about these technologies. Having finished this tutorial, at least you have a working project and can start modifying this code as you explore Visual C++.

We have provided the complete source code and project files for your convenience. They can be accessed via the table of contents at the top of this page.

Further Reading

We highly recommend these books on C++ and the .NET platform. They are good resources for developers trying to learn these new technologies.

Deitel, Harvey. C++: How to Program, 3rd ed. Upper Saddle River, NJ: Prentice Hall, 2001.

Platt, David. Introducing Microsoft .NET. Redmond: Microsoft Press, 2001.

back to top

2002 Microsoft Corporation. All rights reserved. Terms of Use | Privacy Statement | Accessibility