CSc 352, Fall 2002: Assignment 3: C Programming: Arrays and Strings

Out: Thu Sept 19

Due: 12:00 Noon Thu Sept 26


You are to create a number of files, as directed below, and then submit them electronically on host lectura.cs.arizona.edu using the command

turnin cs352_hw3 files

Please follow the directions below carefully: submissions that don't follow directions will be penalized heavily.

Note:

  1. Each of the programs below should exit with a status of 0 if execution proceeds normally, and a status of -1 if any sort of error occurs.

    Under csh and tcsh you can check the exit status of a command or program cmd by typing the command echo $status immediately after the execution of cmd. A program can exit with status n by executing the system call exit(n), or -- in the function main() only -- executing the statement return n.

  2. Your programs should compile with no errors or warnings when compiled with gcc -Wall.


  1. Define a string S to be ascending if the letters in S occur in ascending order, i.e., if i > j then the ith character of the string S occurs later in the ASCII character sequence than the jth character of S. For example, the strings best and filmy are ascending, while beast and system are not.

    Write a program, in a file ascending.c, that reads in strings, one per line, from stdin, until an end-of-file is encountered; and for each string S so read, prints out `S is ascending' if S is an ascending string, and `S is not ascending' if it is not. You may assume that an input string is not more than 64 characters long.

    Your program should be able to handle non-alpha-numeric strings, e.g., something like `~!@#$%^ wascally wabbit!'.

  2. Two words are said to be anagrams of each other if the letters of one can be rearranged to form the other. For example, snap and pans are anagrams, but snap and snaps are not.

    Write a C program, in a file anagram.c, that reads in two strings and checks to see whether they are anagrams. If they are anagrams, it exits with status 0, otherwise it exits with status 1. If an error occurs (e.g., if not enough input strings are provided) it exits with status -1.

    You may assume that the input strings consist only of letters, i.e., do not contain digits or any other characters, and that each input string is at most 64 characters long.

    Your program should ignore the distinction between upper-case and lower-case letters, i.e., the strings sNaP and pAnS should be treated as anagrams. See the library functions toupper() and/or tolower().

    Hint: The simplest way to do this is to first convert both strings to the same case, then for each string count how many times each letter occurs in the string, and finally compare these counts.

  3. Ancient Romans used a numbering scheme that used the following letters as numerals:
    Roman NumeralValue
    I1
    V5
    X10
    L50
    C100
    D500
    M1000
    Other numbers were formed from these by adding or subtracting, according to the following rules. Here, value(x) refers to the value of the symbol x according to the table above.
    1. If a letter x comes immediately to the left of a letter y, and
      value(y) <= value(x)
      then value(xy) = value(y) + value(x).

      For example, the value of `VI' is 5+1 = 6, and that of `XX' is 10+10 = 20.

    2. If a letter x comes immediately to the left of a letter y, and
      value(y) > value(x)
      then value(xy) = value(y) - value(x).

      For example, the value of `IX' is 10-1 = 9.

    3. For longer strings, we apply these rules going from right to left, comparing adjacent characters in each case and adding or subtracting the value of the current character and the value of the characters we have seen so far, according to the rules shown above.

      For example, the value of `CMXVI' is computed as follows: working from right to left:

      1. I evaluates to 1.
      2. VI evaluates to 5+1 = 6, using rule 1 above.
      3. To evaluate XVI, we compare X (the character we're currently looking at) with V the last character we looked at: in this case, rule 1 above applies. So we add 10 (the value of X) with 6 (the value we have so far), to get the value of XVI = 16.
      4. To evaluate MXVI, we compare M (the current character) with X (the last character). Since X < M, rule 1 above applies. So the value of MXVI is obtained as 1000 + 16 = 1016.
      5. To evaluate CMXVI we compare C (the current character) with M (the last character). Since M > C, rule 2 above applies. So the value of CMXVI is obtained as 1016 - 100 = 916.
      Write a C program, in a file roman.c, that repeatedly reads in a string from stdin that is a Roman number, and prints out (only!) its decimal value, until EOF is encountered.

      If an input string contains any characters other than those given above, your program should give an appropriate error message and exit with status -1.

      You may assume that the input strings can be at most 16 characters long. (Strictly speaking, there are additional rules that specify what strings of Roman numerals are legal: e.g., IIIIIIIII is not a legal Roman number: it has to be written as IX. You need not worry about this aspect of Roman numbers.)