Skip to main content

Exercises 2.16 Programming Exercises

1.

Modify the program in Listing 2.15.2 so that it prompts the user to enter an entire line, reads the line, then echoes the entire line. Read only one byte at a time from the keyboard.

Hint

You will need a place to store the characters as they are read from the keyboard. Use a char array, and then use a pointer variable to move through the array:

char aString[200];
char *stringPtr = aString;

In C/C++ using the name of a variable refers to the value stored in that variable, but using the name of an array refers to the address of the first element in the array. Hence, we do not use the & operator when storing the address of the array in the pointer variable. You will learn more about arrays in Chapter 15.

As you saw in Listing 2.15.2, you need to pass an address to the read function. The stringPtr variable contains an address, so the code looks like:

read(STDIN_FILENO, stringPtr, 1);
Solution
/* echoString1.c
 * Echoes a string entered by user.
 * 2017-09-29: Bob Plantz
 */

#include <unistd.h>
#include <string.h>

int main(void)
{
  char aString[200];
  char *stringPtr = aString;

  write(STDOUT_FILENO, "Enter a text string: ",
        strlen("Enter a text string: "));  // prompt user

  read(STDIN_FILENO, stringPtr, 1);    // get first character
  while (*stringPtr != '\n')           // look for end of line
  {
    stringPtr++;                       // move to next location
    read(STDIN_FILENO, stringPtr, 1);  // get next character
  }

  // now echo for user
  write(STDOUT_FILENO, "You entered:\n",
        strlen("You entered:\n"));
  stringPtr = aString;
  do
  {
    write(STDOUT_FILENO, stringPtr, 1);
    stringPtr++;
  } while (*stringPtr != '\n');
  write(STDOUT_FILENO, stringPtr, 1);

  return 0;
}
2.

Modify the program in Exercise 2.16.1 so that after it reads the line typed on the keyboard, it replaces the ‘\n’ character with a NUL character. Now you have stored the input as a C-style string, and you can echo it with:

printf("You entered:\n%s\n", aString);
Hint

When the program exits the first while loop, the pointer variable, stringPtr, is pointing at the ‘\n’ character.

Solution
/* echoString2.c
 * Echoes a string entered by user. Converts input
 * to C-style string.
 * 2017-09-29: Bob Plantz
 */

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

int main(void)
{
  char aString[200];
  char *stringPtr = aString;

  write(STDOUT_FILENO, "Enter a text string: ",
        strlen("Enter a text string: ")); // prompt user

  read(STDIN_FILENO, stringPtr, 1);    // get first character
  while (*stringPtr != '\n')           // look for end of line
  {
    stringPtr++;                       // move to next location
    read(STDIN_FILENO, stringPtr, 1);  // get next character
  }
  *stringPtr = '\0';                   // make into C string

  // now echo for user
  printf("You entered:\n%s\n", aString);

  return 0;
}
3.

Write a C program that prompts the user to enter a line of text on the keyboard then echoes the entire line. The program should continue echoing each line until the user responds to the prompt by not entering any text and hitting the return key. Your program should have two functions, writeStr and readLn, in addition to the main function. The text string itself should be stored in a char array in main. Both functions should operate on NUL-terminated text strings.

  • writeStr takes one argument, a pointer to the string to be displayed, and it returns the number of characters actually displayed. It uses the write system call function to write characters to the screen.

  • readLn takes two arguments, one that points to the char array where the characters are to be stored and one that specifies the maximum number of characters to store in the char array. Additional keystrokes entered by the user should be read from the OS input buffer and discarded. readLn should return the number of characters actually stored in the char array. It should not store the newline character ‘\n’. It uses the read system call function to read characters from the keyboard.

Solution

There are five separate files for this solution. Four of the files, writeStr.h, writeStr.c, readLn.h, and readLn.c, will be used with other programs in the book. If you do not know how to compile multiple-file programs in C, refer to Appendix A.

/* echoString3.c
 * Echoes a string entered by user.
 * 2017-09-29: Bob Plantz
 */

#include "readLn.h"
#include "writeStr.h"
#define STRLEN 5     // limited to 5 for testing readStr
                     // change to 200 for use

int main(void)
{
  char aString[STRLEN];  
  writeStr("Enter a text string: ");
  readLn(aString, STRLEN);
  writeStr("You entered:\n");
  writeStr(aString);
  writeStr("\n");

  return 0;
}
/* writeStr.h
 * Writes a line to standard out.
 *
 * input:
 *    pointer to C-style text string
 * output:
 *    to screen
 *    returns number of chars written
 *
 * 2017-09-29: Bob Plantz
 */
 
#ifndef WRITESTR_H
#define WRITESTR_H
int writeStr(char *);
#endif
/* writeStr.c
 * Writes a line to standard out.
 *
 * input:
 *    pointer to C-style text string
 * output:
 *    to screen
 *    returns number of chars written
 *
 * 2017-09-29: Bob Plantz
 */

#include <unistd.h>
#include "writeStr.h"

int writeStr(char *stringAddr)
{
  int count = 0;

  while (*stringAddr != '\0')
  {
    write(STDOUT_FILENO, stringAddr, 1);
    count++;
    stringAddr++;
  }

  return count;
}
/* readLn.h
 * Reads a line from standard in.
 * Drops newline character. Eliminates 
 * excess characters from input buffer.
 *
 * input:
 *    from keyboard
 * output:
 *    null-terminated text string
 *    returns number of chars in text string
 *
 * 2017-09-29: Bob Plantz
 */
 
#ifndef READLN_H
#define READLN_H
int readLn(char *, int);
#endif
/* readLn.c
 * Reads a line from standard in.
 * Drops newline character. Eliminates 
 * excess characters from input buffer.
 *
 * input:
 *    from keyboard
 * output:
 *    null-terminated text string
 *    returns number of chars in text string
 *
 * 2017-09-29: Bob Plantz
 */

#include <unistd.h>
#include "readLn.h"

int readLn(char *stringAddr, int maxLength)
{
  int count = 0;
  maxLength--;          // allow space for NUL
  read(STDIN_FILENO, stringAddr, 1);
  while (*stringAddr != '\n')
  {
    if (count < maxLength)
    {
      count++;
      stringAddr++;
    }
    read(STDIN_FILENO, stringAddr, 1);
  }
  *stringAddr = '\0';   // terminate C string
   
  return count;
}