Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Функция удаления лишних прбелов справа и слева, Работа cо строкой символов 
V
    Опции темы
Voldemar2004
Дата 28.5.2006, 13:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1650
Регистрация: 25.12.2004

Репутация: нет
Всего: 23



Есть ли в Си готовая функция, которая бы отсекала лишние пробелы (на подобие LTrim, RTrim, Trim в VB 6) ? А то я ничего не нашел и написал сам:
Код
//---------------------------------------------------------------------------
#include <iostream.h>
#include <conio.h>
#include <string.h>
//---------------------------------------------------------------------------
void main(void)
{

char *a = "     Stroka.          ";

        unsigned int i=0;

        for(i; a[i] == ' '; i++) {;}
        const CutLenLeft = i;  /* Позиция 1-го символа, отличного от пробела. */


        for(i=strlen(a); i--; i>0) {if( a[i] != ' ' ) break;}
        /* Позиция 1-го символа, отличного от пробела - заход справа. */
        const CutLenRight = i;

                char *NoSpace = "";

                i = CutLenLeft;
                for(unsigned int j=CutLenLeft; j<CutLenRight+1; j++)
                {
                 NoSpace[j] = a[i];
                 i++;
                 cout<<NoSpace[j];
                }


getch();
}
//---------------------------------------------------------------------------
И еще: чего-то не получается сделать из этого кода функцию типа этого:
Код
char *NoSpace(char *a)
{

/* тело функции */


return NoSpace;
}
 


--------------------
i_i 
(';') 
(V)

user posted image
PM MAIL   Вверх
Darhazer
Дата 28.5.2006, 14:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 429
Регистрация: 28.9.2005
Где: HellCity (Sofia, Bulgaria)

Репутация: 2
Всего: 29



Готовая функция думаю нету, но нашел вот такое STL решение:

Код

std::string trim(std::string const& source, char const* delims = " \t\r\n") {
  std::string result(source);
  std::string::size_type index = result.find_last_not_of(delims);
  if(index != std::string::npos)
    result.erase(++index);

  index = result.find_first_not_of(delims);
  if(index != std::string::npos)
    result.erase(0, index);
  else
    result.erase();
  return result;
}


А еще у CString есть методи TrimLeft и TrimRight 

P.S. или ти спрашиваеш про C, а не про C++? 

Это сообщение отредактировал(а) Darhazer - 28.5.2006, 14:37


--------------------
I'm a wheel, I'm a wheel, I can roll, I can feel
But you can't stop me turning
'Cause I'm the sun, I'm the sun, I can move, I can run
But you'll never stom me burning
PM MAIL WWW ICQ YIM   Вверх
LPBOY
Дата 28.5.2006, 14:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 228
Регистрация: 12.7.2005

Репутация: 20
Всего: 20



Вот моя версия
Код

#include <iostream>
#include <cstring>

char* trim(const char* s)
{
    const char SPACE = ' ';
    int i = 0, j;
    for(; s[i] == SPACE; ++i);
    if (s[i] == 0) return new char[1]();//возвращаем "".

    for(j = strlen(s) - 1; s[j] == SPACE; --j);
    int sz = j - i + 2;
    char* new_s = new char[sz];
    strncpy(new_s, s + i, sz - 1);
    new_s[sz - 1] = 0;
    return new_s;
}

int main()
{
    char str[] = "  string   ";
    char *s = trim(str);
    std::cout << s << '\n';

    delete [] s;
    return 0;
}


STL-версия: http://blogs.msdn.com/marcod/archive/2005/07/08/StdTrim.aspx

 Voldemar2004, писать в такую строку
Код

char *NoSpace = "";

нельзя. Это просто указатель, никакой памяти не выделялось, разве что для константной литеральной строки "" размером 1, в которую также писать нельзя.
Надо делать или так
Код

char str[size];

если размер известен во время компиляции, иначе так
Код

char* str = new char[size];
  

Это сообщение отредактировал(а) LPBOY - 28.5.2006, 15:16
--------------------
Каждый человек по-своему прав, а по-моему нет...
PM MAIL   Вверх
Voldemar2004
Дата 3.6.2006, 12:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1650
Регистрация: 25.12.2004

Репутация: нет
Всего: 23



Цитата(LPBOY @  28.5.2006,  15:48 Найти цитируемый пост)
Voldemar2004, писать в такую строку нельзя.
Пардон, это я сглупил. Вот исправил:
Код
#include <iostream.h>
#include <conio.h>
#include <string.h>

