char s[100] = "hello world"; // string capacity == 99+1. In use == 11+1.
s[6] = '\0'; // now string contains "hello ". In use == 6+1.
strcat( s, "everyone" ); // now string contains "hello everyone". In use == 14+1.
要从字符串中 * 删除 * 内容,必须首先确定开始和结束的位置:
char s[] = "this is a string [this is more string] original string";
char * first = strchr( s, '[' ); // find the '['
char * last = strchr( s, ']' ); // find the ']'
if (first and last) // if both were found...
// ...copy the end of the string over the part to be replaced
memmove( first, last+1, strlen(last+1)+1 );
// s now contains "this is a string original string"
4条答案
按热度按时间lrpiutwd1#
首先,你必须访问允许你修改的内存。对于歇斯底里的葡萄干,C仍然允许你声明指向常量字符数组的指针为非常数......但是你仍然不能修改它们。
相反,声明一个由常量数据初始化的数组。
这样就得到了一个11+1字符的可变数组(不可变源字符串的 * 副本 *)。
然而,我们常常希望能够在琴弦上工作,所以我们需要确保有足够的空间来演奏它们。
要从字符串中 * 删除 * 内容,必须首先确定开始和结束的位置:
注意到这里所有的
+1
了吗?请注意:']'
之后的 * 复制到字符串末尾)记住,string只是一个字符数组,其中最后一个 used 字符后面紧跟一个零值字符(空终止符)。所有用于处理其他类型数组的方法都适用于处理字符串(AKA字符数组)。
cngwdvgl2#
这是那些"有趣"的问题之一,吸引了超过其份额的答案。
完全归功于其他人的回答,他们注意到试图修改"字符串字面量"会触发UB(字符串字面量通常存储在内存的一个 * 不可变 *"只读"区域中)(感谢@chux-reinstatemonica的澄清)。
下面的代码将把这一点带到下一个层次,它处理由一对分隔符('['&']')限定的多个区域,也处理 * nested * 示例。代码很简单,使用
cut
作为计数器,确保嵌套被考虑在内。假定源串是"良好形成的"。现在,删除输出阵列中的多个连续SP可能是一个小挑战。这可以非常容易地"动态"完成,并作为练习留下。
人们开始看到像这样的东西如何可以扩展到一个"中缀计算器程序"。总是有新的东西!
zengzsys3#
使用
string.h
中定义的strchnul
函数你可能需要定义
_GNU_SOURCE
宏,它不能处理字符串。8dtrkrch4#
字符串是只读的,不应该被修改。试图修改一个字符串会导致未定义的行为。但是,它们 * 可以 * 用于初始化字符数组。
如果要删除括号和括号之间的字符,首先需要使用
strchr
确定字符串包含这两个字符。存储了这些指针后,可以使用strncpy
和strcat
的指针算法创建一个新字符串,减去要排除的部分。输出:
或者,我们可以简单地通过从
end
指针+1复制到start
指针来修改原始字符串。进一步的改进是只查找开始字符 * 之后 * 的结束字符。