Skip to content

HW1 - Build Your Own String Library

Due Date: July 1st 2026, 05:00 PM

In this assignment you'll build your own small string library from scratch - the kind of functions C's standard library gives you, but written by you, so you understand how they actually work. Then you'll use your library to write a Caesar cipher program.

Everything here uses only what we've covered: types, loops, functions, char arithmetic, and the multi-file / Makefile workflow from Lecture 2. You do not need pointers, and you may not use <string.h> or <ctype.h> - building those pieces yourself is the point.

  • Starter code: starter/ - implement your code in text.c.
  • Language standard / flags: clang -Wall -Wextra -Werror -std=c17
  • Submission: see Submitting below.

Getting Started

GitHub Setup and Repository Management

As with most CS courses at UChicago, you will use a private GitHub repository to store and submit your homework code. The process to request and initialize your repository is essentially the same as other classes. However, you should still read the instructions below carefully to ensure everything is properly set up.

  • We assume you know your way around a Linux terminal environment. If you are not or just need a refresher, please make sure to work through the Linux Basics tutorial.
  • We assume you are already familiar with Git. If you are not or just need a refresher, please make sure to work through the Git Basics tutorial.
  • We assume you have a GitHub account. If you do not, please create one now. You can get an account here: https://github.com/join. We encourage you to use your CNetID as your GitHub account name, if possible. If that name is already taken, try using your CNetID as a prefix in your Github username.

Once you create your account, you may want to get the Student Developer Pack, which will give you access to a lot of other features (please note that having the Student Developer Pack is not necessary for your UChicago classes; it’s just a nice benefit you get as a student). - We assume you have uploaded an SSH key to GitHub. If you are new to Git, and are working through the Git Basics tutorial, please note that the tutorial will explain how to do this.

Requesting Your Homework Repository

The homework repository will be called homework-GITHUB_USERNAME and will be created inside our uchicago-cmsc14300-sum-2026 organization on GitHub. For example, if your GitHub username is jrandom, the repository will be called homework-jrandom. This repository will be private, and can only be viewed by you and the CS235 course staff.

First, request your homework repository by clicking the following link: Ed Post Link -

Then complete the following steps:

  • Github may ask you to grant permission for GitHub Classroom to have access to your GitHub account. If you are asked this question, you should say yes to grant access to Github Classroom.

  • You will need to select your CNetID from a list. This list is manually synced by the course staff, and due to roster changes, your CNetID may not appear in this list. You can skip this step if you do not find your CNetID in the list.

  • You must click “Accept this assignment” or your repository will not actually be created. Do not skip this step!

  • You will be taken to a page saying your repository is being prepared. It will usually be ready within a few seconds, and you can just reload the page to confirm your repository is setup. Please note that this will sometimes take a few minutes.

If you run into any issues, please ask for help on Ed.

You may receive email from GitHub saying that the "@github-classroom[bot] has invited you to collaborate on the uchicago-cmsc14300-sum-2026/homework-GITHUB_USERNAME repository". You can go ahead and click on the "view invitation" button and accept the invitation.

Warning

Important: Do NOT follow the repository initialization instructions provided by GitHub. Follow the instructions provided in the next section instead.

Setting up Your Repository

In this section, you will finish setting up the repository you just requested. You will only need to do this once, since you will be using the same repository for all your homework this quarter.

Step 1

Verify that your repository has been created on GitHub. To do so, open a browser tab to this URL::

https://github.com/uchicago-cmsc14300-sum-2026/homework-GITHUB_USERNAME

where GITHUB_USERNAME is replaced by your GitHub username. If you are not able to open this URL successfully, please ask for help.

Step 2

Get the SSH URL of the repository from GitHub. In the browser window that you opened to your repository, under "Quick setup — if you’ve done this kind of thing before", make sure the “SSH” button is selected. Your repository URL should look something like this: git@github.com:uchicago-cmsc14300-sum-2026/homework-jrandom.git. (Except jrandom will be your GitHub username). We will refer to this URL as REPO_URL later on.

Step 3

