COMP1511 Revision Strings Sample Solutions

Revision Exercise: Read Line

In the next few activities, you'll be building some functions that deal with strings.

Remember that a string is an array of values representing characters, where the last character is followed by the special value 0 often written as '\0' in C. We refer to this zero marking the end of the string as the null terminator.

Download read_line.c here, or copy it to your CSE account using the following command:

cp -n /web/cs1511/20T1/activities/read_line/read_line.c .

Your task is to add code to this function in read_line.c:

// Reads a line of input into `buffer`, excluding the newline;
// then ensures that `buffer` is a null-terminated string.
void read_line(int buffer_len, char *buffer) {

    // PUT YOUR CODE HERE
}
read_line takes an array, which we call a "buffer", the size of that array, and should read a line of text from standard input using getchar into the buffer.

Assume a line of text will always end with the newline character, \n. You should not write the newline into the buffer.

If more characters are available to be read than there is array space to read it into, you should stop after you have filled the array.

You should never lose characters, except for the newline.

You should always make sure that, when your function returns, you have null-terminated the buffer.

Testing

read_line.c also contains a simple main function which allows you to test your read_line function.

Do not change this main function. If you want to change it, you have misread the question.

Your read_line function will be called directly in marking. The main function is only to let you test your read_line function

Here is how read_line.c should behave after you add the correct code to the function read_line:

dcc read_line.c -o read_line
./read_line
hello world
<hello world>

If you're uncertain about where to start, you may like to try the Parrot, String Length, and Array Functions revision exercises.

When you think your program is working you can use autotest to run some simple automated tests:

1511 autotest read_line
Sample solution for read_line.c
// Read a line of input.
// A sample solution.

#include <stdio.h>

#define BUFFER_LENGTH 64

void read_line(int buffer_len, char *buffer);

int main(int argc, char *argv[]) {
    // Declare a buffer.  In this case, we're declaring and using a
    // 64-byte buffer, but this could be any length you like, and in
    // our tests you will be required to handle arrays of any length.
    char buffer[BUFFER_LENGTH] = {0};

    // Read in a line...
    read_line(BUFFER_LENGTH, buffer);

    // ... and print it out.  The `%s` format code prints a string.
    printf("<%s>\n", buffer);

    return 0;
}

// Reads a line of input into `buffer`, excluding the newline;
// then ensures that `buffer` is a null-terminated string.
void read_line(int buffer_len, char *buffer) {

    int i = 0;
    int ch = getchar();
    while (i < buffer_len - 1 && ch != EOF && ch != '\n') {
        buffer[i] = ch;
        i = i + 1;
        ch = getchar();
    }

    // could also be written buffer[i] = 0
    buffer[i] = '\0';
}

Revision Exercise: String Length

For this activity, you'll be writing the function string_length. It takes a string, and finds its length, excluding the null-terminator.

Download string_length.c here, or copy it to your CSE account using the following command:

cp -n /web/cs1511/20T1/activities/string_length/string_length.c .

Your task is to add code to this function in string_length.c:

// Takes a string and finds its length, excluding the null-terminator.
int string_length(char *string) {
    // Your code goes here!
    // Don't forget to return your result.
    return 0;
}
string_length.c also contains a simple main function with some simple assert-based tests to help you build your solution:
int main(int argc, char *argv[]) {

    // Some simple assert-based tests.
    // You probably want to write some more.
    assert(string_length("") == 0);
    assert(string_length("!") == 1);
    assert(string_length("Hello, world!") == 13);
    assert(string_length("17... seventeen.\n") == 17);

    printf("All tests passed.  You are awesome!\n");

    return 0;
}

Your string_length function will be called directly in marking. The main function is only to let you test your string_length function

You can add more assert tests to main to test your string_length function.

When you think your program is working you can use autotest to run some simple automated tests:

1511 autotest string_length
Sample solution for string_length.c
// How long is a (piece of) string?
// A sample solution.

#include <assert.h>
#include <stdio.h>

int string_length(char *string);

