这样做的办法是去除前导空白和尾随空白并用单个空格替换多个空格吗?
回答该问题的最佳方法是测试它。
void Test(const char *input, const char *expected_output) {
char buffer[80];
strcpy(buffer, input);
RemoveSpace(buffer);
assert(strcmp(buffer, expected_output) == 0);
}
int main() {
Test(" Leading spaces removed.", "Leading spaces removed.");
Test("Trailing spaces removed. ", "Trailing spaces removed.");
Test("Inner spaces trimmed.", "Inner spaces trimmed.");
Test(" A little of everything. ", "A little of everything.");
Test(" \tTabs \t\tare \t spaces, too.", "Tabs are spaces, too.");
return 0;
}
在OP中的代码没有通过最后的测试,所以答案是没有。
您是否认为这是一种高效的单程解决方案?
这是一次性解决方案。如果你试图挤出每盎司的效率,那么你想尽量减少操作和条件分支的数量。
在C语言中使用C字符串时,通常使用指针而不是索引来使用指针。根据编译器和目标平台的不同,使用指针可能比索引效率更高或更低,但两者的成本都很低。由于这已经是一次单一的线性通过,所以最好的办法是使用惯用的代码模式尽可能清楚地写出它。
这里是我的解决方案:
#include <assert.h>
#include <ctype.h>
#include <string.h>
void RemoveSpace(char *string) {
char *target = string;
char *last = target;
int skipping_spaces = 1;
for (const char *source = string; *source != '\0'; ++source) {
if (isspace(*source)) {
if (!skipping_spaces) {
*target++ = *source;
skipping_spaces = 1;
}
} else {
*target++ = *source;
last = target;
skipping_spaces = 0;
}
}
*last = '\0';
}
它本质上是一个小的状态机,这意味着,在每一步,我们决定基于当前输入字符和当前状态做什么。对于这个问题,我们的状态就是我们是否正在跳过空格(还有一个书签记录最后一个结束字符串的合法点)。
由于strlen,这是两次通过。 – 2016-02-16 15:40:00