Examples of C Functions and System Calls for Strings and Files


You will use most, if not all, of these functions and system calls in Project 4. Here are brief explanations and examples that use them. The Project 4 web page contains a link to this page.

The fork and pipe system calls are both introduced with sample programs in the lecture notes on processes, http://faculty.otterbein.edu/PSanderson/CSC340/notes/lecture03.html, and are not addressed here.


strcmp, strcat, strcpy, strlen, sprintf

This program illustrates several handy string functions.

strcmp compares two strings. If the first is "smaller" it returns a negative value; if equal it returns 0, if the first is "greater" it returns a positive value. Comparisons are based on char-by-char comparison of ASCII values.

strcat concatentates (appends) a copy of the second string onto the end of the first string.

strcpy copies the second string into the first.

strlen returns the integer string length, not including the terminating '\0' character.

sprintf second argument is formatting string, into which values of subsequent argument(s) are copied, and the resulting formatted string copied into the first argument, which must be a string variable.

#include <string.h>
#include <stdio.h>
#define LENGTH 80

int main() {  
  int result;
  char message[LENGTH];
  char first[LENGTH];
  char second[LENGTH];
  char * start = "this is ";
  strcpy(first, start);  
  strcpy(second, start);
  strcat(first, "less");
  strcat(second, "more");
  result = strcmp(first,second);
  if (result < 0) {
     sprintf(message, "string '%s' is smaller\n", first);
  } else if (result == 0) {
     sprintf(message, "the strings are equal\n");
  } else {
     sprintf(message, "string '%s' is smaller\n", second);
  }
  /* Shows output system call.  Could have instead used:  printf("%s", message);   */
  write(1, message, strlen(message));
  return 0;
}

mkstemp, open, read, write, close, unlink, perror

mkstemp is used to create and open a temporary file. Its argument is a string containing a template for constructing the file name. The last 6 characters of the template must be XXXXXX. The argument must be a variable and not a constant, because the XXXXXX will be replaced by the actual randomly-generated characters. After generating the file name, the file is created and opened. An int file descriptor is returned for use in subsequent calls to read/write/close.

open is used to open a file for "raw" I/O. First argument is string containing file name. Second argument specifies access code (O_RDONLY for read-only, O_WRONLY for write-only, O_RDWR for read-write, etc.). An int file descriptor is returned for use in subsequent calls to read/write/close. It will return a negative value if an error occurs. This will happen if you open a non-existing file for reading.

read reads raw bytes from file into a buffer. First argument is file descriptor. Second argument is buffer (address of buffer, e.g. name of char array) into which the bytes are to be stored. Third argument is number of bytes to read. Return value is number of bytes actually read. If 0, the end of file has been reached.

write writes raw bytes from a buffer to file. First argument is file descriptor. Second argument is buffer (address of buffer) from which the bytes are obtained. Third argument is number of bytes to write. Return value is number of bytes actually written. Note: file descriptor 1 (one) is automatically opened for screen output when your process is created; you can write to it any time.

close closes an open file. Takes one argument, the file descriptor.

unlink deletes a file. Takes one argument, the file name.

perror prints an error message, which is provided as a string argument.

This example program does the following:

  1. Creates and opens a temp file
  2. Writes two lines of text to it. The second line is written in two separate operations. This shows that a call to write does not necessarily write a line; it simply writes the number of bytes specified. The programmer is responsible for placing line boundaries (e.g. '\n') into the buffer.
  3. Closes the temp file
  4. Opens the same temp file for reading only.
  5. Reads the contents of the file 1 byte at a time and echoes the byte to the screen.
  6. Notice this loop works regardless of how many bytes the file contains!
  7. Closes the temp file.
  8. Deletes the temp file.
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>

int main() {
  int fd;
  char ch;
  char tempFile[20];
  char data[256];
  strcpy(tempFile,"tempXXXXXX");
  fd = mkstemp(tempFile);
  if (fd < 0) {
      perror("error: cannot open temp file for writing");
      exit(1);
  }
  strcpy(data, "first line of file\n");
  write(fd, data, strlen(data));
  strcpy(data, "second line ");
  write(fd, data, strlen(data));
  write(fd, "of file\n", strlen("of file\n"));
  close(fd);
  fd = open(tempFile, O_RDONLY);
  if (fd < 0) {
      perror("error: cannot open temp file for reading");
      exit(1);
  }
  /* read 1 byte at a time from temp file and echo to screen */
  while ( read(fd, data, 1) ) {
     write(1, data, 1);
  }
  close(fd);
  unlink(tempFile);
  return 0;
}