------------------------------------------------------------------------------
MC logo
Running C and C++ Programs
[^] CSc 220: C and C++ Programming
------------------------------------------------------------------------------
Linux Environment
Windows Environment
I/O Redirection
Run-Time Errors
Some Unix Commands
The C language is a whole lot older than GUI programming, Windows, or the PC. Its natural environment is running text-based programs from the command line. There is no standard windowing system for C, though many are available as extra libraries. C's history is tied and Unix, and it runs very happily in that environment. On the PC, C compilers have been available since the DOS days. The C++ refinement is newer, and has grown up in both places.

Linux Environment

These days, the most common version of the Unix environment is found in Linux (which is actually a Unix clone). It is available for free. Some leading distributors are
Fedora and Ubuntu. There is also a distribution called Knoppix which runs directly from a CD. It can also be installed on a hard drive along side Windows without re-partitioning. Linux distributions come well-equipped with programming tools, including the C and C++ compiler. And pretty much anything else you need.

If you don't have your own Linux, you can use the Department's Linux server, Sandbox. Your instructor can get you a Sandbox account if you want one and don't have one. You can connect to Sandbox using the ssh protocol. A Linux install will come with the needed client; if you're using Windows you will can get Putty. Connect to sandbox.mc.edu and log in to run commands.

C or C++ programs are plain text files. To create one, simply fire up you favorite text editor. Linux comes with several, both graphical and text-based. If you're using Sandbox, you'll have to live with text-based. The simplest one of these is called pico. Log on with putty, and use the pico command to start the text editor. This brings up a screen into which you may enter and modify your program. When pico is running, the characters which you type become part of the program you are creating. To give commands to pico, you must enter a control character by holding down the Ctrl key and pressing another character. The list of available commands is shown at the bottom of pico's screen while it is running; for instance, Control-O is the command to write your changes to disk.

Other text-based editors are vi and emacs, both more capable than pico, and with a steeper learning curve. Linux graphical editors include the simple gedit, or many others.

An alternative is to edit your file locally and send it to Sandbox. If you're coming from Windows, a nice program is called WinSCP. This allows you manipulate files on Sandbox using the file explorer as though they were local. You can edit them locally, and the program saves them on Sandbox. (Note: Sandbox doesn't support FTP anymore. You must tell WinSCP to use the SCP or SFTP protocols.)

However you edit, whether running on your own machine or on Sandbox, save your file with a name ending in .c for plain C, or .cpp for C++, like fred.c or sally.cpp. After saving, get to a command prompt. If you're using pico, you can just exit, but it usually makes sense to have a separate window for commands. If you're connecting remotely, just make a second connection. On your own machine, just fire up a command shell window. (There is a summary of common Unix commands below.) To compile a C program named fred.c, say:

[bennet@sandbox test]$ gcc fred.c

(Of course, [bennet@sandbox test]$ is the prompt; you type the rest.) To compile a C++ program, say

[bennet@sandbox test]$ g++ fred.cc

The g++ command actually runs the same compiler as gcc, but with different options directing it to compile C++. (You can compile C++ programs with the gcc command if you know a bunch of obscure options to type on the command line, or you can just let g++ do it for you.)

If the compiler finds an error in your program, it will print appropriate messages; re-edit and re-compile to repair the error. If there are no problems, the compiler will produce an executable file with the not-too-obvious name a.out. This contains the translation of your program into machine language. To run the program, simply type a.out:

[bennet@sandbox test]$ a.out The program will read any input from the keyboard, and write output to the screen (but see below).

Windows Environment

Windows comes well-equipped for word processing and solitaire, but it is just barely possible to write programs with it. C compilers are available for Windows; the most popular free one is probably Dev-C++. Dev-C++ itself is actually the development environment. Make sure to get the edition that includes Mingw/GCC, which is the compiler. This is a Windows port of the same compiler used on Linux systems. The install is straightforward.

