如何更改字符串数组中的单个字符? [英] how to change single char in string array?
问题描述
具有以下内容:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
char *up(char *);
int main() {
char initstr[20];
printf("enter string\n");
fgets(initstr, 20, stdin);
char *str = up(initstr);
printf("%s\n", str);
}
char *up(char *in) {
char *ret;
for (ret = in;
*in != '\n';
*(ret++) = toupper(*(in++))
);
return ret;
}
运行方式为:
$./a.out
enter string
abc
#only new line from `printf("%s\n",str);`
来自调试器
Hardware watchpoint 3: in
Old value = 0x7fffffffdc20 "abc\n"
New value = 0x7fffffffdc21 "bc\n"
Hardware watchpoint 2: ret
Old value = 0x7fffffffdc20 "abc\n"
New value = 0x7fffffffdc21 "bc\n"
Hardware watchpoint 3: in
Old value = 0x7fffffffdc21 "bc\n"
New value = 0x7fffffffdc22 "c\n"
Hardware watchpoint 2: ret
Old value = 0x7fffffffdc21 "bc\n"
New value = 0x7fffffffdc22 "c\n"
...
我看到两个变量都在减少,但是我想更改 ret
inline ,一个字符一个字符。但是最后(循环之后), ret
减少为零,并且程序将仅输出 \n
。那么如何在循环头中实现这一目标呢?
I can see that both variables are reducing, but I wanted to change the ret
inline, char by char. But at the end (after loop), the ret
is reduced to nothing, and the program will only output \n
. So how can I achieve this in the loop head?
编辑:
感谢下面的回答,请记住我必须返回指针的第一个地址,可以通过以下方式实现loop_head-only功能:
Thanks to answer below, having in mind I have to return first address of pointer, I can implement loop_head-only function by this:
char *up(char *in){
char *ret;
size_t size=strlen(in);
for(ret=in;
*in!='\n';
*(ret++)=toupper(*(in++))
);
return (ret-size+1);
}
推荐答案
<$ c中的错误$ c> up 是您将 ret
一直增加到换行符( \n
)并返回 ret
指向字符串中的此字符。相反,您应该返回指向初始字符的指针。
The bug in up
is you increment ret
all the way to the newline (\n
) and return ret
pointing to this character in the string. You should instead return a pointer to the initial character.
- 使用索引编写此函数更简单。
- 将所有逻辑打包到
for
子句中时,其内容为空,很难读取且容易出错。 - 注意另外,该字符串可能不包含换行符,因此在空终止符处停止比较安全,
toupper()
不会更改换行符。 - 最后,您不应将
char
值传递给toupper()
,因为此函数和所有函数< ctype.h>
中仅定义了类型为unsigned char
和特殊负值<$ c的值$ c> EOF 。在默认情况下对char
进行签名的平台上,字符串可能包含负的char
值,当传递给时可能导致未定义的行为toupper()
。将它们强制转换为(未签名字符)
,以避免出现此问题。
- It is simpler to write this function using an index.
- packing all the logic into the
for
clauses with an empty body is hard to read and error prone. - Note also that the string might not contain a newline, so it is safer to stop at the null terminator, the newline will not be changed by
toupper()
. - Finally, you should not pass
char
values totoupper()
because this function and all functions from<ctype.h>
is only defined for values of typeunsigned char
and the special negative valueEOF
. On platforms wherechar
is signed by default, the string might contain negativechar
values which may cause undefined behavior when passed totoupper()
. Cast these as(unsigned char)
to avoid this issue.
修改后的版本:
#include <ctype.h>
#include <stdio.h>
char *up(char *s) {
for (size_t i = 0; s[i] != '\0'; i++) {
s[i] = toupper((unsigned char)s[i]);
}
return s;
}
int main() {
char initstr[20];
printf("enter string\n");
if (fgets(initstr, sizeof initstr, stdin)) {
char *str = up(initstr);
printf("%s\n", str);
}
return 0;
}
这篇关于如何更改字符串数组中的单个字符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!