Форум программистов, компьютерный форум CyberForum.ru

Удаление лишних пробелов в начале и конце строки. - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 64, средняя оценка - 4.75
Zion3439
2 / 2 / 0
Регистрация: 04.03.2009
Сообщений: 30
04.03.2009, 13:31     Удаление лишних пробелов в начале и конце строки. #1
Нужно написать функцию char*alltrim(char*string) для удаления пробелов в начале и конце строки с помощью указателей. Помогите завершить задачку.
Возник ряд вопросов:
1) как создать какую-то произвольную переменную типа char ( у меня это p)и записать туда из строки string подстроку начиная с определённого элемента заканчивая другим элементом с помощью указателей? Надо ли в конце этой строки p записать NULL?
2)Как потом эту произвольную переменную ( у меня это p) вернуть как результат работы функции заместо переменной string?
3) Как вобще правильно описать переменную размер которой неизвестен?
Вот чего получилось добится:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream.h>
char*alltrim(char*string)
 {
  int i=0,d=0,c=0,g=0;
  while(*string==' ')  // Считается количество пробелов в начале строки - i
  {
   c=c+1;
   i=i+1;
   *string++;
  }
  while(*string) // Считается количество пробелов в конце строки - d
  {
   if (*string!='\x0')
   {
    if (*string==' ') d=d+1;
    else d=0;
    c=c+1;
    *string++;
   }
  }
  char*p="";
  for(g=c-i;g>d;g--) // Неверная функция. Копируется подстрока без начальных и           конечных пробелов
   *p++=*(string-g);
   return p;
 }
 
 
void main(void)
 {
  clrscr();
  char*x="      q   w   e r       t     y      ";
  *alltrim(x); //На выходе должно получится  "q   w   e r       t     y"
  
 }
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.03.2009, 13:31     Удаление лишних пробелов в начале и конце строки.
Посмотрите здесь:

C++ Удаление лишних пробелов
C++ Удаление лишних пробелов в строке.
C++ Удаление пробелов в начале и конце
C++ удаление лишних пробелов с помощью вспомогательного массива
C++ Удаление лишних пробелов
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Lord_Voodoo
Супер-модератор
 Аватар для Lord_Voodoo
8501 / 2168 / 61
Регистрация: 07.03.2007
Сообщений: 10,836
Завершенные тесты: 1
04.03.2009, 14:04     Удаление лишних пробелов в начале и конце строки. #2
попробуй так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
 int from = 0, to = 0;
 char str[256];
 string res = "";
 cout << "enter string:" << endl;
 cin.getline(str, 256);
 for(int i = 0; i < strlen(str); i++){
      if(str[i] != ' '){
        from = i;
        break;
      }
    }
 for(int i = strlen(str) - 1; i >= 0 ; i--){
      if(str[i] != ' '){
        to = i;
        break;
      }
    }
    for(int i = from; i <= to; i++){
      res += str[i];
    }
 cout << res << endl;
 return 0;
}
Zion3439
2 / 2 / 0
Регистрация: 04.03.2009
Сообщений: 30
04.03.2009, 14:13  [ТС]     Удаление лишних пробелов в начале и конце строки. #3
Ну мне надо это реализовать с помощью указателей.
Lelik
Сообщений: n/a
04.03.2009, 14:21     Удаление лишних пробелов в начале и конце строки. #4
Можно так:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <cstdio>
#include <cstring>
#include <cstdlib>
char* alltrim(char* string){
int i, j = 0;
char ReturnString[strlen(string) + 1];
ReturnString[0] = '\0';
// for(i = 0, j; i < strlen(string); i++)
while(*string != '\0'){
if(*string != ' ') ReturnString[j++] = *string;
string++;
}
ReturnString[j] = '\0';
free(string);
string = strdup(ReturnString);
return string;
}
int main(){
// clrscr(); 
char* x = " q w e r t y ";
printf("Input string - %s\nOutput string - %s\n", x, alltrim(x));
system("PAUSE");
return EXIT_SUCCESS;
}
PS Если тебе надо не на С, а на С++, то действительно проще использовать cin и cout
Что неясно, пиши - объясню
Забавно, что у меня в Studio не хочет компилироваться, а Dev C++ нормально относится к strlen(string)
Zion3439
2 / 2 / 0
Регистрация: 04.03.2009
Сообщений: 30
04.03.2009, 14:30  [ТС]     Удаление лишних пробелов в начале и конце строки. #5
Lelik подскажи пожалуйсто:
#include <cstdio>
#include <cstring>
#include <cstdlib>