In a new terminal, (ideally on your own machine) run the commands listed below. Run them one-by-one and pay attention to any errors that you encounter. If you encounter an error, don't keep going. Instead, please ask for help.

Recall that we use $ to signify the command-line prompt and that is not part of the command.

Remember to replace GITHUB_USERNAME with your GitHub username and REPO_URL with the SSH URL that appears on your repository page on GitHub (as described in Step 2)

Here are the commands:

$ cd
$ mkdir -p cmsc14300-sum-2026/homework-GITHUB_USERNAME
$ cd cmsc14300-sum-2026/homework-GITHUB_USERNAME
$ git init
$ git remote add origin REPO_URL
$ git remote add upstream git@github.com:uchicago-cmsc14300-sum-2026/homework-upstream.git
$ git pull upstream main
$ git branch -M main
$ git push -u origin main

Check Your Repository is Correctly Set Up

Let's do a few quick checks to make sure everything is properly set up.

The contents of the README.md file will be the following:

# CMSC 143000 - Systems Programming I - Summer 2026

This is the upstream homework repository for CMSC 14300.

If not, your repository was not correctly initialized. If you followed GitHub's instructions for initializing the repository instead of following our instructions, you will need to request a new repository. Please post on Ed to request that we remove your repository so you can request a new one.

