I'm trying to convert a fixed size argv to upper and to lower but It either gives me segmentation fault or it just stores gibberish on the var. I've tried this:
#include <stdlib.h>
#include <ctype.h>
#include <cs50.h>
#include <stdio.h>
#include <string.h>
int main(int argc, string argv[])
{
string lower = "abcdefghijklmnopqrstuvwxyz";
string upper = "abcdefghijklmnopqrstuvwxyz";
for (int i = 0, n = 26; i < n; i++)
{
lower[i] = tolower(argv[1][i]);
upper[i] = toupper(argv[1][i]);
}
}
or:
string lower = "";
string upper = "";
//check if repeated chars or numbers
for (int i = 0, n = 26; i < n; i++)
{
printf("%c\n",(char) argv[1][i]);
printf("%c\n",(char) argv[1][i]);
printf("%c\n",tolower(argv[1][i]));
printf("%c\n",toupper(argv[1][i]));
lower += tolower(argv[1][i]);
upper += toupper(argv[1][i]);
}
The strangest part is that the printf's give the right values but they arent getting stored in lower
or upper
. What n00b thing am I doing here?
You cannot use
+=
in C to append to a string.<cs50.h>
definesstring
to bechar *
. Thenstring lower = "";
defineslower
to be achar *
and sets it to point to the first character of""
.""
represents a null string, which is a string whose first and only character is the null (zero value) character, indicating the end of the string.When applied a pointer,
+= n
attempts to advance the pointer byn
elements of the type it points to. For example, if a pointerp
is pointing to element 3 of an array,p += 4
will make it point to element 7.Since
lower
points to an element of an array with only one element, the null character,lower += tolower(argv[1][i])
attempts to make it point outside the array. The behavior is not defined by the C standard. (Except it could be in a C implementation in whichtolower
applied to that character yields a character with value 1. This would modifylower
to point just beyond the last element in the array, which is a special position that is allowed for pointer arithmetic.)With
string lower = "abcdefghijklmnopqrstuvwxyz";
, you have more room to do the array arithmetic; some additions tolower
will work. However, again,tolower(argv[1][i])
is likely too big to remain inside the array.Further, even if the pointer arithmetic works,
lower += …
only changes the pointer. It does not change the characters it points to.To make your code work, you need to allocate enough memory to hold the resulting string, including the null character, and you must set
lower
to point to that memory, and similarly forupper
. The number of characters you need isstrlen(argv[1][i]) + 1
. If you have learned how to usemalloc
, you can use that. If you have a fixed assignment that guarantees thatargv[1]
will be exactly 26 characters, you can definelower
and provide memory for it by declaring it withchar lower[27];
, and similarly forupper
.Then, you must copy characters into that memory, which you can do with
lower[i] = tolower(argv[1][i]);
. When you are done copying characters into the array, you should write a null character at the end of it, to form a complete C string. (If you are not going to print the array as a string or otherwise use it as a string, you can omit this.)