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
#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
• 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.
• 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.
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.