Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C &引用&引用;变成;1“;将转换为大写和小写时_C - Fatal编程技术网

C &引用&引用;变成;1“;将转换为大写和小写时

C &引用&引用;变成;1“;将转换为大写和小写时,c,C,下面是我的代码,用于更改字符大小写的函数。例如,“ABC”将变成“ABC”,反之亦然 char *flipCase(const char *src){ char *output; output = malloc(sizeof(src)); //Copy source to output strcpy(output,src); int i = 0; //Check if the case is lower or upper while(output[i] != '\0') { //Che

下面是我的代码,用于更改字符大小写的函数。例如,“ABC”将变成“ABC”,反之亦然

char *flipCase(const char *src){

char *output;
output = malloc(sizeof(src));
//Copy source to output
strcpy(output,src);
int i = 0;
//Check if the case is lower or upper
while(output[i] != '\0')
{
    //Check if it's alphabetic
    if (isalpha(output[i]))
    {
        //if it's upper case
        if (isupper(output[i]))
        {
            //Convert to lower case and increment i
            output[i]= tolower(output[i]);
            i++;
        }
        //if it's lower case
        if (islower(output[i]))
        {
            //Convert to upper and increment i
            output[i]=toupper(output[i]);
            i++;
        }

    }
    //Else, skip it
    else 
    {
        i++;
    }

}
return output;}
大多数时候,这对我来说似乎很好。然而,当它被测试为“你好,世界,你好吗?”。我期待着“你好,世界,你好吗?”但我的程序给出了“你好,世界,你好吗1”
注意末尾的“1”而不是“?”。问题出在哪里?我该怎么解决呢?

我想你的问题是你的案子已经演变成另一个案子了:

// Case IS_UPPER
// Some code
// i++;

// Case IS_LOWER (is reached by the same iteration but i is one higher!
// Some code
// i++;
因此,您似乎有一个逻辑错误,
i
的某些值仅达到逻辑块的一半。使用
else if
可以解决此问题。但是,您的控制流(是一个while循环)将继续迭代而不增加
i
,直到正确执行为止。虽然这肯定是需要重构的,但这并不是您的bug


注意:重构此代码以使其更干净的一种方法是使用
for
循环,以避免反复编写
i++

我认为您的问题是您的案例正在演变为另一个案例:

// Case IS_UPPER
// Some code
// i++;

// Case IS_LOWER (is reached by the same iteration but i is one higher!
// Some code
// i++;
因此,您似乎有一个逻辑错误,
i
的某些值仅达到逻辑块的一半。使用
else if
可以解决此问题。但是,您的控制流(是一个while循环)将继续迭代而不增加
i
,直到正确执行为止。虽然这肯定是需要重构的,但这并不是您的bug


注意:将此代码重构为更干净的方法之一是使用
for
循环,以避免反复写入
i++

缓冲区分配不正确,导致缓冲区溢出:

output = malloc(sizeof(src));
sizeof
总是返回一个常量(除非应用于VLA),这样就不会得到字符串的长度。您需要的是
strlen(src)+1


关于循环因子分解的其他答案在抽象级别上有一点,但您的循环似乎并不正确。它总是转到下一个字符,从不检查同一个字符两次,也从不离开缓冲区的末尾(假设缓冲区在第一个位置是有效的)。控制流有点奇怪。

缓冲区分配不正确,导致缓冲区溢出:

output = malloc(sizeof(src));
sizeof
总是返回一个常量(除非应用于VLA),这样就不会得到字符串的长度。您需要的是
strlen(src)+1


关于循环因子分解的其他答案在抽象级别上有一点,但您的循环似乎并不正确。它总是转到下一个字符,从不检查同一个字符两次,也从不离开缓冲区的末尾(假设缓冲区在第一个位置是有效的)。控制流有点奇怪。

该错误是由循环变量的双倍增量引起的

假设输出[i]是大写,而输出[i+1]是小写。然后执行循环的以下部分并递增i:

    if (isupper(output[i]))
    {
        //Convert to lower case and increment i
        output[i]= tolower(output[i]);
        i++;
    }
现在,因为i已经被递增,并且具有“原始”i的值,所以循环的以下部分也会执行,导致i的双增量:

    if (islower(output[i]))
    {
        //Convert to upper and increment i
        output[i]=toupper(output[i]);
        i++;
    }

这类错误是当索引变量或迭代器变量可用时,通常首选“for”循环而不是“while”循环的主要原因之一。仅当循环条件的控制超出本地代码控制(例如读取文件或套接字)时,才使用“while”循环;对于其他所有内容,请使用“for”循环。

该错误是由循环变量的双倍增量引起的

假设输出[i]是大写,而输出[i+1]是小写。然后执行循环的以下部分并递增i:

    if (isupper(output[i]))
    {
        //Convert to lower case and increment i
        output[i]= tolower(output[i]);
        i++;
    }
现在,因为i已经被递增,并且具有“原始”i的值,所以循环的以下部分也会执行,导致i的双增量:

    if (islower(output[i]))
    {
        //Convert to upper and increment i
        output[i]=toupper(output[i]);
        i++;
    }

这类错误是当索引变量或迭代器变量可用时,通常首选“for”循环而不是“while”循环的主要原因之一。仅当循环条件的控制超出本地代码控制(例如读取文件或套接字)时,才使用“while”循环;对于其他所有内容,请使用“for”循环。

代码中有两个问题

首先,正如其他人指出的,您没有为返回字符串分配正确的内存量
sizeof(src)
是指平台中指针的大小(可能是8字节)。你需要

output = malloc(strlen(src) + 1);
请注意,您必须在某个点释放分配的内存(在使用完结果后),否则将出现内存泄漏(每次调用函数时都会创建新的内存块)


第二个问题是在
while
循环中。虽然您正确地测试了输入字符串的结尾,但实际上是在循环中递增
i
,然后查看下一个字符。下一个字符不是由isalpha测试的-如果你认为这很重要(可能不是,我认为toupper和tolower应该足够聪明),那么你不应该这样做。添加一个
else
将清除此问题:

if(isalpha(output[i])) {
    if (isupper(output[i]))
    {
        //Convert to lower case and increment i
        output[i]= tolower(output[i]);
        i++;
    }
    //if it's lower case
    else {
        if (islower(output[i]))
        {
            //Convert to upper and increment i
            output[i]=toupper(output[i]);
            i++;
        }
    }
}
作为一般规则,如果您使用
strncpy
而不是
strcpy
,您将避免“复制超出允许范围”(只要您正确使用参数
n
:“我为复制分配的空间”)。在您的情况下,您分配了
sizeof(src)
,如果您已经分配了

strncpy(output, src, sizeof(src));
问题会更加明显


从长远来看,防御性编码(编写额外的几个字符会引起“麻烦”)是值得的…

您的代码中有两个问题

首先,正如其他人指出的,您没有为返回字符串分配正确的内存量。