factorial.c

#include<stdio.h>
#include<stdlib.h>

// gcc -g -Wall -std=c11 -o factorial factorial.c

int factorial(int x);

int main(int argc, char** argv) {
  if (argc != 2) {
    printf("Error requires exactly one argument\n");
    exit(1);
  }
  // Convert string to int
  int input = atoi(argv[1]);
  int output = factorial(input);
  printf("%d factorial is %d\n", input, output);
}

int factorial(int x) {
  if (x == 0) {
    return x;
  } else {
    return x * factorial(x-1);
  }
}

factorial_fixed.c

#include<stdio.h>
#include<stdlib.h>

int factorial(int x);

int main(int argc, char** argv) {
  if (argc != 2) {
    printf("Error requires exactly one argument\n");
    exit(1);
  }
  // Convert string to int
  int input = atoi(argv[1]);
  int output = factorial(input);
  printf("%d factorial is %d\n", input, output);
}

int factorial(int x) {
  if (x == 0) {
    return 1;
  } else {
    return x * factorial(x-1);
  }
}

reverse.c

/*
 * Ask user for a word and print it forwards and backwards.
 * CSE 374 demo (for debugging), 10/08-1/17.  HP
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_STR 100   /* length of longest input string */

/* Return a new string with the contents of s backwards */
char* reverse(char* s);

/* Ask the user for a string, then print it forwards and backwards. */
int main() {
  char line[MAX_STR];    // original input line
  char* rev_line;       // backwards copy from reverse function

  printf("Please enter a string: ");
  fgets(line, MAX_STR, stdin);
  rev_line = reverse(line);
  printf("The original string was:   >%s<\n", line);
  printf("Backwards, that string is: >%s<\n", rev_line);
  printf("Thank you for trying our program.\n");
  return 0;
}

char* reverse(char* s) {
  char* result = NULL;            // the reversed string
  int L, R;

  // copy original string then reverse and return the copy
  strcpy(result, s);

  L = 0;
  R = strlen(result);
  while (L < R) {
    char temp = result[L];
    result[L] = result[R];
    result[R] = temp;
    L++; R--;
  }

  return result;
}

Debug reverse.c

  1. gcc -g -Wall -std=c11 -o reverse reverse.c
  2. ./reverse [type: hello] [segmentation fault]
  3. gdb -tui ./reverse
  4. run
  5. bt
  6. list 21
  7. list reverse
  8. quit

Problem 1: result = NULL

Add a line before strcpy in code: int strsize=strlen(s) + 1

  • The strlen() function calculates the length of the string pointed to by s, excluding the terminating null byte (‘0‘).

Add another line after strsize: result = (char*) malloc (strsize * sizeof(char));

Change strcpy to strncpy, buffer safe functions: strncpy(result, s, strsize)

  1. gcc -g -Wall -std=c11 -o reverse reverse.c
  2. ./reverse [type: hello] [no more segmentation fault] [unexpected original string]
  3. gdb ./reverse
  4. list main
  5. b line_number (where the reverse function call is)
  6. run
  7. p line
  8. p (int)strlen(line)
  9. quit

Problem 2: remove extra new line character

Add a line before calling reverse(): line[strlen(line) - 1] = '\0';

This might be helpful for your homework :D

  1. `gcc -g -Wall -std=c11 -o reverse reverse.c``
  2. ./reverse [type: hello] [no more segmentation fault] [expected original string] [unexpected reversed string]
  3. gdb ./reverse
  4. list reverse
  5. b line_number (last line in while loop)
  6. display temp
  7. display result
  8. display result[L]
  9. display result[R]
  10. c
  11. quit

Problem 3: keep the last null terminator

Modify the initialization of R: R = strlen(result) - 1;

  1. gcc -g -Wall -std=c11 -o reverse reverse.c
  2. ./reverse

reverse_fixed.c

/*
 * Ask user for a word and print it forwards and backwards.
 * CSE 374 demo (for debugging), 10/08-1/17.  HP
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_STR 100   /* length of longest input string */

/* Return a new string with the contents of s backwards */
char* reverse(char* s);

/* Ask the user for a string, then print it forwards and backwards. */
int main() {
  char line[MAX_STR];    // original input line
  char* rev_line;       // backwards copy from reverse function

  printf("Please enter a string: ");
  fgets(line, MAX_STR, stdin);
  line[strlen(line) - 1] = '\0';
  rev_line = reverse(line);
  printf("The original string was:   >%s<\n", line);
  printf("Backwards, that string is: >%s<\n", rev_line);
  printf("Thank you for trying our program.\n");

  free(rev_line);
  return 0;
}

char* reverse(char* s) {
  int strsize = strlen(s) + 1;
  char* result = (char*)malloc(sizeof(char) * strsize); // the reversed string
  int L, R;

  // copy original string then reverse and return the copy
  strncpy(result, s, strsize);

  L = 0;
  R = strlen(result) - 1;
  while (L < R) {
    char temp = result[L];
    result[L] = result[R];
    result[R] = temp;
    L++; R--;
  }

  return result;
}