Next, the files you see in your repository should also be in your repository on GitHub (to check, use a browser to view https://github.com/uchicago-cmsc14300-sum-2026/homework-GITHUB_USERNAME where GITHUB_USERNAME is replaced by your GitHub username.)

Next, run this:

$ git remote -v

It should print the following (it is ok if the lines don't appear in this exact order, as long as all four lines appear)::

origin  git@github.com:uchicago-cmsc14300-sum-2026/homework-GITHUB_USERNAME.git (fetch)
origin  git@github.com:uchicago-cmsc14300-sum-2026/homework-GITHUB_USERNAME.git (push)
upstream  git@github.com:uchicago-cmsc14300-sum-2026/homework-upstream.git (fetch)
upstream  git@github.com:uchicago-cmsc14300-sum-2026/homework-upstream.git (push)
(where your GitHub username will appear instead of GITHUB_USERNAME)

Note

It's important to understand how git remote repositories work. We push to the upstream repo whenever there are updates to the homework assignments. You will pull from the upstream repo to get these updates. You push to the origin repo when you want to submit your homework.

If you realize you entered the wrong value for either the origin or upstream remote, please note that you will not be able to update it by running git remote add again (you will get an error message that says something like: error: remote origin already exists).

Instead, you must run git remote set-url. For example, suppose your GitHub username is SampleStudent and you entered the wrong value for the origin remote. You can update it like this

git remote set-url origin git@github.com:uchicago-cmsc14300-sum-2026/homework-SampleStudent.git

Finally, if you run:

  $ git status .
in your homework-GITHUB_USERNAME directory, the result should be:

  On branch main
  Your branch is up to date with 'origin/main'.

  nothing to commit, working tree clean

Note

The repositories created by GitHub Classroom can be a bit hard to find from the standard GitHub interface. Fortunately, you can visit the URL https://github.com/orgs/uchicago-cmsc14300-sum-2026/repositories that lists your repositories for this course. We strongly recommend creating a bookmark in your browser to this URL.


Background: C strings

So far we've used single chars. A string in C is just an array of char that ends with the null terminator '\0' (a byte whose value is 0). That '\0' is how every function knows where the string stops.

char word[256];               /* room for up to 255 characters + the '\0' */
  • Indexing: word[0] is the first character, word[1] the second, and so on.
  • The terminator matters. The string "cat" is stored as four bytes: 'c', 'a', 't', '\0'.
  • Walking a string means looping until you hit '\0':
for (int i = 0; word[i] != '\0'; i++) {
    printf("%c\n", word[i]);   /* print one character per line */
}
  • Printing a whole string uses %s: printf("%s\n", word);
  • Reading a string:
  • one whitespace-delimited word: scanf("%s", word); (note: no & - an array's name is already usable here)
  • a whole line (including spaces): fgets(word, sizeof word, stdin); (fgets keeps the trailing newline '\n'; you often want to replace it with '\0').

  • char is a small integer (ASCII). This is the one idea we carry over from operators: you can do arithmetic and comparisons on characters, because they are just small integers.

  • You can view the ASCII table here.
  • 'A' is 65, 'a' is 97 - uppercase and lowercase differ by 32.
  • Test for a letter: c >= 'a' && c <= 'z'
  • Lower -> upper: c - 'a' + 'A'
  • "How far into the alphabet is this letter?": c - 'a' (0 for 'a', 25 for 'z')

That's everything you need. The rest is loops and functions you already know.


Homework 1 Tasks

Implement every function in starter/text.c. The exact prototype for each is in starter/text.h. You may add your own helper functions.

Part 1 - Core library (35 pts)

Function Does
int str_length(char s[]) Your own strlen: number of chars before '\0'.
int str_equals(char a[], char b[]) 1 if the strings are identical, else 0.
void to_upper(char s[]) Uppercase every letter, in place.
void to_lower(char s[]) Lowercase every letter, in place.
void reverse(char s[]) Reverse the string in place.

Part 2 - Counting & checks (30 pts)

Function Does
int count_vowels(char s[]) How many vowels (a e i o u, either case).
int count_words(char s[]) How many words (runs of non-whitespace).
int is_palindrome(char s[]) 1 if s reads the same backwards, else 0.

Part 3 - Caesar cipher app (25 pts)

A Caesar cipher shifts every letter forward in the alphabet by a fixed amount, wrapping z back around to a.

Function Does
void caesar_encrypt(char s[], int shift) Shift letters by shift, in place.
void caesar_decrypt(char s[], int shift) Undo caesar_encrypt with the same shift.

Requirements for the cipher:

  • Preserve case (A -> D, a -> d for a shift of 3).
  • Leave non-letters unchanged (spaces, digits, punctuation pass through).
  • Wrap around: with shift 3, x y z -> a b c.
  • Handle a shift that is larger than 26 or negative (e.g. 29 behaves like 3; -3 shifts backwards). Hint: the % operator and a little care with negatives.

main.c is already written for you - it reads a line and a shift, prints the encrypted text, and decrypts it again. Once your functions work:

$ ./app
Enter a line of text: Hello, World!
Enter a shift: 3
Encrypted: Khoor, Zruog!
Decrypted: Hello, World!

Stretch (extra credit, +up to 10 pts)

Make is_palindrome ignore case and non-letter characters, so that "A man, a plan, a canal: Panama" is reported as a palindrome.


Building and testing

cd starter
make          # build the app
./app         # run it

make test     # build & run the public Criterion test suite
make clean

The public tests in test_text.c are a subset of what we grade with - passing them is necessary but not sufficient. Write your own tests and try edge cases: empty strings, strings with no letters, multiple spaces, wrap-around, shift 0.


Rules & academic integrity

  • No <string.h> and no <ctype.h>. Build str_length, case conversion, etc. yourself. (<stdio.h> is fine.)
  • Your code must compile with no warnings under -Wall -Wextra -Werror.
  • No pointers are required; treat strings as char arrays.
  • You must follow the rules for each function, i.e. modify strings in place when mentioned, and return the correct type. You may add helper functions if you want.
  • Generative AI policy (from the syllabus): do not use an LLM to write or fix your CS143 code, and do not paste course materials or your code into one. The work you submit must be your own. Cite any outside sources you consult (even small ones) in a code comment. If you find yourself stuck, reach out to the instructor on Ed or in person to get unstuck - do not spend more than an hour fighting a problem without asking for help.

Grading

Component Points
Part 1 - core library 35
Part 2 - counting & checks 30
Part 3 - Caesar cipher 25
Manual Grading 10
Total 100

The manual grading portion is for code style, comments, as well as code complexity. Please see the UChicago CS Style Guide for C for additional details.

Submitting

Submit text.c (the only file you change) to Gradescope under "HW1". Make sure it builds against the unmodified text.h, main.c, and Makefile. Remember the late policy from the syllabus (3 late days total for the quarter).