简体   繁体   中英

Why is my program counting letters and digits not running?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM