Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C中删除字符串中的标点符号_C_String - Fatal编程技术网

如何在C中删除字符串中的标点符号

如何在C中删除字符串中的标点符号,c,string,C,String,我希望删除字符串中的所有标点符号,并使所有大写字母在C中小写,有什么建议吗?在字符串的字符上循环。每当遇到标点符号(ispunt),不要将其复制到输出字符串中。每当遇到“alpha字符”(isalpha)时,使用tolower将其转换为小写 所有提到的功能都在 您可以就地执行(通过保留单独的字符串写入指针和读取指针),也可以从中创建新字符串。但这完全取决于您的应用程序。只是使用以下函数的算法草图: #包括 void remove_punt_和_make_小写(char*p) { char*src

我希望删除字符串中的所有标点符号,并使所有大写字母在C中小写,有什么建议吗?

在字符串的字符上循环。每当遇到标点符号(
ispunt
),不要将其复制到输出字符串中。每当遇到“alpha字符”(
isalpha
)时,使用
tolower
将其转换为小写

所有提到的功能都在


您可以就地执行(通过保留单独的字符串写入指针和读取指针),也可以从中创建新字符串。但这完全取决于您的应用程序。

只是使用以下函数的算法草图:

#包括
void remove_punt_和_make_小写(char*p)
{
char*src=p,*dst=p;
while(*src)
{
if(ispunct((无符号字符)*src))
{
/*跳过此字符*/
src++;
}
else if(isupper((无符号字符)*src))
{
/*把它改成小写*/
*dst++=tolower((无符号字符)*src);
src++;
}
否则如果(src==dst)
{
/*在不复制的情况下递增两个指针*/
src++;
dst++;
}
其他的
{
/*复制字符*/
*dst++=*src++;
}
}
*dst=0;
}

标准警告适用:完全未经测试;改进和优化留给读者作为练习。

在C中实现这一点的惯用方法是有两个指针,一个源指针和一个目标指针,并分别处理每个字符:例如

#include <ctype.h>

void reformat_string(char *src, char *dst) {
    for (; *src; ++src)
        if (!ispunct((unsigned char) *src))
            *dst++ = tolower((unsigned char) *src);
    *dst = 0;
}
#包括
无效重新格式化字符串(char*src,char*dst){
对于(;*src;++src)
如果(!ispunct((未签名字符)*src))
*dst++=tolower((无符号字符)*src);
*dst=0;
}
src和dst可以是相同的字符串,因为目标永远不会大于源

尽管这很诱人,但避免调用
tolower(*src++)
,因为tolower可以作为宏实现


避免搜索要替换的字符的解决方案(使用strchr或类似方法),它们会将线性算法转换为几何算法。

以下是一个粗略的答案:

void strip_punct(char * str) {
    int i = 0;
    int p = 0;
    int len = strlen(str);
    for (i = 0; i < len; i++) {
        if (! ispunct(str[i]) {
            str[p] = tolower(str[i]);
            p++;
        }
    }
}
void strip\u punt(char*str){
int i=0;
int p=0;
int len=strlen(str);
对于(i=0;i
<代码>这里有更多的细节:TStamper,那里似乎没有C例子,C,C++,但是没有C@eliben-我的意思是详细的作为例子,而不是特定语言当我编写完整的可编译程序并测试它时,已经有另一个答案在做基本相同的事情。所以,我删除了我的答案,并对@asveikau的答案进行了投票。所以…你知道吗ze-你输了,fit的生存^H^Hastest::-)你需要在适当的地方做,还是可以在新的缓冲区中工作?Jason,eliben的答案在source==destination;-)时会很好你用英语做这个吗?有些语言在小写字符方面有问题。听起来很像家庭作业…别忘了在结尾添加“\0”!!您应该将
is*
to*
函数的参数强制转换为
无符号字符
。这不是一种改进或优化@pmg或者我可以说这只限于ASCII字符串。就像我说的,这是一个算法的草图。:-)无论如何,我本来打算更新它的,但它看起来像是斯南击败了我。谢谢大家。因为tolower()通常是作为宏实现的,所以您需要去掉后增量运算符,否则会有一些严重的副作用。第二个else if子句应该是:else if(*src==*dst)但是你实际上可以把它完全去掉,让最后一个复制匹配的字符。参见画家Shlemiel的算法:
的参数是*
,而
to*
函数应该转换为
无符号字符
。Shlemiel不适用于这里:
strlen()
函数在循环外使用一次。@pmg严格来说,它不是Shlemiel,但该函数确实遍历字符串两次:一次查找长度,然后进行转换。
strlen()
返回一个长而不是整数。
ctype.h
函数的参数必须强制转换为
无符号字符
的参数为*
,而
to*
函数的参数应强制转换为
无符号字符
。谢谢,我已经很久没有写过C代码了,搜索要替换的字符不会使算法指数化。也许你认为它会从O(n)变成O(n^2)。这将是一个几何算法,而不是指数(O(2^n))。但是,除非要替换的字符以某种方式依赖于输入,否则搜索版本只会将算法的时间乘以某个常数(此类字符的数量),该常数仍然是O(n)(尽管显然,效率要低得多O(n))。@Jeffrey-你说得对。我认为O(n^2)是指数型的。
void strip_punct(char * str) {
    int i = 0;
    int p = 0;
    int len = strlen(str);
    for (i = 0; i < len; i++) {
        if (! ispunct(str[i]) {
            str[p] = tolower(str[i]);
            p++;
        }
    }
}