Reputation: 56
I am getting a string from the user and storing it in a variable plaintext
, and then I want to convert that string to lowercase in a for loop and store it in a separate variable plaintextLowercase
. However, when I change a character in the plaintextLowercase
variable to lowercase, the same happens in the plaintext
variable, which I want to remain unchanged. My code is below.
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h>
int main(void)
{
// get_string() is a function defined in the header file cs50.h that prompts the user for string input and returns that string input
string plaintext = get_string("plaintext: ");
string plaintextLowercase = plaintext;
//this converts the entire string to lowercase, but the issue is it is doing the same to the 'plaintext' variable as well
//I only want the 'plaintextLowercase' string to be lowercase, while the 'plaintext' variable
for (int i = 0, n = strlen(plaintext); i < n; i++)
{
plaintextLowercase[i] = tolower(plaintextLowercase[i]);
}
printf("%s\n", plaintext);
printf("%s\n", plaintextLowercase);
}
Upvotes: 0
Views: 61
Reputation: 69286
You are using a library that obfuscates basic C concepts behind useless typedef
s and macros. If you are working with strings in C, then char *
is the only right way to do it. Avoid using something else, specially if you are still learning how the language works. If your book/library/course is suggesting you to use opaque data types like CS50's string
, then throw it away and go find something else to study on.
What is happening here is that your cs50.h
header defines string
as:
typedef char * string;
Therefore, you are wrongly given the impression that doing:
string a = "123";
string b = a;
Will somehow magically create a copy of the string. This is not the case, as the code is equivalent to:
char *a = "123";
char *b = a;
Both a
and b
are pointers, and will simply end up pointing to the same constant string literal in memory. No copy happens.
This is the same with the result of the get_string()
function, which dynamically allocates a string for you with malloc()
under the hood. So this piece of code:
string plaintext = get_string("plaintext: ");
string plaintextLowercase = plaintext;
has the same "issue". Your lowercase
and plaintextLowercase
are just two pointers to the same memory area, containing the same string. If you want to copy the string, you can use strdup()
:
string plaintext = get_string("plaintext: ");
string plaintextLowercase = strdup(plaintext);
And of course, since the new string is also dynamically allocated, do not forget to free()
it when you don't need it anymore:
free(plaintextLowercase);
The string allocated by get_string()
is automatically deallocated for you at exit by the library (yet another counter-intuitive CS50 thing).
Upvotes: 1