Skip to main content

Exercise Solutions

Concept Questions

Question 1

You cannot use == to compare C-strings because == compares memory addresses (pointers), not the string contents. Two strings with identical characters stored at different memory locations would not be equal using ==.

Use strcmp(s1, s2) instead:

  • Returns 00 if strings are identical
  • Returns negative value if s1s1 is lexically earlier than s2s2
  • Returns positive value if s1s1 is lexically later than s2s2

Example:

char s1[] = "hello";
char s2[] = "hello";

if (s1 == s2) // FALSE - different addresses
if (strcmp(s1, s2) == 0) // TRUE - same content

Question 2

Performance Issue: strlen() scans the entire string to find the null terminator. Calling it in a loop condition means it rescans the string on every iteration making the function significantly slower.

Inefficient (AVOID):

for (i = 0; i < strlen(str); i++) {  // strlen() called 6+ times
printf("%c\n", str[i]);
}

Efficient:

int length = strlen(str);  // strlen() called once
for (i = 0; i < length; i++) {
printf("%c\n", str[i]);
}

For a 1000-character string, the inefficient version calls strlen() over 1000 times. Each time the strlen() function runs through all 1000 characters. Thus, the loop effectively iterates 1000 * 1000 = 1000000 times while the other version iterates 1000 + 1000 = 2000 times.

Question 3

  • strcpy(): Copies entire string including null terminator; no length limit specified
  • strncpy(): Copies up to nn characters; safer when destination size is limited

Use strncpy() when:

  • Destination buffer has limited size
  • You want to prevent buffer overflow
  • Source string might be longer than destination

Example:

char dest[10];
strcpy(dest, "hello world"); // DANGEROUS - buffer overflow
strncpy(dest, "hello world", 9); // SAFE - copies only 9 chars

Question 4

toupper() and tolower() use pass-by-value parameter passing. This means the character is copied into the function's parameter, and any modifications are local to the function and never reflected back to the caller.

These functions return the converted character; they do not modify the original.

Incorrect:

char c = 'a';
toupper(c); // c is still 'a'
printf("%c\n", c); // prints: a

Correct:

char c = 'a';
c = toupper(c); // Capture return value
printf("%c\n", c); // prints: A

Question 5

A pseudo-random number generator produces a sequence of numbers that appear random but are actually determined by a mathematical formula starting from a seed value.

Why same seed produces same sequence:

  • The generator uses a deterministic algorithm
  • The seed determines the starting point in the sequence
  • Same starting point → same sequence

Debugging benefit:

srand(42);  // Fixed seed
// Always generates: 1234, 5678, 9012, ...

This reproducibility allows developers to:

  • Reproduce bugs consistently
  • Test with known random values
  • Verify program logic without randomness interference

Question 6

Errors:

  1. Line 5: strcmp(str1, str2) == 1 is incorrect

    • strcmp() returns negative, zero, or positive (not specifically 1)
    • Should be: strcmp(str1, str2) > 0
  2. Line 9: printf("%s\n", result) is incorrect

    • result is a char, not a string
    • Should be: printf("%c\n", result)

Corrected code:

char str1[20] = "hello";
char str2[20] = "world";

if (strcmp(str1, str2) < 0) { // str1 is less than str2
printf("str1 is less than str2\n");
}

char result = toupper(str1[0]);
printf("%c\n", result); // Print as character, not string

Question 7

#include <ctype.h>

int countDigits(char str[])
{
int count = 0;
int i;

for (i = 0; str[i] != '\0'; i++) {
if (isdigit(str[i]) != 0) {
count++;
}
}

return count;
}

Walkthrough

Exact Output:

Input: pass123
Match: 0
Input: PASS123
Match: 1

Debugging

Errors Identified:

  1. Single Entry-Single Exit(SESE) Violation: Lines 18-21: Multiple return statements violate single entry/single exit principle
  2. Logical Error - Lines 11, 14: Comparing return value to 11
    • isupper() and isdigit() return non-zero (truthy), not specifically 11
    • Should compare to 00: if (isupper(password[i]) != 0)
    • Or simply: if (isupper(password[i]))
  3. Stylistic Error - Line 8: Missing braces on if statement

Corrected Function:

#include <string.h>
#include <ctype.h>

int validatePassword(char password[])
{
int length = strlen(password);
int hasUpper = 0;
int hasDigit = 0;
int i;
int isValid = 0;

if (length >= 8) {
for (i = 0; i < length; i++) {
if (isupper(password[i]) != 0) {
hasUpper = 1;
}
if (isdigit(password[i]) != 0) {
hasDigit = 1;
}
}

if (hasUpper != 0 && hasDigit != 0) {
isValid = 1;
}
}

return isValid;
}

Programming

Part a

#include <ctype.h>
#include <string.h>

void stringToUppercase(char str[])
{
int i;

for (i = 0; str[i] != '\0'; i++) {
str[i] = toupper(str[i]);
}
}

Part b

#include <string.h>

void appendLongToShort(char result[], const char s1[], const char s2[])
{
int len1 = strlen(s1);
int len2 = strlen(s2);

if (len1 <= len2) {
strcpy(result, s1);
strcat(result, s2);
}
else{
strcpy(result, s2);
strcat(result, s1);
}
}

Part c

#include <stdlib.h>

int generateRandomInRange(int min, int max)
{
//total number of random numbers between max and min
int numRandom = max - min + 1;

//this is a random number between 0 and numRandom-1.
int randomValue = rand() % numRandom;

//puts this in range between min and max inclusive.
randomValue = randomValue + min;

return randomValue;
}