int main(int argc, char *argv[]) {

    // Some simple assert-based tests.
    // You probably want to write some more.
    assert(string_length("") == 0);
    assert(string_length("!") == 1);
    assert(string_length("Hello, world!") == 13);
    assert(string_length("17... seventeen.\n") == 17);

    printf("All tests passed.  You are awesome!\n");

    return 0;
}

// Takes a string and finds its length, excluding the null-terminator.
int string_length(char *string) {
    int i = 0;
    while (string[i] != '\0') {
        i = i + 1;
    }
    return i;
}

Revision Exercise: Char Index

You should make sure you have completed read_line before completing this task.

Download char_index.c here, or copy it to your CSE account using the following command:

cp -n /web/cs1511/20T1/activities/char_index/char_index.c .

Your task is to add code to this function in char_index.c:

// Return the index of the first occurrence of
// character `c` in the string, or `NOT_IN_STRING`
int char_index(int c, char *string) {
    // Your code goes here!
    // Don't forget to return your result.
    return 0;
}
Start by copying your read_line code into the provided function stub.

Note char_index takes a character and a string and should return the index (position) of the first appearance of the character in the string.

If the character doesn't appear in the string, char_index should return the value NOT_IN_STRING which has been already #defined for you.

char_index.c also contains a simple main function to help you test your char_index function.

// DO NOT CHANGE THIS MAIN FUNCTION
int main(int argc, char *argv[]) {
    // Declare a buffer
    char buffer[BUFFER_LENGTH] = {0};

    // Read in a line...
    printf("Enter a line: ");
    read_line(BUFFER_LENGTH, buffer);

    // Get a character
    printf("Enter a character: ");
    int ch;
    ch = getchar();

    // Find and print character index or "not in string"
    int index = char_index(ch, buffer);
    if (index == NOT_IN_STRING) {
        printf("Character '%c' is not in the string.\n", ch);
    } else {
        printf("Index of character '%c': %d\n", ch, index);
    }

    return 0;
}
This main function reads in a string and a character. Here is how char_index.c should behave after you add the correct code to the function char_index:
dcc char_index.c -o char_index
./char_index
Enter a line: Hello, world!
Enter a character: w
Index of character 'w': 7
./char_index
Enter a line: aaa
Enter a character: a
Index of character 'a': 0
./char_index
Enter a line: aaa
Enter a character: b
Character 'b' is not in the string.

When you think your program is working you can use autotest to run some simple automated tests:

1511 autotest char_index
Sample solution for char_index.c
// Find the index of a character in a given string.
// Created by
//  ... (z0000000)
// Created on 2019-??-??

#include <stdio.h>

#define BUFFER_LENGTH 1024
#define NOT_IN_STRING -1

void read_line(int buffer_len, char *buffer);
int char_index(int ch, char *string);

// DO NOT CHANGE THIS MAIN FUNCTION
int main(int argc, char *argv[]) {
    // Declare a buffer
    char buffer[BUFFER_LENGTH] = {0};

    // Read in a line...
    printf("Enter a line: ");
    read_line(BUFFER_LENGTH, buffer);

    // Get a character
    printf("Enter a character: ");
    int ch;
    ch = getchar();

    // Find and print character index or "not in string"
    int index = char_index(ch, buffer);
    if (index == NOT_IN_STRING) {
        printf("Character '%c' is not in the string.\n", ch);
    } else {
        printf("Index of character '%c': %d\n", ch, index);
    }

    return 0;
}


// Read a line of input into `buffer`, excluding the newline;
// ensures that `buffer` is a null-terminated string.
void read_line(int buffer_len, char *buffer) {

    int i = 0;
    int ch = getchar();
    while (i < buffer_len - 1 && ch != EOF && ch != '\n') {
        buffer[i] = ch;
        i = i + 1;
        ch = getchar();
    }

    // could also be written buffer[i] = 0
    buffer[i] = '\0';
}

// Return the index of the first occurrence of
// character ch in the string, or `NOT_IN_STRING`
int char_index(int ch, char *string) {

    int i = 0;
    while (string[i] != '\0') {
        if (string[i] == ch) {
            return i;
        }
        i = i + 1;
    }

    return NOT_IN_STRING;
}

Revision Exercise: Show Letters

In this activity, you will need to complete a function that prints an array of char values.

You should use the putchar() function to print each character in the array.

Download show_letters.c here, or copy it to your CSE account using the following command:

cp -n /web/cs1511/20T1/activities/show_letters/show_letters.c .

Your task is to add code to this function in show_letters.c:

// print size characters from array letters
void show_letters(int size, char letters[]) {
    // Put your code here
}
show_letters.c also contains a main function to help you test your function Your show_letters function will be called directly in marking. The main function is only to let you test your string_reverse function

Here is how string_reverse.c should behave after you add the correct code to the function string_reverse:

dcc show_letters.c -o show_letters
./show_letters
Hello, world!
Test message.
sample text
a string

When you think your program is working you can use autotest to run some simple automated tests:

1511 autotest show_letters
Sample solution for show_letters.c
// Display character arrays as text, by printing the individual
// characters -- a sample solution.

#include <assert.h>
#include <stdio.h>

#define ENOUGH_SPACE 100

void show_letters(int size, char letters[]);

int main(int argc, char *argv[]) {

    char letters_a[13] = {0};
    letters_a[0] = 72;
    letters_a[1] = 101;
    letters_a[2] = 108;
    letters_a[3] = 108;
    letters_a[4] = 111;
    letters_a[5] = 44;
    letters_a[6] = 32;
    letters_a[7] = 119;
    letters_a[8] = 111;
    letters_a[9] = 114;
    letters_a[10] = 108;
    letters_a[11] = 100;
    letters_a[12] = 33;
    show_letters(13, letters_a);

    putchar('\n');

    char letters_b[13] = {
        84,  101, 115, 116, 32,
        109, 101, 115, 115, 97,
        103, 101, 46
    };
    show_letters(13, letters_b);

    putchar('\n');

    char letters_c[11] = {
        's', 'a', 'm', 'p', 'l', 'e',
        ' ', 't', 'e', 'x', 't'
    };
    show_letters(11, letters_c);

    putchar('\n');

    char letters_d[ENOUGH_SPACE] = "a string";
    show_letters(8, letters_d);

    putchar('\n');

    return 0;
}

// print size characters from array letters
void show_letters(int size, char letters[]) {
    int i = 0;
    while (i < size) {
        putchar(letters[i]);
        i = i + 1;
    }
}

Revision Exercise: Show Terminated Letters

In this activity, you will need to complete a function that prints an array of char values.

You should use the putchar() function to print each character in the array.

Your function will not be given the number of characters to show, instead, you must display characters from the array until you find a null terminator (0 or '\0') in the array.

Download show_terminated_letters.c here, or copy it to your CSE account using the following command:

cp -n /web/cs1511/20T1/activities/show_terminated_letters/show_terminated_letters.c .

Your task is to add code to this function in show_terminated_letters.c:

void show_terminated_letters(char *letters) {
    // Your code here
}
show_terminated_letters.c also contains a main function to help you test your function Your show_terminated_letters function will be called directly in marking. The main function is only to let you test your string_reverse function

Here is how string_reverse.c should behave after you add the correct code to the function string_reverse:

dcc show_terminated_letters.c -o show_terminated_letters
./show_terminated_letters
Hello, world!
Test message.
sample text
a string

When you think your program is working you can use autotest to run some simple automated tests:

1511 autotest show_terminated_letters
Sample solution for show_terminated_letters.c
// Displaying arrays as text
// A sample solution.

#include <assert.h>
#include <stdio.h>

#define ENOUGH_SPACE 100

// Print out each character in a NUL-terminated array of characters.
void show_terminated_letters(char *letters);

int main(int argc, char *argv[]) {

    char letters_a[14] = {0};
    letters_a[0] = 72;
    letters_a[1] = 101;
    letters_a[2] = 108;
    letters_a[3] = 108;
    letters_a[4] = 111;
    letters_a[5] = 44;
    letters_a[6] = 32;
    letters_a[7] = 119;
    letters_a[8] = 111;
    letters_a[9] = 114;
    letters_a[10] = 108;
    letters_a[11] = 100;
    letters_a[12] = 33;
    letters_a[13] = 0;
    show_terminated_letters(letters_a);

    putchar('\n');

    char letters_b[14] = {
        84,  101, 115, 116, 32,
        109, 101, 115, 115, 97,
        103, 101, 46, 0
    };
    show_terminated_letters(letters_b);

    putchar('\n');

    char letters_c[12] = {
        's', 'a', 'm', 'p', 'l', 'e',
        ' ', 't', 'e', 'x', 't', '\0'
    };
    show_terminated_letters(letters_c);

    putchar('\n');

    char letters_d[ENOUGH_SPACE] = "a string";
    show_terminated_letters(letters_d);

    putchar('\n');

    return 0;
}

void show_terminated_letters(char *letters) {
    int i = 0;
    while (letters[i] != '\0') {
        putchar(letters[i]);
        i = i + 1;
    }
}

Revision Exercise: Strings Equal

You've probably noticed that you can't use the comparison operator, ==, to compare strings. So, how do we compare two strings? For this activity, you'll be writing a function to do exactly that:

Download strings_equal.c here, or copy it to your CSE account using the following command:

cp -n /web/cs1511/20T1/activities/strings_equal/strings_equal.c .

Your task is to add code to this function in strings_equal.c:

// Takes two strings, and if they are the same,
// returns 1, or 0 otherwise.
int strings_equal(char *string1, char *string2) {
    // Your code goes here!
    // Don't forget to return your result.
    return 0;
}

It takes two strings, string1 and string2, and, if they are element-for-element the same, it returns 1, and 0 otherwise. You shouldn't ever read beyond the null-terminator of either string.

Download strings_equal.c here, or copy it to your CSE account using the following command:

cp -n /web/cs1511/20T1/activities/strings_equal/strings_equal.c .

Your task is to add code to this function in strings_equal.c:

// Takes two strings, and if they are the same,
// returns 1, or 0 otherwise.
int strings_equal(char *string1, char *string2) {
    // Your code goes here!
    // Don't forget to return your result.
    return 0;
}
strings_equal.c also contains a simple main function with some simple assert-based tests to help you build your solution:
int main(int argc, char *argv[]) {

    // Some simple assert-based tests.
    // You probably want to write some more.
    assert(strings_equal("", "") == 1);
    assert(strings_equal(" ", "") == 0);
    assert(strings_equal("", " ") == 0);
    assert(strings_equal(" ", " ") == 1);
    assert(strings_equal("\n", "\n") == 1);
    assert(strings_equal("This is 17 bytes.", "") == 0);
    assert(strings_equal("", "This is 17 bytes.") == 0);
    assert(strings_equal("This is 17 bytes.", "This is 17 bytes.") == 1);
    assert(strings_equal("Here are 18 bytes!", "This is 17 bytes.") == 0);

    printf("All tests passed.  You are awesome!\n");

    return 0;
}

Your strings_equal function will be called directly in marking. The main function is only to let you test your strings_equal function

You can add more assert tests to main to test your strings_equal function.

When you think your program is working you can use autotest to run some simple automated tests:

1511 autotest strings_equal
Sample solution for strings_equal.c
// String Equality
// A sample solution.

#include <stdio.h>
#include <assert.h>

int strings_equal(char *string1, char *string2);

int main(int argc, char *argv[]) {

    // Some simple assert-based tests.
    // You probably want to write some more.
    assert(strings_equal("", "") == 1);
    assert(strings_equal(" ", "") == 0);
    assert(strings_equal("", " ") == 0);
    assert(strings_equal(" ", " ") == 1);
    assert(strings_equal("\n", "\n") == 1);
    assert(strings_equal("This is 17 bytes.", "") == 0);
    assert(strings_equal("", "This is 17 bytes.") == 0);
    assert(strings_equal("This is 17 bytes.", "This is 17 bytes.") == 1);
    assert(strings_equal("Here are 18 bytes!", "This is 17 bytes.") == 0);

    printf("All tests passed.  You are awesome!\n");

    return 0;
}


// Takes two strings, and if they are the same,
// returns 1, or 0 otherwise.
int strings_equal(char *string1, char *string2) {
    int i = 0;

    // note if string2[i] == '\0', loops terminates too
    while (string1[i] == string2[i] && string1[i] != '\0') {
        i = i + 1;
    }

    // could be just return string1[i] == string2[i];

    if (string1[i] == string2[i]) {
        return 1;
    } else {
        return 0;
    }
}

Revision Exercise: String Copy

For this activity, you'll be writing the function string_copy

It takes a string in the source buffer, and copies it to the destination buffer, which is dest_size elements in size. If there are more characters in source than there is array space in destination, you should stop after you have filled the array. You should always make sure that your function null-terminates the destination array.

Download string_copy.c here, or copy it to your CSE account using the following command:

cp -n /web/cs1511/20T1/activities/string_copy/string_copy.c .

Your task is to add code to this function in string_copy.c:

// Takes a string in `source`, and copies it to `destination`, which
// is `destSize` elements in size; only copies up to `destSize` bytes.
// Ensures the `destination` array is null-terminated.
void string_copy(char *destination, char *source, int destination_size) {
    // Put your code here
}
string_copy.c also contains a simple main function with to help you test your string_copy function
int main(int argc, char *argv[]) {
    // Declare a buffer.  In this case, we're declaring and using a
    // 64-byte buffer, but this could be any length you like, and in
    // our tests you will be required to handle arrays of any length.
    char buffer[BUFFER_LENGTH] = {0};

    // Copy a string into the buffer ...
    string_copy(buffer, "Seventeen bytes.\n", BUFFER_LENGTH);

    // ... and print it out.  The `%s` format code prints a string.
    printf("<%s>\n", buffer);

    return 0;
}

Your string_copy function will be called directly in marking. The main function is only to let you test your string_copy function

When you think your program is working you can use autotest to run some simple automated tests:

1511 autotest string_copy
Sample solution for string_copy.c
// Copy a String
// A sample solution.

#include <stdio.h>

#define BUFFER_LENGTH 64

void string_copy(char *destination, char *source, int destination_size);

int main(int argc, char *argv[]) {
    // Declare a buffer.  In this case, we're declaring and using a
    // 64-byte buffer, but this could be any length you like, and in
    // our tests you will be required to handle arrays of any length.
    char buffer[BUFFER_LENGTH] = {0};

    // Copy a string into the buffer ...
    string_copy(buffer, "Seventeen bytes.\n", BUFFER_LENGTH);

    // ... and print it out.  The `%s` format code prints a string.
    printf("<%s>\n", buffer);

    return 0;
}

// Takes a string in `source`, and copies it to `destination`, which
// is `destSize` elements in size; only copies up to `destSize` bytes.
// Ensures the `destination` array is null-terminated.
void string_copy(char *destination, char *source, int destination_size) {
    int i = 0;

    // stop before last array element so we can add '\0'
    while (i < destination_size - 1 && source[i] != '\0') {
        destination[i] = source[i];
        i = i + 1;
    }
    destination[i] = '\0';
}

Revision Exercise: String To Upper

For this activity, you'll be writing the function string_to_upper. It takes a string and converts it to upper case

Download string_to_upper.c here, or copy it to your CSE account using the following command:

cp -n /web/cs1511/20T1/activities/string_to_upper/string_to_upper.c .

Your task is to add code to this function in string_to_upper.c:

// Convert the characters in `buffer` to upper case
void string_to_upper(char *buffer) {
    // YOUR CODE GOES HERE!
}
string_to_upper.c also contains a simple main function to help you test your solution.
int main(int argc, char *argv[]) {

    // NOTE: THIS WON'T WORK:
    // char *str = "Hello!"
    // string_to_upper(str)
    //
    // str only points to a string literal, which it is not legal to change.
    // If you attempt to modify it on Linux you will get a runtime error.
    // Instead, you need to create an array to store the string in, e.g.:
    //
    // char str[] = "Hello!"
    // string_to_upper(str)

    char str[] = "Seventeen...  SEVENTEEN, I SAY!";
    string_to_upper(str);
    printf("%s\n", str);
    return 0;
}

Your string_to_upper function will be called directly in marking. The main function is only to let you test your string_to_upper function