To create a program, use File/New/Source File. (Happily, Dev-C++ doesn't force you to create a project when all you want is one file.) Edit your file and save it some place you can find. It's not a bad idea to create a folder for your C code.

You can compile your program from the Execute/Compile. You can also run it from Execute/Run, but that won't work well for most of what we'll write in class, since the programs run in a window which pops up and disappears along with your output. You will want to start a command shell, and change to the folder where your program is stored. Programs compile to plain .exe files with the same stem as the original program; fred.cpp compiles to fred.exe. You can run them simply by simply typing the file name:

Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\Documents and Settings\bennet>cd Desktop\C

C:\Documents and Settings\bennet\Desktop\C>dir
 Volume in drive C has no label.
 Volume Serial Number is 31D0-F15C

 Directory of C:\Documents and Settings\bennet\Desktop\C

08/21/2007  12:32 PM    <DIR>          .
08/21/2007  12:32 PM    <DIR>          ..
08/21/2007  12:31 PM                97 fred.cpp
08/21/2007  12:32 PM           474,990 fred.exe
               2 File(s)        475,087 bytes
               2 Dir(s)  35,202,727,936 bytes free

C:\Documents and Settings\bennet\Desktop\C>type fred.cpp
#include <iostream>
using namespace std;
main()
{
      cout << "Hello, World!" << endl;
}

C:\Documents and Settings\bennet\Desktop\C>fred
Hello, World!

C:\Documents and Settings\bennet\Desktop\C>

I/O Redirection

One of the command-line joys is file redirection. We will use that often in class. This was created as part of Unix (adapted from Multics), and was copied by DOS and successor command shells on Windows.

By default, the standard input facilities, such as C scanf or C++ cin, read characters from the keyboard. Likewise, standard output commands print onto the screen. Either (or both) of these can be changed by specifying an input or output redirection. For instance, if you run your program with:

[bennet@sandbox test]$ a.out < in.txt
your program will read from the file named in.txt instead of reading from the keyboard. No change in your program is required. The Windows command shell does the same thing, except you have the distinctive program name instead of a.out:
C:\Documents and Settings\bennet\Desktop\C>fred < in.txt
The same program can be run reading from the keyboard or from a file, depending on the presence of the redirection specification, < in.txt. Likewise, the program can be run so that its output will be placed in a file rather than printed on the terminal. For instance,
[bennet@sandbox test]$ a.out > results.txt
will write its output to the file results.txt, rather than the screen. Input redirection can be useful when you have a long test input you don't wish to type every time you run the program. You can use the text editor to place the input into a file, then run your program any number of times reading from that file. Output redirection can be helpful when you have a long output you wish to check carefully. After you create a file of your output, you can examine it with a text editor, or print it out.

Redirection is more flexible and convenient than having to read or write a file explicitly in a program. The programmer will have to get a file name from the command line or input, open it, and report failure. Even with this extra work, the program is still less flexible, since redirection can be to other places than files: one program's output can become the input of another program, or a program can be connected to a local or network stream.

Run-Time Errors

Even if your program compiles correctly, it may not run correctly. This may simply result in incorrect output, or it may result in a run-time error. The error messages produced by the C runtime system are particularly un-helpful. Here's what Unix tells you:

[bennet@sandbox test]$ gcc fred.c
[bennet@sandbox test]$ a.out
Segmentation fault (core dumped)
[bennet@sandbox test]$ 

The notation "core dumped" tells you that the system left a core file in your working directory. It's named core.nnnn, where nnnn is the process number your program had while it was alive. A core file can be read by the debugger; if you don't plan to use it, they are safe to delete.

The Windows version at right is no more helpful, but somewhat more amusing. (Do you suppose that, if you send it a report, Microsoft will tell you what's wrong with your program?)

In either case, there's not much more than "sorry, it broke." One improvement is to add debugging output to your program. If you do, be careful because core dumps and output redirection don't always mix well. Sometimes part of your output gets lost on the way to the file when the program does not terminate normally. This may lead you to believe the program died earlier than it actually did. If you need to capture debugging output before a core dump, you may want to use the script command.

Or, you can use the debugger, gdb. It can be used directly with the gdb command (on Windows you have to set the path first). But it's common to use it indirectly. On Sandbox, you might try the postmortem program, like this:

[bennet@sandbox test]$ gcc boom.c
[bennet@sandbox test]$ a.out
Segmentation fault (core dumped)
[bennet@sandbox test]$ postmortem
Fatal error: #11: Segmentation fault.  Usually a bad pointer or subscript.
Call stack follows.  Program died on line listed first.
  Line 1259 in vfprintf.c: Func _IO_vfprintf
  Line 31 in printf.c: Func printf
  Line ??? in ???: Func main
  Line 92 in libc-start.c: Func __libc_start_main
Recompile with -g for more line number information.
Suggestion: Check the arguments to your printf call(s).
[bennet@sandbox test]$ 

Postmortem is showing that the program died at line 1259 in file vfprintf.c, while running the function _IO_vfprintf. This is a system library function which was called from function printf at line 31, which was called from function main in my program. But note that the line in the program is not given. To get such information, you should compile your program with the -g option. The postmortem program suggests this. That looks like this:

[bennet@sandbox test]$ gcc -g boom.c
[bennet@sandbox test]$ a.out
Segmentation fault (core dumped)
bennet 1006%postmortem
Fatal error: #11: Segmentation fault.  Usually a bad pointer or subscript.
Call stack follows.  Program died on line listed first.
  Line 1259 in vfprintf.c: Func _IO_vfprintf
  Line 31 in printf.c: Func printf
 >Line 4 in boom.c: Func main
Suggestion: Check the arguments to your printf call(s).
[bennet@sandbox test]$ 

Much better. The -g option tells the compiler to leave extra information in the a.out file which postmortem can use. In fact, line 4 of boom.c is

printf("%s", 17);

which causes the program to die.

With Dev-C++, use Debug/Debug. If you haven't use the -g flag on your compile, it will offer to rebuild for you. You'll want to accept the offer. Then it will run the program and you'll see a pop-up message not unlike the Unix one. You can clear this, and and click on the Backtrace tab near the bottom to show where the error occurs. (Make sure to go back to the Debug sub-tab and say Stop Execution when you are done, so Dev-C++ will do other stuff for you.)

The debugger can do a number of other things for you, such as single stepping and setting break points. These are available as tabs in Dev-C++, or as sub-commands if you run gdb under Linux or Windows. Use the help command to find out about the others. If you're running Linux locally, you can also use one of the GUI wrappers for GDB, such as ddd or kdbg.

Some Unix Commands

Here are a few Unix commands which you may find useful if you are running on Sandbox or on your own system.
logout
This is how you leave the system.
ls
This lists all the files in the current directory. It is like the DOS dir command.
mkdir
This creates a new directory. Say mkdir dirname to create a new directory named dirname. Directories are the same thing as folders in Windows terminology. They allow you to collect related files in one place.
cd
Commands apply to files in the "current directory". The command cd dir changes the current directory to be dir.
rm
This deletes files; say rm fn to delete the file named fn. This is like DOS delete. The name stands for "remove".
script
The script command places a script of your session into a file, which you can then edit or print. Everything you type, and everything the computer types, exactly as it appears on the screen, is placed into the file. To use it, just say script, and you will get a message and your prompt back, as:

[bennet@sandbox test]$ script
Script started, file is typescript
[bennet@sandbox test]$ 

Now, everything that happens is recorded in the file typescript. Recording ends when you give the command exit.

[bennet@sandbox test]$ exit
[bennet@sandbox test]$ Script done, file is typescript
[bennet@sandbox test]$ 

(Note that the "Script done..." line was typed by the computer. It is not a command). You can now examine typescript with any text editor, or print it. You should not try to work with the typescript file until you have given the exit command.

man
man -k
apropos
The man command documents other commands. Say man command to get information about command. To find out what commands might be available, you can try man -k topic, and you will get a list of commands related to the topic. Apropos is the same as man -k.
info
The info command is the Free Software Foundation's documentation tool. Not every command or program is documented here, but many are, and the documentation is usually quite thorough, including everything you could ever possibly want to know about emacs or gcc. Say info to reach the main topic menu. Say info info for help using the info program itself.
lpr fn
pr fn | lpr
pr -n fn | lpr
The lpr command prints the file. Just say lpr fn, and the file named fn will appear on the nearest printer. The command pr fn | lpr adds some pretty headers and page numbers to each page. The command pr -n fn | lpr also numbers the lines. This is useful when you are trying to find where an error message refers.