I'm trying to figure out the issue with this code:
int main(int argc, char *argv[])
{
char *s;
scanf("%s\n", s);
char *t = malloc(sizeof(*s) + 1);
strcpy(t, s);
t[0] = toupper(t[0]);
printf("s: %s\n", s);
printf("t: %s\n", t);
free(t);
return 0;
}
I was trying to upper case the first alphabet of my input to get for example hi!
changed into Hi!
.
You are using scanf on a char* without first allocating memory to it. This may lead to segmentation fault. In fact, the following code :
does give segmentation fault sometimes. Instead you can use a
char
array instead of achar*
if you want to avoidmalloc
beforescanf
. You can usefgets
instead ofscanf
to prevent writing out of bounds or you can check withscanf
itself like this:Also in your code, you have a
\n
after%s
in thescanf
statement, that I have removed(assuming you didn't intend this behaviour) . You can see what that does here: Using "\n" in scanf() in CSecondly, in allocating memory for
t
, you are usingsizeof(*s)
which is justsizeof(char)
which is defined to be1
. Instead, you should be usingstrlen(s)+1
which will allocate one more byte than the length of s which should work fine. Also, checking ift==NULL
is also recommended.Before calling
toupper
the argument must be type-casted into anunsigned char
to avoid the risks of undefined behaviour if thechar
type is signed on the platform. More on this can be found on this answer: https://stackoverflow.com/a/21805970/18639286 (Though the question was a C++ question, the answer actually quotes C standard specifications)I have edited the above changes into your code to get the following:
Some extra points:
You can also use
fgets
instead ofscanf
:fgets(s, 100, stdin);
asfgets
does bound checking.Also, fgets reads till end of line/file or till the buffer is full, so it will read past the spaces in input, But
scanf
will stop at a space. Or as Ted Lyngmo pointed out in the comments,scanf
with%s
reads a word, whilefgets
reads a line.But, even if you intend to read only a word, you can use
fgets
and then usesscanf
to read the first word from the string with which you usedfgets
. Example:Here, you don't need to use
%19s
because we know the size ofbuffer
.