2 / 2 / 1
Регистрация: 04.03.2009
Сообщений: 30
1

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

04.03.2009, 13:31. Показов 13577. Ответов 28
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Нужно написать функцию 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"
  
 }
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
04.03.2009, 13:31
Ответы с готовыми решениями:

Удаление лишних пробелов в конце строки
На проверочном сайте мое решение не проходит из-за лишнего пробела в выходной строке, как его...

Удаление пробелов в начале и конце
Подскажите, пожалуйста, функцию удаление пробелов в начеле и конце строки? Вот примерный код: //...

Удаление пробелов в начале и в конце
Задание:Предложите два варианта функции, удаляющей из строки ведущие и концевые пробелы ...

Отрезание пробелов в начале и в конце строки
Разработайте функцию std::string Trims(std::string const&amp; str), выполняющую отрезание пробелов в...

28
Супер-модератор
8783 / 2536 / 144
Регистрация: 07.03.2007
Сообщений: 11,873
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;
}
1
2 / 2 / 1
Регистрация: 04.03.2009
Сообщений: 30
04.03.2009, 14:13  [ТС] 3
Ну мне надо это реализовать с помощью указателей.
0
Lelik
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)
2 / 2 / 1
Регистрация: 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 угрохал всё одолеть немогу, вечно под самый конец программы возникают проблемы с присвоением полученого результата какойто переменной.%)
0
Супер-модератор
8783 / 2536 / 144
Регистрация: 07.03.2007
Сообщений: 11,873
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;
}
1
Lelik
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() выделяет память под новую строку и копирует входную, возвращая указатель на выделенную область памяти
176 / 168 / 27
Регистрация: 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;
 }
2
2 / 2 / 1
Регистрация: 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 " (с пробелами по бокам)
}
В чём моя ошибка?
0
176 / 168 / 27
Регистрация: 12.01.2009
Сообщений: 430
04.03.2009, 16:05 10
делай так
C++
1
cout<<alltrim(x);
1
2 / 2 / 1
Регистрация: 04.03.2009
Сообщений: 30
04.03.2009, 16:09  [ТС] 11
ООООО, всем огромное человеческое спасибо! Всё заработало =)))
0
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
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;        
}
лучше, конечно, пробелы в конце сразу определить, а то для длинной строки будет дольше работать
0
176 / 168 / 27
Регистрация: 12.01.2009
Сообщений: 430
05.03.2009, 11:16 13
C++
1
2
    while (*--endp == ' ')
    *endp = '\0';
Дойдет до первого символа,не равного пробелу и заменит его на ноль.
Так вот наверное будет правильней
C++
1
2
    while (*--endp == ' ')
    *++endp = '\0';
0
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
05.03.2009, 11:53 14
Цитата Сообщение от Humanitis
Дойдет до первого символа,не равного пробелу
и всё

а так бесконечный цикл получится на первом пробеле
0
176 / 168 / 27
Регистрация: 12.01.2009
Сообщений: 430
05.03.2009, 12:59 15
Да я про то,что последний символ, не равный пробелу, не стоит заменять нулем.
C++
1
2
3
    while (*--endp == ' ');
 
    *++endp = '\0';
Не заметил,что ты каждый раз заменяешь нулем...думал просто сдвигаешься вниз,а потом заменяешь нулем
0
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
05.03.2009, 13:18 16
Код
*--endp == ' '
он сдвинул влево, проверил если там пробел
если пробел - зашёл в цикл поставил ноль, иначе не зашёл в цикл

а у тебя он сдвинул влево, зашёл допустим потому что там пробел, сдвинул вправо поставил ноль и опять сдвигает влево, то есть находит тот же пробел
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
12453 / 7478 / 1752
Регистрация: 25.07.2009
Сообщений: 13,748
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));
    }
0
577 / 571 / 65
Регистрация: 29.01.2009
Сообщений: 1,274
13.08.2009, 19:27 18
C
1
2
3
/* Не работает! */
        for ( start = str; isspace(*start); start++ )
                ;
А почему оно должно работать, если цикл пустой.

Добавлено через 55 секунд
О, и я все понял
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
12453 / 7478 / 1752
Регистрация: 25.07.2009
Сообщений: 13,748
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" получается. Можно поправить, можно отслеживать...
0
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;
}
0
14.08.2009, 00:45
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
14.08.2009, 00:45
Помогаю со студенческими работами здесь

Удаление лишних пробелов в середине строки
Я написал как мог, всё работает, но если вы знаете как упростить код и написать более проще, то...

Удаление лишних пустых строк и пробелов на конце строки
open(FIL,&quot;azaz.txt&quot;); my @s =&lt;FIL&gt;; close FIL; for ($i=0; $i &lt;= 9; $i++) { if ( length( $s ) &gt;...

Удаление пробелов в начале и в конце строки
Ошибка: Встречено ';', а ожидалось ':' (в первой строке после filtr). Как исправить , почему...

Удаление пробелов в конце и начале списка
Возможно ли в прологе реализовать удаление пробелов из начала и конца списка? Есть задача -...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru