【问题标题】:Converting a string to all CAPS and returning it from a function将字符串转换为所有大写字母并从函数中返回
【发布时间】:2020-11-17 12:24:28
【问题描述】:
const char* CAPITALIZE(string val)
{
    char valCap[strlen(val)];
    for (int i = 0; i < strlen(val); i++)
    {
        char n = val[i];
        if (n >= 'a' && n <= 'z')
        {
            n -= 32;
            valCap[i] = n;
        }
        else
        {
            valCap[i] = n;
        }
    }
    valCap[strlen(val) + 1] = '\0';
    return valCap;
}

这应该做的是:

  1. 输入一个字符串。
  2. 将其中的所有字母大写。
  3. 返回字符串。

但它不起作用。我尝试寻找解决方案,但似乎没有任何效果。

【问题讨论】:

  • 这不起作用,因为 a) char valCap[strlen(val)]; 不允许字符串终止符,并且 b) 从函数返回后它不会存在。
  • string = const char*?
  • 选项是 a) 为新字符串分配动态内存,b) 将新字符串的缓冲区作为另一个参数传递,c) 原地大写字符串。
  • ...即使您有额外的终止符字节,valCap[strlen(val) + 1] = '\0'; 仍然是错误的(1 太远了)。
  • 我发现考虑非常短的字符串来可视化这些东西很有帮助,比如长度 0 或 1。

标签: arrays c string char cs50


【解决方案1】:

valCap是一个局部变量,它的生命周期将在函数返回时结束,返回后访问函数的局部变量相当于undefined behavior

有几种方法可以解决这个问题:

  1. 为了安全地返回变量,您需要通过声明指针并为其分配内存来延长其生命周期:

    #include <stdlib.h>
    
    //...
    
    char *valCap = malloc(strlen(val) + 1); //note the + 1 for the null character
    

    以后你需要在它不再使用时释放它。

  • 或将其设为静态:

    static char valCap[strlen(val) + 1]; //note the + 1 for the null character
    

    这延长了变量的生命周期,它将与程序本身一样长。

  1. 或者,您可以传递包含目标字符串的第二个参数,而不是在函数中声明它。
  • 在上述所有情况下,您都需要正确地为 null 终止字符串:

     valCap[strlen(val)] = '\0';
    
  1. 我将使用的更简单的方法是将作为参数传递的字符串大写。

    #include <ctype.h>
    
    //...
    
    void CAPITALIZE(string val)
    {  
        for (int i = 0; i < strlen(val); i++)
        {
            val[i] = toupper(val[i]);
        }
    }
    
  • 或者,因为参数实际上是一个指向字符串1的指针:

    void CAPITALIZE(string val)
    {  
        while(*val != 0) //or '\0'
        {
            *val = toupper(*val);
            val++;
        }
    }
    

    如果你想保持原始字符串不变或者如果原始字符串是常量,你可以传递一个副本。

您可以保留原来的大写策略并应用这些修复之一,但使用 toupper 更安全、更便携且更简单。

1. cs50 string 只不过是char* 中的typedef

【讨论】:

  • 非常感谢您的大力支持。我将分析提供的每种方法以进一步了解。
  • 当心字符串的就地修改。如果字符串常量是只读的,CAPITALIZE( "this is a string constant" ); 将导致您的程序失败。
  • @AndrewHenle 注意。谢谢!
猜你喜欢
  • 2020-12-05
  • 1970-01-01
  • 1970-01-01
  • 2018-04-03
  • 1970-01-01
  • 1970-01-01
  • 2017-08-26
  • 1970-01-01
相关资源
最近更新 更多