char* alltrim(char* string)
{
int i, j = 0;
char ReturnString[strlen(string) + 1]; //Что такое ReturnString и strlen?
ReturnString[0] = '\0'; // соответственно что делает вот эта команда?

// for(i = 0, j; i < strlen(string); i++)
while(*string != '\0')
{
if(*string != ' ') ReturnString[j++] = *string;
string++;
}
ReturnString[j] = '\0';

free(string); // Это как я понимаю очищает переменную, или как?
string = strdup(ReturnString); // что такое strdup?
return string;
}

int main()
{
// clrscr();
char* x = " q w e r t y ";
printf("Input string - %s\nOutput string - %s\n", x, alltrim(x));
system("PAUSE");
return EXIT_SUCCESS;
}
PS: Я на эту прогу уже дня 4 угрохал всё одолеть немогу, вечно под самый конец программы возникают проблемы с присвоением полученого результата какойто переменной.%)
Lord_Voodoo
Супер-модератор
 Аватар для Lord_Voodoo
8501 / 2168 / 61
Регистрация: 07.03.2007
Сообщений: 10,836
Завершенные тесты: 1
04.03.2009, 14:32     Удаление лишних пробелов в начале и конце строки. #6
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <iostream>
#include <string.h>
#include <alloc.h>
using namespace std;
string trimall1(char* str){
  int from = 0, to = 0;
  string res = "";
  for(int i = 0; i < strlen(str); i++){
    if(str[i] != ' '){
      from = i;
      break;
    }
  }
  for(int i = strlen(str) - 1; i >= 0 ; i--){
    if(str[i] != ' '){
      to = i;
      break;
    }
  }
  for(int i = from; i <= to; i++){
    res += str[i];
  }
  return res;
}
char* trimall2(char* str){
  int from = 0, to = 0, j = 0;
  for(int i = 0; i < strlen(str); i++){
    if(str[i] != ' '){
      from = i;
      break;
    }
  }
  for(int i = strlen(str) - 1; i >= 0 ; i--){
    if(str[i] != ' '){
      to = i;
      break;
    }
  }
  char* res = (char*)malloc((to - from)*sizeof(char));
  memset(res, ' ', (to - from));
  for(int i = from; i <= to; i++){
    res[j++] = str[i];
  }
  return res;
}
int main()
{
    char* str = (char*)malloc(256*sizeof(char));
    cout << "enter string:" << endl;
    cin.getline(str, 256);
    cout <<"1. start_line_" <<trimall1(str)<<"_endline" << endl;
    cout <<"2. start_line_" <<trimall2(str)<<"_endline" << endl;
    return 0;
}
Lelik
Сообщений: n/a
04.03.2009, 14:37     Удаление лишних пробелов в начале и конце строки. #7
char ReturnString[strlen(string) + 1]; - просто создаем статическую переменную типа char длиной, равной длине переданной нам строки + 1 (для нулевого символа).

ReturnString[0] = '\0'; - говорим, что строка пустая ('\0' - это конец строки)

free(string); - ты в main() выделил память под, ее нужно очистить прежде, чем указатель будет указывать на другую область памяти.

string = strdup(ReturnString);

DESCRIPTION
The strdup() function shall return a pointer to a new string, which is a duplicate of the string pointed to by s1. The returned pointer can be passed to free(). A null pointer is returned if the new string cannot be created.

RETURN VALUE
The strdup() function shall return a pointer to a new string on success. Otherwise, it shall return a null pointer and set errno to indicate the error.

ERRORS
The strdup() function may fail if:

[ENOMEM]
Storage space available is insufficient.

Если коротко, то strdup() выделяет память под новую строку и копирует входную, возвращая указатель на выделенную область памяти
Humanitis
 Аватар для Humanitis
170 / 162 / 5
Регистрация: 12.01.2009
Сообщений: 430
04.03.2009, 14:44     Удаление лишних пробелов в начале и конце строки. #8
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
char*alltrim(char*string)
 {
    char *p,*iter;
    while(*string++==' ');
    iter=--string;
    while(*iter)iter++;
    while(*(--iter)==' ');
    p=new char[iter-string+1];
    char *result=p;
    while(string<=iter)*p++=*string++;
    *p=0;
   return result;
 }
 
 
int main(void)
 {
  char*x="      q   w   e r       t     y    ";
  std::cout<<alltrim(x); //На выходе должно получится  "q   w   e r       t     y"
  system("pause");
  return 0;
 }