int main(int argc, char *argv[]) {

    // NOTE: THIS WON'T WORK:
    // char *str = "Hello!"
    // string_to_upper(str)
    //
    // str only points to a string literal, which it is not legal to change.
    // If you attempt to modify it on Linux you will get a runtime error.
    // Instead, you need to create an array to store the string in, e.g.:
    //
    // char str[] = "Hello!"
    // string_to_upper(str)

    char str[] = "Seventeen...  SEVENTEEN, I SAY!";
    string_to_upper(str);
    printf("%s\n", str);
    return 0;
}

Your string_to_upper function will be called directly in marking. The main function is only to let you test your string_to_upper function

Here is how string_to_upper.c should behave after you add the correct code to the function string_to_upper:

dcc string_to_upper.c -o string_to_upper
./string_to_upper
SEVENTEEN...  SEVENTEEN, I SAY!

When you think your program is working you can use autotest to run some simple automated tests:

1511 autotest string_to_upper
Sample solution for string_to_upper.c
// CONVERT A STRING TO UPPERCASE
// CREATED BY
//  ... (Z0000000)
// CREATED ON 2019-??-??

#include <stdio.h>

void string_to_upper(char *buffer);
int uppercase(int c);

int main(int argc, char *argv[]) {

    // NOTE: THIS WON'T WORK:
    // char *str = "Hello!"
    // string_to_upper(str)
    //
    // str only points to a string literal, which it is not legal to change.
    // If you attempt to modify it on Linux you will get a runtime error.
    // Instead, you need to create an array to store the string in, e.g.:
    //
    // char str[] = "Hello!"
    // string_to_upper(str)

    char str[] = "Seventeen...  SEVENTEEN, I SAY!";
    string_to_upper(str);
    printf("%s\n", str);

    return 0;
}

// Convert the characters in `buffer` to upper case
void string_to_upper(char *buffer) {
    int i = 0;
    while (buffer[i] != '\0') {
        buffer[i] = uppercase(buffer[i]);
        i = i + 1;
    }
}

int uppercase(int c) {
    if (c >= 'a' && c <= 'z') {
        return c - 'a' + 'A';
    } else {
        return c;
    }
}

Revision Exercise: String To Lower

For this activity, you'll be writing the function string_to_lower. It takes a string and converts it to lower case

Download string_to_lower.c here, or copy it to your CSE account using the following command:

cp -n /web/cs1511/20T1/activities/string_to_lower/string_to_lower.c .

Your task is to add code to this function in string_to_lower.c:

// Convert the characters in `buffer` to lower case
void string_to_lower(char *buffer) {
    // YOUR CODE GOES HERE!
}
string_to_lower.c also contains a simple main function to help you test your solution.
int main(int argc, char *argv[]) {

    // NOTE: THIS WON'T WORK:
    // char *str = "Hello!"
    // string_to_lower(str)
    //
    // str only points to a string literal, which it is not legal to change.
    // If you attempt to modify it on Linux you will get a runtime error.
    // Instead, you need to create an array to store the string in, e.g.:
    //
    // char str[] = "Hello!"
    // string_to_lower(str)

    char str[] = "Seventeen...  SEVENTEEN, I SAY!";
    string_to_lower(str);
    printf("%s\n", str);

    return 0;
}

Your string_to_lower function will be called directly in marking. The main function is only to let you test your string_to_lower function

Here is how string_to_lower.c should behave after you add the correct code to the function string_to_lower:

dcc string_to_lower.c -o string_to_lower
./string_to_lower
seventeen...  seventeen, i say!

When you think your program is working you can use autotest to run some simple automated tests:

1511 autotest string_to_lower
Sample solution for string_to_lower.c
// convert a string to lowercase
// a sample solution.

#include <stdio.h>

void string_to_lower(char *buffer);
int lowercase(int c);

int main(int argc, char *argv[]) {

    // NOTE: THIS WON'T WORK:
    // char *str = "Hello!"
    // string_to_lower(str)
    //
    // str only points to a string literal, which it is not legal to change.
    // If you attempt to modify it on Linux you will get a runtime error.
    // Instead, you need to create an array to store the string in, e.g.:
    //
    // char str[] = "Hello!"
    // string_to_lower(str)

    char str[] = "Seventeen...  SEVENTEEN, I SAY!";
    string_to_lower(str);
    printf("%s\n", str);

    return 0;
}

