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 if strings are identical
- Returns negative value if is lexically earlier than
- Returns positive value if is lexically later than
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 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:
-
Line 5:
strcmp(str1, str2) == 1is incorrectstrcmp()returns negative, zero, or positive (not specifically 1)- Should be:
strcmp(str1, str2) > 0
-
Line 9:
printf("%s\n", result)is incorrectresultis achar, 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:
- Single Entry-Single Exit(SESE) Violation: Lines 18-21: Multiple return statements violate single entry/single exit principle
- Logical Error - Lines 11, 14: Comparing return value to
isupper()andisdigit()return non-zero (truthy), not specifically- Should compare to :
if (isupper(password[i]) != 0) - Or simply:
if (isupper(password[i]))
- 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;
}