char *NoSpace(char *a)
{
unsigned int i=0;

        for(i; a[i] == ' '; i++) {;} /* Пока не встретится символ пробела. */

        const CutLenLeft = i;        /* Номер 1-го элемента, не равного ' '. */

        /* Номер 1-го элемента, не равного ' ' - просмотр справа. */
        for(i=strlen(a); i--; i>0) {if( a[i] != ' ' ) break;}

                const CutLenRight = i;

                /* Число символов, включая пробелы
                без левых и правых крайних пробелов. */
                int length = CutLenRight - CutLenLeft + 1;

                        if(length) /* Если есть хотя бы один пробел. */
                        {
                         /* В новый массив запишем результат. */
                         char *b = new char[length];

                                unsigned int j=0;

                                for(i=CutLenLeft; i<CutLenRight+1; i++)
                                {
                                b[j] = a[i];
                                j++;
                                }

                        return b;

                        delete[] b; /* char *b    */
                        }                /* if(length) */
}

void main(void)
{

cout<<NoSpace("     Hello, World!   ");

getch();
}


Цитата(Voldemar2004 @  28.5.2006,  14:17 Найти цитируемый пост)
не получается сделать из этого кода функцию типа этого:
А это потому, что у меня присутствует:
Код
char *NoSpace = "";
 - памяти не выделилось, как верно заметил LPBOY, и это же значение я пытался возвратить.

Как думаете, есть еще недочеты?

LPBOY, в этой строке у тебя по-моему ошибка:
Код
if (s[i] == 0) return new char[1]();//возвращаем "".
Или я чего-то не понял, зачем круглые скобочки после переопределения размера массива? LPBOY, если я возвращу такое значение
Код
cout<<trim("");
то компилятор цепляет мусор (причем каждый компилятор - свой).

Цитата(Darhazer @  28.5.2006,  15:33 Найти цитируемый пост)
P.S. или ти спрашиваеш про C, а не про C++? 
Я спрашивал, есть ли функция наподобие int strlen(char *) из библиотеки string или другой библиотеки, которая отсекала бы пробелы. 


--------------------
i_i 
(';') 
(V)

user posted image
PM MAIL   Вверх
LPBOY
Дата 5.6.2006, 19:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 228
Регистрация: 12.7.2005

Репутация: 20
Всего: 20



Цитата(Voldemar2004 @  3.6.2006,  12:45 Найти цитируемый пост)
Как думаете, есть еще недочеты?

Компилировать я не пробовал, но вот, что бросается в глаза...

(строка 9) for(i; a[i] == ' '; i++) {;} 
Зачем нужно выделенное? Это, конечно, не ошибка, но абсолютно бесполезно.

(11) const CutLenLeft = i;  //надо const int CutLenLeft = i;
Не забывай указывать тип, компиляторы строго придерживающиеся стандарта такое не скомпилируют.

(14) for(i=strlen(a); i--; i>0)
Наверно, ты имел в виду вот так: for(i=strlen(a); i>0; i--)   ;)
Хотя более правильно будет так:
for(i=strlen(a) - 1; i>=0; i--)

(37) delete[] b;
Эта строчка никогда не выполнится. Да и в любом случае очищать память должна вызывающая сторона.

Для случая, когда length равно нулю, и блок if не выполняется, нет соответствующего return.

Память, выделенная для новой строки, не очищается, надо сделать как-то так:
Код

char* s = NoSpace("     Hello, World!   ");
cout << s;
delete[] s;


Цитата(Voldemar2004 @  3.6.2006,  12:45 Найти цитируемый пост)
зачем круглые скобочки после переопределения размера массива?

По идее они должны обнулять массив. Хотя старые компиляторы могут не знать про такой синтаксис. Это можно переписать вот так:
Код

if (s[i] == 0) 
{
    char* t = new char[1];
    t[0] = 0;
    return t;
}


Цитата(Voldemar2004 @  3.6.2006,  12:45 Найти цитируемый пост)
если я возвращу такое значение то компилятор цепляет мусор

У меня, вроде, правильно отрабатывает. 
--------------------
Каждый человек по-своему прав, а по-моему нет...
PM MAIL   Вверх
Voldemar2004
Дата 6.6.2006, 13:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1650
Регистрация: 25.12.2004

Репутация: нет
Всего: 23



Цитата(LPBOY @  5.6.2006,  20:17 Найти цитируемый пост)
Не забывай указывать тип, компиляторы строго придерживающиеся стандарта такое не скомпилируют.
Цитата(LPBOY @  5.6.2006,  20:17 Найти цитируемый пост)
По идее они должны обнулять массив. Хотя старые компиляторы могут не знать про такой синтаксис.
Я использовал Borland C++ 5.02 (не Builder) и KDevelop. Ни о каких ошибках они меня не предупреждали. LPBOY, а ты какой компилятор используешь? 


--------------------
i_i 
(';') 
(V)

user posted image
PM MAIL   Вверх
LPBOY
Дата 6.6.2006, 14:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 228
Регистрация: 12.7.2005

Репутация: 20
Всего: 20



gcc выдает ошибку. 
--------------------
Каждый человек по-своему прав, а по-моему нет...
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0573 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.