'toupper'和'tolower'对C语言中的char数组没有影响

时间:2019-02-17 02:59:25

标签: c input

我正在创建一个创建用户名的函数。要求用户输入名字,然后输入姓氏。姓氏与名字的首字母串联。另外,任何大写字母都应转换为小写字母。因此,输入“ John DoE”应等于“ jdoe”。

另一个函数计算字符串“此语句具有较小的大小写字符”中小写字母的数量。然后将小写字母转换为大写字母并打印字符串。

第一个函数不会将大写字母转换为小写字母。第二个功能甚至无法识别任何字符的ASCII值。

我尝试为这两个函数使用指针,但是输出没有变化。

void createUsername()
{
int j = 1;
char firstName[15], lastName[15], userName[20];

printf("Enter your first name : ");
fgets(firstName, 15, stdin);
firstName[strlen(firstName) - 1] = '\0';

printf("Enter your last name : ");
fgets(lastName, 15, stdin);
lastName[strlen(lastName) - 1] = '\0';

userName[0] = tolower(firstName[0]);

for (int i = 0, j; lastName[i] != '\0'; i++, j++)
    userName[j] = tolower(lastName[i]);
userName[j+1] = '\0';

printf("User name : %s", userName);
}

void lowerToUpperCase()
{
char sentence[] = "THiS SentENCE HAS SOMe LoWEr CASE ChARAcTERs";
int lowerCases = 0;
for (int i = 0; sentence[i] != '\0'; i++)
{
    if ((sentence[i] >= 97) && (sentence[i] <= 122))
    {
        lowerCases++;
        sentence[i] = toupper(sentence[i]);
    }
}
printf("Number of lower case characters= %d \n", lowerCases);
printf("Upper case sentence : %s \n", sentence);
}

Joe SMITH的预期输出应为jsmith。小写字母的数量应为10,并且句子应打印所有大写字母。

实际输出为JSMITH,小写字母的数量为0,句子打印出原始字母。

2 个答案:

答案 0 :(得分:1)

除了其他答案中提到的问题外,您还存在内存覆盖问题。输入比缓冲区更长的名称会导致生产上的极大痛苦。更好地动态分配足够的内存以容纳名称。

#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void createUsername() {
    printf("Enter your first name : ");
    char *firstName;
    errno = 0;
    int n = scanf("%ms", &firstName);
    if (n != 1) {
        perror("scanf");
        exit(EXIT_FAILURE);
    }

    printf("Enter your last name : ");
    char *lastName;
    errno = 0;
    n = scanf("%ms", &lastName);
    if (n != 1) {
        perror("scanf");
        free(firstName);
        exit(EXIT_FAILURE);
    }

    char *userName = (char *) malloc(1u + strlen(lastName) + 1u);
    userName[0] = tolower(firstName[0]);
    char *userNameIter = userName + 1;
    char *lastNameIter = lastName;
    while ((*userNameIter = tolower((unsigned char) *lastNameIter))) {
        userNameIter++;
        lastNameIter++;
    }

    printf("User name : %s\n", userName);
    free(userName);
    free(lastName);
    free(firstName);
}

void lowerToUpperCase() {
    char sentence[] = "THiS SentENCE HAS SOMe LoWEr CASE ChARAcTERs";
    int lowerCases = 0;
    for (int i = 0;; i++) {
        unsigned char const ch = (unsigned char) sentence[i];
        if (islower(ch)) {
            lowerCases++;
            sentence[i] = toupper(ch);
        } else if (ch == '\0') {
            break;
        }
    }
    printf("Number of lower case characters = %d\n", lowerCases);
    printf("Upper case sentence : %s\n", sentence);
}

答案 1 :(得分:0)

让我们从简单的事情开始,我们将从那里开始:

您可以轻松比较asentence[i]。这样做:

if ((sentence[i] >= 'a') && (sentence[i] <= 'z'))
{
    lowerCases++;
    sentence[i] = toupper(sentence[i]);
}

比这有点难过:

i < lastName[i] != '\0'

这到底是什么?如果您查看此页面: https://en.cppreference.com/w/c/language/operator_precedence 您会看到<的优先级高于!=

编辑:

for (int i = 0, j; lastName[i] != '\0'; i++, j++)

j在这里被重新初始化为for()循环的局部变量,因此它可能会变为0,但在我的情况下,它总是会出现一些垃圾和setfault。所以把这个:

for (int i = 0; lastName[i] != '\0'; i++, j++)

然后您就可以出发了。