I am working on Vigenere (CS50) and keep getting an "UndefinedBehaviorSanitiser SEGV on Unknown Address" when I run my program with any argument that passes the initial screening.
I have read about this issue but cannot find the solution. I cut my code down as much as I could and found the problem occurs even when I do this part. Where is the issue? Thank you so much.
#include <cs50.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
//int shift(char c);
int main(int argc, string argv[])
{
if (argc != 2)
{
printf("Usage: ./vigenere keyword");
return 1;
}
else
{
for (int i = 0; i < strlen(argv[1]); i++)
{
if (!isalpha(argv[1]))
{
printf("Usage: ./vigenere keyword");
return 1;
}
else
{
printf("All good!");
return 1;
}
}
}
}
The fix indeed is
if (!isalpha((unsigned char)argv[1][i]))
The isalpha
function/macro takes only a single integer, which must have the value of a single character as unsigned char
. But argv[1]
is a pointer to multiple characters!
Now as an extra complication, the isalpha
is often realized as a macro, and often coded so that a compiler does not produce any diagnostics for a wrong type of argument. This is unfortunate, but you just need to know these when you're programming in C.
The cast of char
to unsigned char
is required too - if not, then any extended characters (i.e. for example ä
) will invoke undefined behaviour on platforms where char
is signed - and they are on x86 processors - because the value will be negative, but isalpha
would expect just a number that is either EOF
or a non-negative number less than or equal to UCHAR_MAX
.