c - 从 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);
}
解决方案
明显的问题:
- 不是 NUL 终止副本
copyStr
- 返回指向局部变量的指针
upper
在 C 中,您不能“直接”传递(作为参数)或返回(作为返回值)字符串,因为它们不是值类型——相反,您必须传递或返回一个指针。每当您处理指针时,您都需要担心所指向的事物的生命周期,就好像您在被指针的生命周期结束后使用指针一样,您会得到未定义的行为。
因此,为了从函数中“返回”一个字符串,您实际上必须返回一个指针,该指针指向具有在函数返回后扩展的生命周期(这意味着它不能是指向函数的本地 var 的指针) . 通常有三种方法可以安排这种情况发生:
- 传递一个指向将结果字符串作为附加参数放在哪里的指针(这就是您对
copyStr
函数所做的事情) - 使用 malloc 为字符串分配动态空间并返回指向该字符串的指针。
- 返回指向静态(全局)字符串的指针。
这些都有其自身的缺点:
- 调用者在调用之前必须知道要返回多大的字符串(以创建传递指针的对象)。通常这是不可能的,或者需要分配“最坏情况”的大字符串,或者有溢出缓冲区的危险(导致 UB)。至少您经常需要第二个附加参数来指定缓冲区的大小。
- 调用者需要“负责”返回的内存并确保它被正确释放。这成为调用者和被调用者之间隐式契约的一部分,但通常没有记录,因此是内存泄漏的常见来源
- 所有调用通常将共享相同的静态全局,因此它不是可重入的或线程安全的。
推荐阅读
- java - jesport 报告在 javafx 中显示错误
- sql - 根据Oracle中的字段值插入记录数
- java - 根据三个浮点输入过滤 JTable?
- javascript - ng-table 如何使用 Angular 5 从 API AWS 获取数据
- protocol-buffers - 使用 protobuff 编译的 qtcreator 问题
- python - 尝试在 Keras 中构建编码器-解码器模型时出现图形断开错误
- google-cloud-storage - Google 存储服务身份验证不适用于 cron 作业
- rust - 有没有办法返回一个函数并在没有生命周期的情况下进行闭包?
- c++ - Windows 2012 R2 closesocket() 挂在侦听套接字上
- javascript - 尝试使用来自另一个函数的变量