用 C 语言编写 String.trim()

发布于 2024-08-25 05:25:08 字数 630 浏览 9 评论 0原文

可能的重复:
在 C 中轻松修剪前导/尾随空格的方法?
在 C 中修剪字符串

我正在用 c 编写字符串修剪方法,这是我想出的代码。我认为它可以消除前导和尾随空格,但是,我希望代码可以更干净。您能提出改进建议吗?

void trim(char *String)
{
int i=0;j=0;
char c,lastc;
while(String[i])
{
   c=String[i];
   if(c!=' ')
   {
     String[j]=c;
     j++;
   }
   else if(lastc!= ' ')
   {
     String[j]=c;
     j++;

   }
   lastc = c;
   i++;
}

这段代码看起来干净吗?

Possible Duplicates:
Painless way to trim leading/trailing whitespace in C?
Trim a string in C

I was writing the String trim method in c and this is the code I came up with. I think it does the job of eliminating leading and trailing whitespaces however, I wish the code could be cleaner. Can you suggest improvements?

void trim(char *String)
{
int i=0;j=0;
char c,lastc;
while(String[i])
{
   c=String[i];
   if(c!=' ')
   {
     String[j]=c;
     j++;
   }
   else if(lastc!= ' ')
   {
     String[j]=c;
     j++;

   }
   lastc = c;
   i++;
}

Does this code look clean ??

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

闻呓 2024-09-01 05:25:08

看起来不干净。假设第一个字符是空格,则您将 lastc 与未定义的值一起使用。您将在末尾留下一个空格(如果末尾有空格,则按 c 时将是一个空格,而 lastc 则不会)。

您也没有终止字符串。假设您解决了未初始化的 lastc 问题,您将把“abc”转换为“abcbc”,因为它在任何时候都没有被缩短。

该代码还折叠了字符串内的多个空格。这不是你所描述的;这是期望的行为吗?

It doesn't look clean. Assuming the first character is a space, you're using lastc with an undefined value. You're leaving one space at the end (if there's a space at the end, when it's hit c will be a space and lastc won't).

You're also not terminating the string. Assuming you fix the uninitialized lastc problem, you'll transform " abc" to "abcbc", since it's not being shortened at any point.

The code also collapses multiple spaces inside the string. This isn't what you described; is it desired behavior?

春庭雪 2024-09-01 05:25:08

如果您明智地使用标准库函数,它通常会使您的代码更具可读性 - 例如,isspace()memmove() 在这里特别有用:

#include <string.h>
#include <ctype.h>

void trim(char *str)
{
    char *start, *end;

    /* Find first non-whitespace */
    for (start = str; *start; start++)
    {
        if (!isspace((unsigned char)start[0]))
            break;
    }

    /* Find start of last all-whitespace */
    for (end = start + strlen(start); end > start + 1; end--)
    {
        if (!isspace((unsigned char)end[-1]))
            break;
    }

    *end = 0; /* Truncate last whitespace */

    /* Shift from "start" to the beginning of the string */
    if (start > str)
        memmove(str, start, (end - start) + 1);
}

It often makes your code more readable if you make judicious use of the standard library functions - for example, isspace() and memmove() are particularly useful here:

#include <string.h>
#include <ctype.h>

void trim(char *str)
{
    char *start, *end;

    /* Find first non-whitespace */
    for (start = str; *start; start++)
    {
        if (!isspace((unsigned char)start[0]))
            break;
    }

    /* Find start of last all-whitespace */
    for (end = start + strlen(start); end > start + 1; end--)
    {
        if (!isspace((unsigned char)end[-1]))
            break;
    }

    *end = 0; /* Truncate last whitespace */

    /* Shift from "start" to the beginning of the string */
    if (start > str)
        memmove(str, start, (end - start) + 1);
}
终弃我 2024-09-01 05:25:08

该代码有几个问题。它仅检查空间。不是制表符或换行符。您正在复制字符串的整个非空白部分。并且您在设置之前使用了lastc。

这是一个替代版本(已编译但未测试):

char *trim(char *string)
{
    char *start;
    int len = strlen(string);
    int i;

    /* Find the first non whitespace char */
    for (i = 0; i < len; i++) {
        if (! isspace(string[i])) {
            break;
        }
    }

    if (i == len) {
        /* string is all whitespace */
        return NULL;
    }

    start = &string[i];

    /* Remove trailing white space */
    for (i = len; i > 0; i--) {
        if (isspace(string[i])) {
            string[i] = '\0';
        } else {
            break;
        }
    }

    return start;
}

There's several problems with that code. It only checks for space. Not tabs or newlines. You are copying the entire non-whitespace part of the string. And you are using lastc before setting it.

Here's an alternate version (compiled but not tested):

char *trim(char *string)
{
    char *start;
    int len = strlen(string);
    int i;

    /* Find the first non whitespace char */
    for (i = 0; i < len; i++) {
        if (! isspace(string[i])) {
            break;
        }
    }

    if (i == len) {
        /* string is all whitespace */
        return NULL;
    }

    start = &string[i];

    /* Remove trailing white space */
    for (i = len; i > 0; i--) {
        if (isspace(string[i])) {
            string[i] = '\0';
        } else {
            break;
        }
    }

    return start;
}
一场信仰旅途 2024-09-01 05:25:08

有一些问题:lastc 可能在未初始化的情况下使用。例如,您可以使用 for 循环而不是 while 循环。此外,修剪/剥离功能通常取代空格、制表符和换行符。

这是我不久前编写的使用指针的解决方案:

void trim(char *str)
{
    char *ptr = str;
    while(*ptr == ' ' || *ptr == '\t' || *ptr == '\r' || *ptr == '\n') ++ptr;

    char *end = ptr;
    while(*end) ++end;

    if(end > ptr)
    {
        for(--end; end >= ptr && (*end == ' ' || *end == '\t' || *end == '\r' || *end == '\n'); --end);
    }

    memmove(str, ptr, end-ptr);
    str[end-ptr] = 0;
} 

There are some problems: lastc could be used uninitialized. And you could make use of a for loop instead of a while loop, for example. Furthermore, trim/strip functions usually replace spaces, tabs and newlines.

Here's a solution using pointers that I wrote quite a while ago:

void trim(char *str)
{
    char *ptr = str;
    while(*ptr == ' ' || *ptr == '\t' || *ptr == '\r' || *ptr == '\n') ++ptr;

    char *end = ptr;
    while(*end) ++end;

    if(end > ptr)
    {
        for(--end; end >= ptr && (*end == ' ' || *end == '\t' || *end == '\r' || *end == '\n'); --end);
    }

    memmove(str, ptr, end-ptr);
    str[end-ptr] = 0;
} 
つ可否回来 2024-09-01 05:25:08

这是我的解决方案。

简短、简单、干净、有注释且经过轻微测试。

它使用“isspace”分类功能,因此您可以轻松更改要修剪的“空白”的定义。

void trim(char* String)
{
    int dest;
    int src=0;
    int len = strlen(String);

    // Advance src to the first non-whitespace character.
    while(isspace(String[src])) src++;

    // Copy the string to the "front" of the buffer
    for(dest=0; src<len; dest++, src++) 
    {
        String[dest] = String[src];
    }

    // Working backwards, set all trailing spaces to NULL.
    for(dest=len-1; isspace(String[dest]); --dest)
    {
        String[dest] = '\0';
    }
}

Here is my solution.

Short, simple, clean, commented, and lightly tested.

It uses the "isspace" classification function, so you can easily change your definition of "white space" to be trimmed.

void trim(char* String)
{
    int dest;
    int src=0;
    int len = strlen(String);

    // Advance src to the first non-whitespace character.
    while(isspace(String[src])) src++;

    // Copy the string to the "front" of the buffer
    for(dest=0; src<len; dest++, src++) 
    {
        String[dest] = String[src];
    }

    // Working backwards, set all trailing spaces to NULL.
    for(dest=len-1; isspace(String[dest]); --dest)
    {
        String[dest] = '\0';
    }
}
2024-09-01 05:25:08

我不会将字符与空格字符“ ”进行比较,而是使用“isspace”函数,我相信该函数是在 ctype.h 中定义的。

Instead of comparing a character with the space character ' ', I'd use the "isspace" function, which I believe is defined in ctype.h.

皇甫轩 2024-09-01 05:25:08

我不知道干净,但我发现很难遵循。如果我需要这样做,我最初会考虑分两个阶段:

  1. 计算出从开头开始要删除多少个字符,然后将字符串的其余部分(包括空终止符)移动到起始地址。 (如果允许返回不同的起始指针,您可能不需要 memmove,但如果是这样,您需要非常小心内存卫生。)
  2. 计算出从(新)末尾删除多少个字符并设置新的 null那里有终结者。

然后,我可能会更仔细地研究您似乎试图实现的一次性解决方案,但前提是存在速度问题。

顺便说一句,您可能想要使用 isspace() 而不是仅检查空间。

I don't know about clean, but I find it hard to follow. If I needed to do this I'd initially think of it in two phases:

  1. Figure out how many characters to drop from the beginning, then memmove the rest of the string (including the null terminator) to the start address. (You might not need the memmove if you are allowed to return a different start pointer, but if so you need to be very careful with memory hygiene.)
  2. Figure out how many characters to drop from the (new) end and set a new null terminator there.

I might then look more closely at a one-pass solution like you seem to be trying to implement, but only if there was a speed problem.

By the way, you probably want to use isspace() rather than checking only for space.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文