首页 > 解决方案 > 从 C 中的“自定义”toupper 语句中删除字符

问题描述

这是我第一次用 C 语言编写代码,我必须编写一个代码来对字符串执行 uper 操作,而无需实际使用 to upper。
我已经这样做了,但是由于某种原因它最多只能工作 8 个字符....
-----
这是输入:
hello hello hello hello
-----
这是输出:
复制: hello hello hello hello
; ▒<br/>大写字符串为HELLO HEp▒▒▒<br/>原字符串为hello hello hello hello

#include <stdio.h>

int strLength(char* str){
     int count;
     for(count=0;str[count] != '\n';count++){}
     return count;
}

char* copyStr(char* str,char* str2){
     for(int i=0;str[i] != '\n';i++){
          char n = str[i];
          str2[i] = n;
     }
     str2[strLength(str)] = '\n';
     return str2;
}

char* upper(char* str){
     char str2[100];
     for(int i=0;str[i] != '\n';i++){
         int current = str[i];
         if((current >= 97) && (current <= 122)){
              char new = str[i];
              str2[i] = new-32;
          }
          else{
               str2[i] = current;
          }
    }
    char* str3 = str2;
    return str3;
}

int main(int argc, char **argv){
     char input[100];
     char inputcopy[100];

     //get the input string
     printf("Enter string: ");
     fgets(input, 100, stdin);

     copyStr(input,inputcopy);
     printf("Copy: %s\n", inputcopy);
     printf("The capitalized string is %s\n",upper(inputcopy));
     printf("The original string is %s",input);
}

标签: cstringuppercase

解决方案


明显的问题:

  • 不是 NUL 终止副本copyStr
  • 返回指向局部变量的指针upper

在 C 中,您不能“直接”传递(作为参数)或返回(作为返回值)字符串,因为它们不是值类型——相反,您必须传递或返回一个指针。每当您处理指针时,您都需要担心所指向的事物的生命周期,就好像您在被指针的生命周期结束后使用指针一样,您会得到未定义的行为。

因此,为了从函数中“返回”一个字符串,您实际上必须返回一个指针,该指针指向具有在函数返回后扩展的生命周期(这意味着它不能是指向函数的本地 var 的指针) . 通常有三种方法可以安排这种情况发生:

  1. 传递一个指向将结果字符串作为附加参数放在哪里的指针(这就是您对copyStr函数所做的事情)
  2. 使用 malloc 为字符串分配动态空间并返回指向该字符串的指针。
  3. 返回指向静态(全局)字符串的指针。

这些都有其自身的缺点:

  1. 调用者在调用之前必须知道要返回多大的字符串(以创建传递指针的对象)。通常这是不可能的,或者需要分配“最坏情况”的大字符串,或者有溢出缓冲区的危险(导致 UB)。至少您经常需要第二个附加参数来指定缓冲区的大小。
  2. 调用者需要“负责”返回的内存并确保它被正确释放。这成为调用者和被调用者之间隐式契约的一部分,但通常没有记录,因此是内存泄漏的常见来源
  3. 所有调用通常将共享相同的静态全局,因此它不是可重入的或线程安全的。

推荐阅读