I wrote this function tat checks for upper, lower and digits in a string but when I'm trying to run the code this pops up and cant seem to understand the problem.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define size 50
void statistics(char str[], int *lower, int *upper, int *digits) {
for (int i = 0; i < size; i++) {
if (islower(str[i]) != 0) {
*lower = *lower + 1;
} else
if (isupper(str[i]) != 0) {
*upper = *upper + 1;
} else
if (isalpha(str[i])) {
*digits = *digits + 1;
}
}
}
int main() {
char str[size] = { " " };
int upper = 0, lower = 0, digits = 0;
printf("Enter a string:\n");
gets_s(str);
statistics(&str[size], &lower, &upper, &digits);
printf("Lower: %d\nUpper: %d\nDigits %d", lower, upper, digits);
return 0;
}
There are multiple problems in your code:
the gets_s()
function is not portable: it is optional and not supported on many systems. You forget to pass the array size, hence causing undefined behavior. The compiler should output a diagnostic that you should not ignore. You should use fgets()
instead.
you should not pass char
values to the isupper()
and similar functions because they are only defined for values of the type unsigned char
and the special negative value EOF
. Use an unsigned char
variable or cast the str[i]
argument as (unsigned char)str[i]
.
you pass the address of the end of the char array instead of the beginning. Just pass str
as the argument to statistics
. The statistics
function reads characters beyond the end of the array, invoking undefined behavior, and one of these bytes happens to be a negative char
value less than -1
triggering the diagnostic in your Visual C++ compiler runtime. The error message is difficult to interpret, the IDE should point you to the calling code.
you iterate on the whole array, beyond the null terminator. The contents of the array is undefined beyond the null terminator set by gets_s()
or fgets()
. Just stop at the null terminator.
you test if (isalpha(ch))
where you probably mean to use if (isdigit(ch))
the isxxx
functions return a non zero value for true and zero for false. It is idiomatic in C to just write if (isdigit(c))
instead of if (isdigit(c) != 0)
which seems redundant.
defining size
as a macro is error prone. Use upper case and a more explicit name.
Here is a modified version:
#include <ctype.h>
#include <stdio.h>
#define LINE_SIZE 50
void statistics(const char *str, int *lower, int *upper, int *digits) {
while (*str != '\0') {
unsigned char ch = *str++;
if (islower(ch)) {
*lower += 1;
} else
if (isupper(ch)) {
*upper += 1;
} else
if (isdigit(ch) {
*digits += 1;
}
}
}
int main() {
char str[LINE_SIZE];
int upper = 0, lower = 0, digits = 0;
printf("Enter a string:\n");
if (fgets(str, sizeof str, stdin)) {
statistics(str, &lower, &upper, &digits);
printf("Lower: %d\nUpper: %d\nDigits %d", lower, upper, digits);
}
return 0;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.