Zion3439
2 / 2 / 0
Регистрация: 04.03.2009
Сообщений: 30
04.03.2009, 15:46  [ТС]     Удаление лишних пробелов в начале и конце строки. #9
Так я попробовал разные ваши способы, но всётаки хотелось бы улучшить свой.
#include <iostream.h>
#include <conio.h>
#include <string.h>
#include <alloc.h>

char*alltrim(char*string)
{
int i=0,d=0,c=0,g=0,j=0;
while(*string==' ')
{
c=c+1;
i=i+1;
*string++;
}
while(*string)
{
if (*string!='\x0')
{
if (*string==' ') d=d+1;
else d=0;
c=c+1;
*string++;
}
}
char*p=new char[c-d-i+1];
for(g=c-i;g>d;g--)
p[j++]=*(string-g);
p[j]='\0';
cout<<p; //тут выводит всё как надо - "q w e r t y"(без пробелов по бокам)
return p;

}


void main(void)
{
clrscr();
char*x=" q w e r t y ";
*alltrim(x);
cout<<x; //а тут почему-то уже выводит - " q w e r t y " (с пробелами по бокам)
}
В чём моя ошибка?
Humanitis
 Аватар для Humanitis
170 / 162 / 5
Регистрация: 12.01.2009
Сообщений: 430
04.03.2009, 16:05     Удаление лишних пробелов в начале и конце строки. #10
делай так
C++
1
cout<<alltrim(x);
Zion3439
2 / 2 / 0
Регистрация: 04.03.2009
Сообщений: 30
04.03.2009, 16:09  [ТС]     Удаление лишних пробелов в начале и конце строки. #11
ООООО, всем огромное человеческое спасибо! Всё заработало =)))
accept
4838 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
05.03.2009, 01:28     Удаление лишних пробелов в начале и конце строки. #12
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <string.h>
 
/* SqueezeSpaces:  удаляет из s группы пробелов _по краям_ */
int SqueezeSpaces(char *s)
{
    char *startp, *endp;
    
    if (s == NULL)
        return EOF;
    for (startp = s; *startp == ' '; startp++)
        ;
    if (startp-s > 0) {
        endp = startp;
        startp = s;
        while (*startp++ = *endp++)
            ;
    }
    endp = s+strlen(s);
    while (*--endp == ' ')
        *endp = '\0';
    return 1;        
}
лучше, конечно, пробелы в конце сразу определить, а то для длинной строки будет дольше работать
Humanitis
 Аватар для Humanitis
170 / 162 / 5
Регистрация: 12.01.2009
Сообщений: 430
05.03.2009, 11:16     Удаление лишних пробелов в начале и конце строки. #13
C++
1
2
    while (*--endp == ' ')
    *endp = '\0';
Дойдет до первого символа,не равного пробелу и заменит его на ноль.
Так вот наверное будет правильней
C++
1
2
    while (*--endp == ' ')
    *++endp = '\0';
accept
4838 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
05.03.2009, 11:53     Удаление лишних пробелов в начале и конце строки. #14
Цитата Сообщение от Humanitis
Дойдет до первого символа,не равного пробелу
и всё

а так бесконечный цикл получится на первом пробеле
Humanitis
 Аватар для Humanitis
170 / 162 / 5
Регистрация: 12.01.2009
Сообщений: 430
05.03.2009, 12:59     Удаление лишних пробелов в начале и конце строки. #15
Да я про то,что последний символ, не равный пробелу, не стоит заменять нулем.
C++
1
2
3
    while (*--endp == ' ');
 
    *++endp = '\0';
Не заметил,что ты каждый раз заменяешь нулем...думал просто сдвигаешься вниз,а потом заменяешь нулем
accept
4838 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
05.03.2009, 13:18     Удаление лишних пробелов в начале и конце строки. #16
Код
*--endp == ' '
он сдвинул влево, проверил если там пробел
если пробел - зашёл в цикл поставил ноль, иначе не зашёл в цикл

а у тебя он сдвинул влево, зашёл допустим потому что там пробел, сдвинул вправо поставил ноль и опять сдвигает влево, то есть находит тот же пробел
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9371 / 5421 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
13.08.2009, 19:21     Удаление лишних пробелов в начале и конце строки. #17
Примерно то же самое, но не работает:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <stdio.h>
#include <ctype.h>
#include <string.h>
 
/* char *trunc_str(char *) - должна бы выдавать указатель на строку без начальных и конечных пробелов */
char *trunc_str(char *str){
    char *start;
    char *stop;
 
/* Не работает! */
    for ( start = str; isspace(*start); start++ )
        ;
/* Работает... */
    for ( stop = str + strlen(str) - 1; isspace(*stop) && stop > start; stop-- )
        ;
    *++stop = 0;
 
    return start;
}
 
