Lab Solution

Assignment Task: sixfive (Lab1-w2)

Objective: Print all numbers in a file that are multiples of 5 or 6, using strchr to identify separators.

1. Full Code Solution (user/sixfive.c)

#include "kernel/types.h"
#include "user/user.h"
#include "kernel/fcntl.h"

void process_file(int fd) {
  char buf[512];
  char num_buf[32];
  int n, i, n_idx = 0;
  char *separators = " -\r\t\n./,";

  while ((n = read(fd, buf, sizeof(buf))) > 0) {
    for (i = 0; i < n; i++) {
      // If we hit a separator, process the current number in num_buf
      if (strchr(separators, buf[i]) || buf[i] == '\0') {
        if (n_idx > 0) {
          num_buf[n_idx] = '\0';
          int val = atoi(num_buf);
          
          // Print if multiple of 5 or 6 (and not zero)
          if (val != 0 && (val % 5 == 0 || val % 6 == 0)) {
            printf("%d\n", val);
          }
          n_idx = 0; // Reset for the next number
        }
      } 
      // If it's a digit, add it to our number buffer
      else if (buf[i] >= '0' && buf[i] <= '9') {
        if (n_idx < sizeof(num_buf) - 1) {
          num_buf[n_idx++] = buf[i];
        }
      }
    }
  }

  /* * THE EOF FIX: 
   * If the file ends on a digit without a trailing separator, 
   * we must process the final number here.
   */
  if (n_idx > 0) {
    num_buf[n_idx] = '\0';
    int val = atoi(num_buf);
    if (val != 0 && (val % 5 == 0 || val % 6 == 0)) {
      printf("%d\n", val);
    }
  }
}

int main(int argc, char *argv[]) {
  // If no files provided, just exit
  if (argc < 2) {
    exit(0);
  }

  // Iterate through all files passed as arguments
  for (int i = 1; i < argc; i++) {
    int fd = open(argv[i], O_RDONLY);
    if (fd < 0) {
      // Skip files that can't be opened
      continue;
    }
    process_file(fd);
    close(fd);
  }

  exit(0);
}

2. Setup Instructions

  • Modify Makefile: Add _sixfive to the UPROGS list.

Last updated