Reputation: 59
I have a problem with one of the test for my solution for challenge in codewars. I have to write a function that returns alphabet position of characters in input string. My solution is below. I pass all my test and also tests from codewars but fail on this one (I did not implement this test code it was pat of the test code implemented by code wars):
Test(number_tests, should_pass) {
srand(time(NULL));
char in[11] = {0};
char *ptr;
for (int i = 0; i < 15; i++) {
for (int j = 0; j < 10; j++) {
char c = rand() % 10;
in[j] = c + '0';
}
ptr = alphabet_position(in);
cr_assert_eq(strcmp(ptr, ""), 0);
free(ptr);
}
}
The error I receive is following: The expression (strcmp(ptr, "")) == (0) is false.
Thanks for the help!
p.s Also I noticed that I am leaking memory (I don't know how to solve this so I suppose I would use array to keep track of string and don't use malloc) --> I suppose this is not an issue I would just free(ptr) in main function.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *alphabet_position(char *text);
// test
int main()
{
if (!strcmp("1 2 3", alphabet_position("abc")))
{
printf("success...\n");
}
else
{
printf("fail...\n");
}
if (!strcmp("", alphabet_position("..")))
{
printf("success...\n");
}
else
{
printf("fail...\n");
}
if (!strcmp("20 8 5 19 21 14 19 5 20 19 5 20 19 1 20 20 23 5 12 22 5 15 3 12 15 3 11", alphabet_position("The sunset sets at twelve o' clock.")))
{
printf("success...\n");
}
else
{
printf("fail...\n");
}
}
char *alphabet_position(char *text)
{
// signature: string -> string
// purpose: extact alphabet position of letters in input string and
// return string of alphabet positions
// return "123"; // stub
// track numerical value of each letter according to it's alphabet position
char *alph = "abcdefghijklmnopqrstuvwxyz";
// allocate maximum possible space for return string
// each char maps to two digit number + trailing space after number
char *s = malloc(sizeof(char) * (3 * strlen(text) + 1));
// keep track of the begining of return string
char *head = s;
int index = 0;
int flag = 0;
while(*text != '\0')
{
if ( ((*text > 64) && (*text < 91)) || ((*text > 96) && (*text < 123)))
{
flag = 1;
index = (int)(strchr(alph, tolower(*text)) - alph) + 1;
if (index > 9)
{
int n = index / 10;
int m = index % 10;
*s = n + '0';
s++;
*s = m + '0';
s++;
*s = ' ';
s++;
}
else
{
*s = index + '0';
s++;
*s = ' ';
s++;
}
}
text++;
}
if (flag != 0) // if string contains at least one letter
{
*(s -1) = '\0'; // remove the trailing space and insert string termination
}
return head;
}
Upvotes: 2
Views: 107
Reputation: 1702
Here is what I think is happening:
In the cases where none of the characters in the input string is an alphabet character, s
is never used, and therefore the memory allocated by malloc()
could be anything. malloc()
does not clear / zero-out memory.
The fact that your input case of ".."
passes is just coincidence. The codewars test case does many such non-alphabetical tests in a row, each of which causes a malloc()
, and if any one of them fails, the whole thing fails.
I tried recreating this situation, but it's (as I say) unpredictable. To test this, add a debugging line to output the value of s
when flag
is still 0
:
if (flag != 0) { // if string contains at least one letter
*(s -1) = '\0'; // remove the trailing space and insert string termination
}
else {
printf("flag is still 0 : %s\n", s);
}
I'll wager that sometimes you get a garbage / random string that is not ""
.
Upvotes: 1