int main(){
    char buf[BUFSIZ];
 
    while ( fgets(buf, BUFSIZ, stdin) ) {
        trunc_str(buf);
        if ( buf ) printf("\"%s\"\n", buf);
    }
/* Пробелы в начале строки остаются, в конце удаляются */
 
    return 0;
}
Извиняюсь, я всё понял!
C
1
2
3
while ( fgets(buf, BUFSIZ, stdin) ) {
        printf("\"%s\"\n",trunc_str(buf));
    }
Gravity
 Аватар для Gravity
556 / 550 / 39
Регистрация: 29.01.2009
Сообщений: 1,274
13.08.2009, 19:27     Удаление лишних пробелов в начале и конце строки. #18
C
1
2
3
/* Не работает! */
        for ( start = str; isspace(*start); start++ )
                ;
А почему оно должно работать, если цикл пустой.

Добавлено через 55 секунд
О, и я все понял
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9371 / 5421 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
13.08.2009, 19:39     Удаление лишних пробелов в начале и конце строки. #19
Кстати, можно и короче

C
1
2
3
4
5
6
7
8
9
10
char *trunc_str(char *str){
    char *stop;
    for ( ; isspace(*str); str++ )
        ;
    for ( stop = str + strlen(str) - 1; isspace(*stop) && stop > str; stop-- )
        ;
    *++stop = 0;
 
    return str;
}
Добавлено через 3 минуты 41 секунду
Цитата Сообщение от Gravity Посмотреть сообщение
C
1
2
3
/* Не работает! */
        for ( start = str; isspace(*start); start++ )
                ;
А почему оно должно работать, если цикл пустой.

Добавлено через 55 секунд
О, и я все понял
Оно на самом деле работает, а цикл пустой - так в нём start++ пока isspace(*start) от него больше и не нужно. Я в printf по сути обрезанную с конца buf передавал, а так всё получилось. Ну разве что пустые строки неправильно обрабатываются - указатель на "\n" получается. Можно поправить, можно отслеживать...
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
14.08.2009, 00:45     Удаление лишних пробелов в начале и конце строки.
Еще ссылки по теме:

Удаление лишних пробелов C++
C++ Создание программы со своей библиотекой ( удаление элементов с N по M в строке и удаление лишних пробелов(если 2 и более оставить один))
C++ Рекурсия. Удаление лишних пробелов

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
sledge
0 / 0 / 0
Регистрация: 27.07.2009
Сообщений: 13
14.08.2009, 00:45     Удаление лишних пробелов в начале и конце строки. #20
Если еще актуально, я просто для себя разбирался, прокомментировал заодно:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <iostream.h>
//#include <conio.h>
//#include <string.h>
//#include <alloc.h>
 
char* alltrim( char*string)
{
int i=0,d=0,c=0,g=0,j=0;
while(*string==' ')
{
    c=c+1;      //total_length
    i=i+1;      //spaces_before
    string++;   //было *string++; *string++ - значит получить значение(char)на   которое сейчас указывает string а после этого увеличить указательна на один .
//достаточно просто увеличить указатель
}
while(*string)
{
    if (*string!='\x0')// Этот if не нужен. *string!='\x0' можно перенести в while
    {                  // либо вообще убрать
        if (*string==' ') d=d+1;//spaces_after
        else d=0;
        c=c+1;              //total_length
        string++;           //было *string++;
    }
}
char*p=new char[c-d-i+1];// выделение памяти
for(g=c-i;g>d;g--) p[j++]=*(string-g); // сердце функции хитрое какое :-)
p[j]='\0';
cout<<"_"<<p<<"_"<<endl; //тут выводит всё как надо - "q w e r t y"(без пробелов по бокам)
return p;       // функция возвращает указатель, его нужно присвоить такому же указателю такого ж
                // типа, после окочания работы функии указатель p уничтожается и на выделенную
                //выше память никто не указывает - она утекла.
}
int main(void)
{
//clrscr();
char*x=" q w e r t y ";
//*alltrim(x);  тут ты просто вызвал функцию она себе отработала, создала локальную переменную p,
                //которая после возврата из функции умерла.
char *result;
result=alltrim(x); //  тут обЪявляется и инициализируется указатель который и словит значение p.
cout<<"_"<<result<<"_"; //а тут почему-то уже выводит - " q w e r t y " (с пробелами по бокам)return 0;
}
Yandex
Объявления
14.08.2009, 00:45     Удаление лишних пробелов в начале и конце строки.
Ответ Создать тему
Опции темы

Текущее время: 03:12. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru