我在C中编写一个函数,它将获取一个字符串并删除所有不是小写字母字符的字符。我到目前为止编写了这段代码:
protected void btnDelete_Click(object sender, EventArgs e)
{
foreach (GridViewRow gvrow in gvDetails.Rows)
{
//Finiding checkbox control in gridview for particular row
CheckBox chkdelete = (CheckBox)gvrow.FindControl("chkSelect");
//Condition to check checkbox selected or not
if (chkdelete.Checked)
{
//Getting UserId of particular row using datakey value
int usrid = Convert.ToInt32(gvDetails.DataKeys[gvrow.RowIndex].Value);
using (SqlConnection con = new SqlConnection("Data Source=murugan-pc;Initial Catalog=rg_lava_software;User ID=sa;Password=123"))
{
con.Open();
SqlCommand cmd = new SqlCommand("delete from emp where empid=" + usrid, con);
cmd.ExecuteNonQuery();
con.Close();
}
}
}
BindUserDetails();
}
}
当我传递字符串" hello [] [] world"该函数似乎主要起作用,除了输出是:
void strclean(char* str) {
while (*str) {
if (!(*str >= 'a' && *str <= 'z')) {
strcpy(str, str + 1);
str--;
}
str++;
}
}
当我在输入if语句的每一行之后打印它时,这是我收到的输出:
hellowoldd
它似乎非常接近,但我无法理解为什么它会产生这个输出!最奇怪的部分是我已经将代码提供给其他两个朋友,它在他们的计算机上工作正常。我们都在运行相同版本的Linux(ubuntu 14.04.3),并且都使用gcc进行编译。
我不确定代码是否存在导致输出不一致的问题,或者是否是编译问题造成的问题。也许它与我们的机器上的strcpy有关吗?
答案 0 :(得分:9)
如果范围重叠,strcpy
函数不能保证正常工作,就像你的情况一样。来自C11 7.24.2.3 The strcpy function /2
(我的重点):
strcpy
函数将s2
指向的字符串(包括终止空字符)复制到s1
指向的数组中。 如果在重叠的对象之间进行复制,则行为未定义。
根据memmove
,您可以使用C11 7.24.2.2 The memmove function /2
之类的内容,其中 使用重叠范围:
memmove
函数将n
指向的对象中的s2
个字符复制到s1
指向的对象中。 复制的过程就好像n
指向的对象中的s2
字符首次被复制到n
个字符的临时数组中,这些字符与指向的对象不重叠至s1
和s2
,然后将临时数组中的n
字符复制到s1
指向的对象中。 < / p>
但是,在时间复杂度方面,O(n)
而不是O(n2)
是一个更好的解决方案,同时仍然是重叠安全的:
void strclean (char* src) {
// Run two pointers in parallel.
char *dst = src;
// Process every source character.
while (*src) {
// Only copy (and update destination pointer) if suitable.
// Update source pointer always.
if (islower(*src)) *dst++ = *src;
src++;
}
// Finalise destination string.
*dst = '\0';
}
您会注意到我还使用islower()
(来自ctype.h
)来检测小写字母字符。由于C标准没有强制要求字母字符具有连续的代码点(数字是唯一保证连续的数字),因此这更具可移植性。
也没有单独检查isalpha()
的需要,因为根据C11 7.4.1.2 The isalpha function /2
,islower() == true
暗示isalpha() == true
:
isalpha
函数测试isupper
或islower
为真的任何字符,或者......
答案 1 :(得分:4)
来自N1256 7.21.2.3 strcpy函数
即使区域重叠,也可以使用如果在对象之间进行复制 重叠,行为未定义。
memmove
。
void strclean(char* str) {
while (*str) {
if (!islower(*str)) { /* include ctype.h to use islower function */
memmove(str, str + 1, strlen(str)); /* strlen(str + 1) + 1 (for terminating null character) should be strlen(str) */
} else {
str++;
}
}
}
由于它从指针中减去未定义的行为以使其指向数组之前的区域,因此我还重构了str
操作。< / p>