Запись String.trim () в C [дубликат]

7
задан Community 23 May 2017 в 12:16
поделиться

7 ответов

Ваш код часто становится более читабельным, если вы разумно используете стандартные библиотечные функции - например, 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);
}
3
ответ дан 7 December 2019 в 01:19
поделиться

Есть некоторые проблемы: 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;
} 
1
ответ дан 7 December 2019 в 01:19
поделиться

Я не знаю насчет чистоты, но мне трудно уследить за этим. Если бы мне нужно было это сделать, я бы сначала подумал об этом в двух фазах:

  1. Выяснил, сколько символов нужно отбросить с самого начала, а затем переместить оставшуюся часть строки (включая нулевой терминатор) на начальный адрес. (Возможно, вам не понадобится memmove, если вам разрешено возвращать другой указатель начала, но в этом случае вам нужно быть очень осторожным с гигиеной памяти.)
  2. Выясните, сколько символов нужно отбросить с (нового) конца, и установите там новый нулевой терминатор.

Затем я мог бы более внимательно рассмотреть однопроходное решение, которое вы, кажется, пытаетесь реализовать, но только в том случае, если возникла проблема со скоростью.

Кстати, вы, вероятно, захотите использовать isspace () , а не проверять только наличие пробела.

0
ответ дан 7 December 2019 в 01:19
поделиться

С этим кодом есть несколько проблем. Он только проверяет наличие места. Не вкладки или символы новой строки. Вы копируете всю непробельную часть строки. И вы используете 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;
}
1
ответ дан 7 December 2019 в 01:19
поделиться

Вместо сравнения символа с пробелом '' я бы использовал функцию "isspace", которая, как мне кажется, определена в ctype.h.

0
ответ дан 7 December 2019 в 01:19
поделиться

Вот мое решение.

Короткое, простое, чистое, прокомментированное и слегка протестированное.

Оно использует функцию классификации "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';
    }
}
1
ответ дан 7 December 2019 в 01:19
поделиться

Он не выглядит чистым. Предполагая, что первый символ - это пробел, вы используете lastc с неопределенным значением. Вы оставляете один пробел в конце (если в конце есть пробел, при его нажатии c будет пробелом, а lastc - нет).

Вы также не завершаете строку. Предполагая, что вы исправите проблему неинициализированного lastc , вы преобразуете «abc» в «abcbc», поскольку он ни в коем случае не сокращается.

Код также сокращает несколько пробелов внутри строки. Это не то, что вы описали; это желаемое поведение?

4
ответ дан 7 December 2019 в 01:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: