0

My goal is if I have array of strings such as "hello", "world", "dog" calling reverse should ensure it becomes "dog", "world", "hello".

In reverse, char** is the array of strings and num is just the number of elements Reverse calls swap until all elements are reversed. Doesn't seem to be working as intended as output is not in reverse.

I think one of the issues is I am unsure as to how to make the changes actually permanent. In c++ that would be call by reference, which doesn't seem to exist in c. (New to c had some experience with c++) Any suggestions? Only the top two functions need to be examined. The bottom program is what tests the two functions.

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

  void swap(char* a, char* b){
  char* temp = a;
  a = b;
  b = temp;
}


void reverse_arr(char** arr, int num){
    for(int i=0; i<num/2; i++){
      swap(*(arr+i), *(arr+num-1-i));
    }

}

Program that uses the above functions


#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "reverse.h"

static int total_tests = 0;
static int num_correct = 0;
static int num_incorrect = 0;

#define USAGE "\"./reverse_test\" runs reverse tests"

/**
 * checks if the elements are properly reversed and returns an
 * error message if not
 */
void assert_equal(char** expected, char** actual, const char* message,
                  int len) {
  total_tests++;
  int element_correct = 0;
  int element_incorrect = 0;

  for (int i = 0; i < len; i++) {
    if (!strcmp(expected[i], actual[i])) {
      element_correct++;
      if (element_correct == len) num_correct++;
    } else {
      element_incorrect++;
      if (element_correct == len) num_incorrect++;
      printf(
          "[FAILED Test %d: %s]: At index: %d, expected string: %s, actual "
          "string: %s\n",
          total_tests, message, i, expected[i], actual[i]);
    }
  }
}
/**
 * Runs tests 
 */
void test_reverse() {
  // test 1: test single element
  char* str[] = {"hello"};
  reverse_arr(str, 1);
  assert_equal(str, str, "one element test", 1);

  // test 2: test three elements (odd number of elements)
  char* str2[] = {"hello", "my", "name"};
  char* reverse2[] = {"name", "my", "hello"};
  reverse_arr(str2, 3);
  assert_equal(str2, reverse2, "three element test", 3);

  // test 3: test four elements (even number of elements)
  char* str3[] = {"hello", "my", "name", "is"};
  char* reverse3[] = {"is", "name", "my", "hello"};
  reverse_arr(str3, 4);
  assert_equal(str3, reverse3, "four element test", 4);

  // test 4: test five elements
  char* str4[] = {"i", "love", "systems", "csci", "300"};
  char* reverse4[] = {"300", "csci", "systems", "love", "i"};
  reverse_arr(str4, 5);
  assert_equal(str4, reverse4, "five element test", 5);

  // test 5: test 2 elements
  char* str5[] = {"csci", "300"};
  char* reverse5[] = {"300", "csci"};
  reverse_arr(str5, 2);
  assert_equal(str5, reverse5, "two element test", 2);
void print_test_summary() {
  printf("Passed %d tests, Failed %d tests | %f%%\n", num_correct,
         num_incorrect,
         100 * ceil((float)num_correct) / (total_tests == 0 ? 1 : total_tests));
  total_tests = 0;
  num_incorrect = 0;
  num_correct = 0;
}

/**
 * runs the function passed in and prints a test summary
 */
void run_test(void (*func)(), const char* message) {
  printf("=================== Running %s Tests. ===================\n",
         message);
  func();
  printf("%s: ", message);
  print_test_summary();
}
int main(int argc, char** argv) {
  int num_elements = atoi(argv[1]);

  char* arr[num_elements];
  for (int i = 0; i < num_elements; i++) {
    arr[i] = argv[i + 2];
  }

  reverse_arr(arr, num_elements);

  for (int i = 0; i < num_elements; i++) {
    printf("%s ", arr[i]);
  }
  printf("\n");

  printf("Testing for correctness...\n");
  // passes the function test_reverse to run_test
  run_test(&test_reverse, "Reverse");

  return 0;

  • The pointer to the array is passed by value so you can't allocate a new array and point that pointer to it. But the array itself is not passed at all so it can be changed any way you like. – Jerry Jeremiah Feb 03 '22 at 00:05
  • As an example: https://onlinegdb.com/yQRCiTE_B – Jerry Jeremiah Feb 03 '22 at 00:12
  • Thanks for the response let me take a look! – Volapiik Vyrient Feb 03 '22 at 00:16
  • Your solution seems to pass the pointer to the array of strings itself and then commence swap directly on the array. But what if I wanted to pass individual elements of the array first and then swap? Is there no way to ensure the changes would be sent back to the caller? – Volapiik Vyrient Feb 03 '22 at 00:27
  • You have to pass pointers to the pointers, not just the pointers. – Barmar Feb 03 '22 at 00:30
  • 1
    If you want to pass individual strings then pass the strings by reference using a pointer: https://onlinegdb.com/p7WD1kUuE – Jerry Jeremiah Feb 03 '22 at 01:09
  • @Jerry Jeremiah That second implementation really helped. Thanks for sticking it out with me, really means a lot to me. I would vote you as the correct answer but I don't think I can right now since the post got shut down. – Volapiik Vyrient Feb 03 '22 at 01:35

0 Answers0