C 消除字符串中的所有多余空格
函数必须消除单词和标点符号之间的所有额外空格,但标点符号与前面的单词之间不得有任何空格 例如,我有以下字符串:C 消除字符串中的所有多余空格,c,C,函数必须消除单词和标点符号之间的所有额外空格,但标点符号与前面的单词之间不得有任何空格 例如,我有以下字符串: Hey ,how are you today ? 我应该得到这个: Hey, how are you today? 此函数消除了此处的额外空间。但是我不知道怎么加标点符号 顺便说一句,我正在主函数中校准此函数 void space_rule(char *str[]){ printf("Enter a string: "); gets(*str);
Hey ,how are you today ?
我应该得到这个:
Hey, how are you today?
此函数消除了此处的额外空间。但是我不知道怎么加标点符号
顺便说一句,我正在主函数中校准此函数
void space_rule(char *str[]){
printf("Enter a string: ");
gets(*str);
puts(*str);
char *p = strtok(*str, " ");
while(*p!=NULL){
printf("%s ",p);
p=strtok(NULL, " ");
}
}
考虑:
#include <stdio.h>
#include <ctype.h>
int main()
{
const char* input = "Hey ,how are you today ?" ;
const char* chp = input ;
// While not end of input...
while( *chp != '\0' )
{
// Print all regular characters (not space or punctuation)
if( !(isspace( *chp ) || ispunct( *chp )) )
{
putchar( *chp ) ;
chp++ ;
}
// Print all punctuation followed by a space (except at end)
else if( ispunct( *chp ) )
{
putchar( *chp ) ;
chp++ ;
if( *chp != '\0' && !isspace( *chp ) )
{
putchar( ' ' ) ;
}
}
// Is space...
else if( isspace( *chp ) )
{
// Skip all space
while( *chp != '\0' && isspace( *chp ) )
{
chp++ ;
}
// If not end, and not punctuation...
if( *chp != '\0' && !ispunct( *chp ) )
{
// ...insert single space
putchar( ' ' ) ;
}
}
}
return 0;
}
输出为:
She said" Hello"
这是不可能的。为此,您不仅需要为“”包含一条例外规则,还需要说明开始和结束引号,并相应地应用该规则。这是一个读者练习-如果您仍然坚持这一点,我建议您发布一个新问题
如果您有一个字符串,例如:
She said, "Hey, how are, you today?"
因为你有?
和“
在一起,对于?
你需要一条规则:“除非下一个字符也是标点符号,否则在标点符号后加空格”。但是,如果?
和“
以空格分隔,那么在做出决定之前,您必须首先消除空格。老实说,我放弃了尝试找出所有排列。我建议,如果您想这样做,您可以一次应用一个规则在多个过程中执行转换,例如:
“
或”
)通过使用更简单的规则(在单独的函数中执行)和多个过程,将更容易以牺牲效率为代价获得正确的结果。您还可以轻松地重新排序规则的应用程序,以获得预期的结果。例如,规则4必须在规则3之后应用。您想要的更改都可以表示为基于每对相邻字符类型的更改。您需要将每个字符描述为空格、字母或标点符号,并按如下方式处理成对字符:
- :删除一个(第一个?)空格
- :删除空格
- :在它们之间插入空格
- 否则:别管它
void copy_and_fix(char *out, const char *in) {
while (*in) {
if (isspace(in[0]) && isspace(in[1])) {
// don't copy the first space
} else if (isspace(in[0]) && ispunct(in[1])) {
// don't copy the space
} else if (ispunct(in[0]) && iswordchar(in[1])) {
// keep the punct and insert a space;
*out++ = *in;
*out++ = ' ';
} else {
// just copy the character
*out++ = *in;
}
++in;
}
*out = '\0'; // NUL terminate the output.
}
当然,您需要注意缓冲区的大小,以确保不会溢出输出缓冲区,但这可以通过多种方式处理(确保输出缓冲区至少是输入大小的1.5倍,或者传递大小并在必要时截断输出,或者在堆上分配输出缓冲区并根据需要调整大小).您的示例结果显示,您还希望在
,
之后添加空格。是吗?立即停止使用get()
!什么是“第一部分”?这就是代码的结果——也要清楚地表明这一点。顺便说一句,你的解决方案太复杂了。你在传递什么str
和一个参数?@Barmar是的。标点符号和下一个单词开头之间需要的空格。如果检索到空格,请遍历字符串并将标志设置为true。如果标志为true,则跳过当前字符,否则将其写入字符串的当前写入(!)位置。如果获得的字符不是空格,请将标志设置为false。因此,您必须处理两个索引(一个写入和一个读取),不要忘记在字符串末尾设置\0
。
void copy_and_fix(char *out, const char *in) {
while (*in) {
if (isspace(in[0]) && isspace(in[1])) {
// don't copy the first space
} else if (isspace(in[0]) && ispunct(in[1])) {
// don't copy the space
} else if (ispunct(in[0]) && iswordchar(in[1])) {
// keep the punct and insert a space;
*out++ = *in;
*out++ = ' ';
} else {
// just copy the character
*out++ = *in;
}
++in;
}
*out = '\0'; // NUL terminate the output.
}