// Convert the characters in `buffer` to lower case
void string_to_lower(char *buffer) {
    int i = 0;
    while (buffer[i] != '\0') {
        buffer[i] = lowercase(buffer[i]);
        i = i + 1;
    }
}

int lowercase(int c) {
    if (c >= 'A' && c <= 'Z') {
        return c - 'A' + 'a';
    } else {
        return c;
    }
}

Revision Exercise: String Reverse

For this activity, you'll be writing the function string_reverse. It takes a string and reverses it in place.

Download string_reverse.c here, or copy it to your CSE account using the following command:

cp -n /web/cs1511/20T1/activities/string_reverse/string_reverse.c .

Your task is to add code to this function in string_reverse.c:

// Takes a string in `buffer`, and reverses it in-place.
void string_reverse(char *buffer) {
    // YOUR CODE GOES HERE!
}
string_reverse.c also contains a simple main function to help you test your function string_reverse
int main(int argc, char *argv[]) {

    // NOTE: THIS WON'T WORK:
    // char *str = "Hello!"
    // string_reverse(str)
    //
    // str only points to a string literal, which it is not legal to change.
    // If you attempt to modify it on Linux you will get a runtime error.
    // Instead, you need to create an array to store the string in, e.g.:
    //
    // char str[] = "Hello!"
    // string_reverse(str)

    char str[] = ".'neetneves' :egassem terces A";
    string_reverse(str);
    printf("%s\n", str);
    return 0;
}

Your string_reverse function will be called directly in marking. The main function is only to let you test your string_reverse function

Here is how string_reverse.c should behave after you add the correct code to the function string_reverse:

dcc string_reverse.c -o string_reverse
./string_reverse
A secret message: 'seventeen'.

When you think your program is working you can use autotest to run some simple automated tests:

1511 autotest string_reverse
Sample solution for string_reverse.c
// gnirts a esreveR (Reverse a string)
// A sample solution.

#include <stdio.h>

void string_reverse(char *buffer);
int string_length(char *string);

int main(int argc, char *argv[]) {

    // NOTE: THIS WON'T WORK:
    // char *str = "Hello!"
    // string_reverse(str)
    //
    // str only points to a string literal, which it is not legal to change.
    // If you attempt to modify it on Linux you will get a runtime error.
    // Instead, you need to create an array to store the string in, e.g.:
    //
    // char str[] = "Hello!"
    // string_reverse(str)

    char str[] = ".'neetneves' :egassem terces A";
    string_reverse(str);
    printf("%s\n", str);
    return 0;
}

// Takes a string in `buffer`, and reverses it in-place.
void string_reverse(char *buffer) {
    int length = string_length(buffer);
    int i = 0;
    while (i < length/2) {

        // swap array elements
        char tmp = buffer[i];
        buffer[i] = buffer[length - i - 1];
        buffer[length - i - 1] = tmp;

        i = i + 1;
    }
}

// Takes a string and finds its length, excluding the null-terminator.
int string_length(char *string) {
    int i = 0;
    while (string[i] != '\0') {
        i = i + 1;
    }
    return i;
}

Revision Exercise: Rotate Thirteen

For this activity, you'll be writing the function rotate_thirteen. It takes a string, and rotates each character by thirteen positions in the alphabet.

To see more about this algorithm, check out the wikipedia article.

Download rotate_thirteen.c here, or copy it to your CSE account using the following command:

cp -n /web/cs1511/20T1/activities/rotate_thirteen/rotate_thirteen.c .

Your task is to add code to this function in rotate_thirteen.c:

