CPE2600 – Systems Programming (Solution)

$ 25.00
Category:

Description

Lab 4 Console Formatted IO
Objectives
• Work with a variety of C language syntax and practices for strings and formatted IO.
Topical Concepts
Command Line Arguments
This program will utilize a couple of simple command line arguments to control its behavior. We saw an example of this very early in the course. In order to utilize command line arguments, your main must accept two arguments (passed from the operating system’s command shell). The first argument is an integer that will tell you how many arguments were passed and the second argument will be an array of character pointers (char*) referencing each argument. Of special note, there is always at least one argument and that is the name of the program itself. Refer to the following example.
#include <stdio.h>
#include <string.h>

// note, argv is often char**, what is that? A double pointer? int main(int argc, char* argv[])
{ printf(“Number of args: %d “,argc);
for(int i=0; i<argc; i++)
{ printf(“Arg %d is %s “,i,argv[i]);
}

// a particular arg if(argc>1)
{
if(!strcmp(argv[1],”marco”))
{ printf(“Polo “);
}
}
return 0;
}
printf
We have seen printf used in a variety of examples. For routine usage, printf is easy enough. Just be sure to match the type and number of format specifiers to the type and number of additional arguments.
A feature of printf that is used a little less frequently is that it can establish fields and print justified within that field. This can be used to create nicely formatted tables. Consider the following example:
int main(int argc, char* argv[])
{ int rows = 5;

// make sure there is an arg if(argc>1)
{ rows=atoi(argv[1]);
} printf(“———————– “); for (int i=0; i<rows; i++)
{ printf(“|%10d|%10x| “,i,i);
} printf(“———————– “);
printf(“———————– “); for (int i=0; i<rows; i++)
{ printf(“|%-10d|%-10x| “,i,i);
} printf(“———————– “);
return 0;
}
When this is executed, you can see the effect of the field width and justification:

In addition to width and justification, there are a number of other options that can be applied to the format specifier.

Arrays
The basic usage and syntax of arrays was covered in lecture. Basic usage is simple enough. Where it can get tricky is working with strings. Often errors will go unnoticed for some time after a program is written. Also, occasionally you may wish to use an array in a less common capacity. The following example explores some less common usage of strings in character arrays.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

// Some “global” data arrays const char *help[] = {“Help text line 1″,”Help text line 2″,”More help text”,””}; const char info[][4] = {“NUL”,”BEL”,”EOR”,”FUN”,”END”}; // why 4?

// note, argv is often char**, what is that? A double pointer? int main(int argc, char* argv[])
{
// print out arrays int i = 0; while (strlen(help[i]))
{
// help is an array of char*… printf(“Line %d: %s “,i,help[i]); i++;
}

// if using 2 indexes, get a character printf(“Info [%d][%d]: %c “,1,1,info[1][1]);

// if using 1 index, you will basically get
// the address to the first element of that
// row. In this case, that is actaully char*
// and can use it like a string. printf(“Info %d: %s “,1,info[1]);

// OK, I said stay away from sizeof, but I cannot resist printf(“Sizeof Help: %zu “,sizeof(help)); printf(“Sizeof Info: %zu “,sizeof(info));

// Hmm…
printf(“Address of help[0]: %p “,&help[0]); printf(“Address of help[1]: %p “,&help[1]); printf(“Address of info[0]: %p “,&info[0][0]); printf(“Address of info[1]: %p “,&info[1][0]);
return 0;
}

The Assignment
Write an application which accept command line arguments to produce a variety of output. The following represents minimal expectations and you may embellish as you wish. Also keep in mind the background information above which provides some hints as to efficient implementation.
• When your program is invoked with no arguments, your program should print to the console a nicely formatted table of all 7-bit ASCII codes and characters (that is ASCII values from 0 to 127). At a minimum it should list each ASCII value in decimal, in hex, and the actual character. For non-printable characters, the customary mnemonics should be shown (i.e. NUL, SOH, STX, etc.)

The example below is an example of what might be a minimal expectation.

The printable characters can be generated directly from printf with a %c specifier. How about the mnemonics for the non-printable characters? You must store them in a data array that can easily be iterated.
• If your program is invoked with a ‘-c’ argument, the argument after the ‘-c’ will be interpreted as the number of columns the table should be. The example above shows eight columns which might be a suitable default. If the user has requested an unreasonable number of columns, your program can report that. Perhaps a range of 1 to 8 would be reasonable with 8 as the default if the -c option is not provided. What if a user supplies a -c but neglects to include a number as the next argument? This would be an error condition you should catch and handle.

• If your program is provided a single printable character as an argument, it should respond with the ASCII value of that character in decimal, hex, and 8-bit binary* presented to the user in an easy to read format.

* as discussed in lecture, there is not currently a printf specifier for binary conversions, although it is planned for C23 and is apparently available in newer versions of glibc. In any case, you must write a conversion routine yourself. The routine should accept a number as an argument and convert it to a string holding the binary representation. I would imagine the function will benefit from another argument to set the bit-width so that it can apply the proper number of leading zeros to the resulting string. The implementation details will be left up to you.

• Your program should be validating and verifying proper commands. For example, if the program is run with options ‘-c 100’ it is probably not reasonable. If an invalid command is detected, you have a couple of choices. Some programs will display a terse error message and exit. Some will display a general help message, and some programs will display a brief error message and run with default behavior. The choice of behavior is up to you.

• OPTIONAL – want to spiff up your output? Check out the topic of ANSI Escape Codes (ANSI escape code – Wikipedia). This is not a C feature per see, rather, it is how a terminal may respond to special sequences of characters printed to it. In this case, the non-printable character ESC (ASCII 27) kicks things off. After the terminal receives ESC, it will interpret the following characters in a particular format to control color, the cursor, and other effects. Check out the C example in the Wikipedia article and see if you can make your ASCII table pretty.
Implementation Details
To implement this program, I suggest two source (.c) files and at least one header file.
• main.c (or other suitable name) should contain main(), of course, and perhaps basic code to decipher the command line arguments.
• ainfo.c (or other suitable name) should contain code specific to this assignment – generating the table and single character information, etc.
Although not critical for this application, you must also supply a makefile to build your project. Be sure to also comply with the course coding standards.
Deliverable
You will demo your finished program during lab in Week 5. In addition, you will submit source code to Canvas by the end of Week 5.
Grading will be based on adherence to specifications, functionality, coding efficiency, and adherence to the coding standard.

Reviews

There are no reviews yet.

Be the first to review “CPE2600 – Systems Programming (Solution)”

Your email address will not be published. Required fields are marked *