-1

I'll admit the title may be confusing, but I really didn't know a better way to put this into words. Here's the code:

char * convertCase(char const * array){
  size_t i = 0;
  while(array[i] != '\0'){
    if(array[i] > 96 && array[i] < 123) *array+i -= 32; // fourth row
    else if(array[i] > 64 && array[i] < 91) array[i] += 32; // fifth row
    i++;
  }
  return(array);
}

What I want to do is something like what you can see in the fifth row, just in the "fourth row" fashion. I'd like to traverse an array in a similar way, but that gives me an l-value error. What's the correct way?

Impasse
  • 85
  • 9
  • 4
    You got the precedence wrong, it should be *(array + i) -= 32. – August Karlstrom Sep 02 '19 at 16:45
  • 4
    `char const * array` declares the pointer to const chars. You can't modify elements pointed by this `array`. – 273K Sep 02 '19 at 16:47
  • 5
    `*array+i` == `(*array)+i` which isn't an l-value. It should be `*(array+i)` which is equivalent to `array[i]` – Ingo Leonhardt Sep 02 '19 at 16:48
  • 1
    It would help with understanding your question and your problem if you#d describe what (by your understanding) fourth row and fifth row are doing (should be doing). Because of the operator precedences, you might be wrong and "what fourth/fifth row" actually IS doing is not what you WANT/THINK it to do. – Yunnosch Sep 02 '19 at 16:49
  • 3
    This is not directly related to your question but you can do: if array[i] >= 'a' instead of using the ASCII value. This will make it easier to understand for anyone who reads your code in the future. – jmq Sep 02 '19 at 16:53
  • @ S.M. this is actually something I was testing before that I forgot to delete, it's not meant to be there; @ jmq thanks for the advice! will do for sure; @ August Karlstrom thanks! clears a lot of stuff up; @ Yunnosch I wanted to increase / decrease the characters in the array to convert them to the opposite case – Impasse Sep 02 '19 at 16:58
  • Related: https://stackoverflow.com/questions/1641957/is-an-array-name-a-pointer See second answer – S.S. Anne Sep 02 '19 at 17:09

1 Answers1

2

There are some things need to be changed in you code:

  1. As Ingo said, *array + i is wrong; it should be *(array + i) which is equivalent to array[i]

  2. Instead of checking if(array[i] > 96 && array[i] < 123), I would prefer using if(array[i] => 'a' && array[i] <= 'z') which adds readability. Same goes for second if

  3. I would recommend you to not change original string, instead, create another string and collect new letters there:

char * convertCase(char const * array)
{
    size_t len = strlen(array);
    char *new_str = (char *) calloc(len + 1, sizeof(char));

    for (size_t i = 0; i < len; ++i)
    {
        if (array[i] >= 'a' && array[i] <= 'z') new_str[i] = array[i] - ('a' - 'A');
        else if (array[i] >= 'A' && array[i] <= 'Z') new_str[i] = array[i] + ('a' - 'A');
    }

    return new_str;
}
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
Miradil Zeynalli
  • 423
  • 4
  • 18
  • Technically using `char` literals is not equivalent behavior, because the C standard does not guarantee that the character set is ASCII. So, while your code would always perform a case inversion in the implementation's character set, the numeric literals would always perform case inversion in ASCII, so be mindful of the intention. – Patrick Roberts Sep 02 '19 at 17:47
  • @chux You are right, I forgot about that. Already edited. Also added `('a' - 'A')` Thanks for mentioning. – Miradil Zeynalli Sep 02 '19 at 17:59
  • Why is changing the original string not advised? I think I heard something similar before but never got an answer to that question – Impasse Sep 03 '19 at 07:59
  • @Impasse like I said, either could be correct, or incorrect, depending on your intent, but my point was just to make the answerer aware they were not equivalent behavior according to the specification. – Patrick Roberts Sep 03 '19 at 13:21