void rotate_thirteen(char *string) {
    // YOUR CODE HERE
    // See: https://en.wikipedia.org/wiki/ROT13
}
rotate_thirteen.c also contains a simple main function with some simple assert-based tests to help you build your solution:
int main(int argc, char *argv[]) {
    // Example tests
    char test_a[MAX_LENGTH] = "Hello, world!";
    rotate_thirteen(test_a);
    assert(strings_equal("Uryyb, jbeyq!", test_a));

    char test_b[MAX_LENGTH] = "abcdefghijklmnopqrstuvwxyz";
    rotate_thirteen(test_b);
    assert(strings_equal("nopqrstuvwxyzabcdefghijklm", test_b));

    char test_c[MAX_LENGTH] = "The quick brown fox jumped over the lazy dog.";
    rotate_thirteen(test_c);
    assert(strings_equal("Gur dhvpx oebja sbk whzcrq bire gur ynml qbt.", test_c));

    // Add your own tests here

    printf("All tests passed. You are awesome!\n");

    return 0;
}

Your rotate_thirteen function will be called directly in marking. The main function is only to let you test your rotate_thirteen function

You can add more assert tests to main to test your rotate_thirteen function.

You will need to use your strings_equal function from the strings_equal activity for tests to work.

You may want to use your rotate_one function from the rotate_one activity.

You may want to use your rotate_thirteen function from the rotate_thirteen activity.

When you think your program is working you can use autotest to run some simple automated tests:

1511 autotest rotate_thirteen
Sample solution for rotate_thirteen.c
// Perform the ROT13 algorithm on a string -- sample solution.

#include <stdio.h>
#include <assert.h>

#include <string.h>


// Add your own #defines here
#define ALPHABET_LENGTH 26
#define LOWER_START     'a'
#define LOWER_END       (LOWER_START + ALPHABET_LENGTH)
#define UPPER_START     'A'
#define UPPER_END       (UPPER_START + ALPHABET_LENGTH)

#define MAX_LENGTH      256

void rotate_thirteen(char *string);
int rotate_one(int c);
int string_length(char *string);
int strings_equal(char *string_a, char *string_b);

// Add your own function prototypes here
int is_lower_letter(char l);
int is_upper_letter(char l);

int main(int argc, char *argv[]) {
    // Example tests
    char test_a[MAX_LENGTH] = "Hello, world!";
    rotate_thirteen(test_a);
    assert(strings_equal("Uryyb, jbeyq!", test_a));

    char test_b[MAX_LENGTH] = "abcdefghijklmnopqrstuvwxyz";
    rotate_thirteen(test_b);
    assert(strings_equal("nopqrstuvwxyzabcdefghijklm", test_b));

    char test_c[MAX_LENGTH] = "The quick brown fox jumped over the lazy dog.";
    rotate_thirteen(test_c);
    assert(strings_equal(
        "Gur dhvpx oebja sbk whzcrq bire gur ynml qbt.",
        test_c
    ));

    // Add your own tests here

    printf("All tests passed. You are awesome!\n");

    return 0;
}

// See: https://en.wikipedia.org/wiki/ROT13
void rotate_thirteen(char *string) {
    int l = 0;
    int length = string_length(string);
    while (l < length) {
        int i = 0;
        while (i < 13) {
            string[l] = rotate_one(string[l]);
            i = i + 1;
        }
        l = l + 1;
    }
}

// Use your code from the rotate_one warmup here.
int rotate_one(int c) {
    int letter_num = 0;
    int base = '\0';

    // Deal with lowercase and uppercase letters separately.
    if (is_lower_letter(c)) {
        letter_num = c - LOWER_START;
        base = LOWER_START;
    } else if (is_upper_letter(c)) {
        letter_num = c - UPPER_START;
        base = UPPER_START;
    } else {
        // If it's not lowercase or uppercase, it remains unchanged.
        return c;
    }

    // rotate by 1, wrap around alphabet
    letter_num = letter_num + 1;
    letter_num = letter_num % ALPHABET_LENGTH;

    return base + letter_num;
}

int string_length(char *string) {
    // Use your code from the string_length activity here.
    // Lazy tutor solution: use string.h
    return strlen(string);
}

int strings_equal(char *string_a, char *string_b) {
    // Use your code from the strings_equal activity here.
    // Lazy tutor solution: use string.h
    return strcmp(string_a, string_b) == 0;
}

int is_lower_letter(char l) {
    return (l >= LOWER_START && l < LOWER_END);
}

int is_upper_letter(char l) {
    return (l >= UPPER_START && l < UPPER_END);
}