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

Указатель char* - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 20, средняя оценка - 4.85
balrak
6 / 6 / 1
Регистрация: 01.04.2012
Сообщений: 81
19.04.2012, 15:02     Указатель char* #1
программа которая удаляет из введенной с клавиатуры строки начальные пробелы

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>
 
 
void new_string(char* p)
{
    int i = 0;
    while(*p++ == ' ')
    {
        i++;
    }
    std::cout << i << '\n';
    p = &p[i];
    std::cout << p << '\n'; //в этом месте выводится пустая строка
}
 
void main()
{
    char* p = new char;
    std::cout << "Please enter ur string\n";
    std::cin.get(p,256);
    new_string(p);
    std::cout << p << '\n';
}
Не получается сместить указатель на i знаков
Подскажите что не так делаю

При таком варианте работает как нода

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 <iostream>
 
 
int new_string(char* p)
{
    int i = 0;
    while(*p++ == ' ')
    {
        i++;
    }
    std::cout << i << '\n';
    p = &p[i];
    std::cout << p << '\n'; //в этом месте выводится пустая строка
    return i;
}
 
void main()
{
    char* p = new char;
    std::cout << "Please enter ur string\n";
    std::cin.get(p,256);
    int i = new_string(p);
    std::cout << p+i << '\n';
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.04.2012, 15:02     Указатель char*
Посмотрите здесь:

C++ Указатель на массив char и прочее
Сравнение с 0 через указатель *char C++
Указатель на char C++
C++ Указатель на поле типа char []
Указатель на массив char C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
dimcoder
Полярный
 Аватар для dimcoder
449 / 422 / 66
Регистрация: 11.09.2011
Сообщений: 1,108
19.04.2012, 15:47     Указатель char* #2
Цитата Сообщение от balrak Посмотреть сообщение
char* p = new char;
Начнем с того что это всего лишь выделение памяти для одного символа. Для массива так:
C++
1
char *p = new char[256];
Kuzia domovenok
 Аватар для Kuzia domovenok
1883 / 1738 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
19.04.2012, 15:50     Указатель char* #3
так ты зачем одновременно и p++ и i++ делаешь, да ещё потом p[i] берёшь?
Ты не понял, что при p++ ты уже двигаешь начало строки вперёд. и после этой операции p[0] и будет первой буквой без пробела???

да и выделение памяти и правда неверное, тогда уж и освободить память не забывай.
balrak
6 / 6 / 1
Регистрация: 01.04.2012
Сообщений: 81
19.04.2012, 15:54  [ТС]     Указатель char* #4
dimcoder,
Попробовал заменить, но программа работает так же .
Kuzia domovenok
 Аватар для Kuzia domovenok
1883 / 1738 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
19.04.2012, 15:59     Указатель char* #5
а меня ты игнорируешь? Измени БЫСТРО, я сказал.
balrak
6 / 6 / 1
Регистрация: 01.04.2012
Сообщений: 81
19.04.2012, 16:16  [ТС]     Указатель char* #6
Kuzia domovenok, теперь понял ^^
Но все же , когда печатается
Цитата Сообщение от balrak Посмотреть сообщение
std::cout << p << '\n';
то пробелы возращаются.
Почему указатель в главном теле печатает с пробелами , а в функции после сдвига нормально?

Добавлено через 29 секунд
Kuzia domovenok, да я ж не успеваю так быстро))

Добавлено через 15 минут
Может я не правильно понимаю то что сделал?
Я хотел функции передать указатель на строку, что бы строка не копировалась заново
далее в функции найти первый символ , после начальных пробелов
изменить указатель , так что бы он указывал на первый символ найденый раньше
Kuzia domovenok
 Аватар для Kuzia domovenok
1883 / 1738 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
19.04.2012, 16:32     Указатель char* #7
Цитата Сообщение от balrak Посмотреть сообщение
Kuzia domovenok, теперь понял ^^
Но все же , когда печатается

то пробелы возращаются.
Почему указатель в главном теле печатает с пробелами , а в функции после сдвига нормально?

Добавлено через 29 секунд
Kuzia domovenok, да я ж не успеваю так быстро))

Добавлено через 15 минут
Может я не правильно понимаю то что сделал?
Я хотел функции передать указатель на строку, что бы строка не копировалась заново
далее в функции найти первый символ , после начальных пробелов
изменить указатель , так что бы он указывал на первый символ найденый раньше
Я тебе ещё раз повторю: у тебя тут несколько ошибок:
- Ты двигаешь указатель на начало строки несколько раз.
p=" abcd"
первый: в цикле while(*p++==' ')
//p="abcd" i=3
второй p=&(p[i])// p="d"
-После возврата из функции p как и любой другой аргумент функции остаётся прежним.
аналогично обычному аргументу функции, все арифметические операции с указателем не играют никакой роли после выхода.
пример
C++
1
2
3
4
5
6
7
8
9
void new_s(char* p, int i){
while(p[i]==' ') i++;
}
int main(){
char* str="sdfd";
int i=0;
new_s(str, i);
//выход из new_s переменная i всё ещё равна нулю, также и указатель в твоём примере.
}
Надо сделать так:
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 <iostream> 
#include <cstring> 
char* new_string(char* p)
{
    int len = 0;
    char* out;
    while(*p++ == ' ');
    len=strlen(p);
    out=new char[len];
    strcpy(out, p);
    return out;
}
 
void main()
{
    char* p = new char[256];
    char* s;
    std::cout << "Please enter ur string\n";
    std::cin.get(p,256);
    s=new_string(p);
    std::cout << s << '\n';
    delete[] p;
    delete[] s;
}
не проверял, писал прямо в форуме.
это с созданием новой строки и копированием в неё.
balrak
6 / 6 / 1
Регистрация: 01.04.2012
Сообщений: 81
19.04.2012, 18:50  [ТС]     Указатель char* #8
Kuzia domovenok, да я понял свою ошибку на счет сдвигания
я ее исправил
С использованием копирования я могу сделать, но я хотел попробовать сделать что бы не копировать строку . Типа функции передается место начала масива строки , а функция меняет указатель начала этой строки на первый символ после начальных пробелов и что бы этот указатель изменился в main
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
19.04.2012, 19:07     Указатель char* #9
Цитата Сообщение от balrak Посмотреть сообщение
int i = 0;
* * while(*p++ == ' ')
* * {
* * * * i++;
* * }
* * std::cout << i << '\n';
C++
1
while(*p++ == ' ')
уже ищет первый не пробельный символ и на него будет указывать p, задача решена, если не требуется освобождение памяти из-под начальных пробелов.
C++
1
i++;
в этом цикле считает сами пробелы, после этого
Цитата Сообщение от balrak Посмотреть сообщение
p = &p[i];
удалит и не пробельные символы по числу начальных пробелов, в результате можно попасть снова в пробел, то есть результат не только искажается, но ещё и задача снова не решена.

Добавлено через 4 минуты
Цитата Сообщение от balrak Посмотреть сообщение
int new_string(char* p)
В вызывающей программе значение указателя, то есть адрес начала строки поменяться не может. Надо передавать или ссылку на указатель, или указатель на указатель, или в самой функции физически перемещать сами данные (символы) вместо модификации адреса.
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9373 / 5423 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
19.04.2012, 19:19     Указатель char* #10
Цитата Сообщение от balrak Посмотреть сообщение
Типа функции передается место начала масива строки , а функция меняет указатель начала этой строки на первый символ после начальных пробелов и что бы этот указатель изменился в main
Указатель указывает на определённый байт в памяти, и сдвинуть его не получится (по крайней мере вменяемыми средствами) независимо от того, статически была выделена память, на начало которой он указывает, или динамически. Но тем не менее всё проще:
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 <iostream>
#include <cstring>
#include <cctype>
 
char * no_trailing_spaces(char * s){
    char * p = s;
    
    while ( *p && isspace(*p) )
        ++p;
    
    return (char*)memmove(s, p, strlen(p) + 1);
}
 
int main(){
    const size_t MAX_STR_LEN(256);
    char buf[MAX_STR_LEN];
    
    while ( std::cout << "String: " && std::cin.getline(buf, MAX_STR_LEN) && *buf ){
        std::cout << "Returned by function: " << no_trailing_spaces(buf) << std::endl;
        std::cout << "Now string contains: " << buf << std::endl;
    }
    
    return 0;
}
balrak
6 / 6 / 1
Регистрация: 01.04.2012
Сообщений: 81
20.04.2012, 01:05  [ТС]     Указатель char* #11
Спасибо конечно всем за помошь
но я и сам могу создать еще 1 переменую и вернуть ее функцией.

Цитата Сообщение от taras atavin Посмотреть сообщение
В вызывающей программе значение указателя, то есть адрес начала строки поменяться не может. Надо передавать или ссылку на указатель, или указатель на указатель.
А как передать ссылку на указатель? или как эту задачу решить с помошью указателя на указател?
Но так что бы не копировать строку , а оставить ее в том же куске памяти.
-=ЮрА=-
Заблокирован
Автор FAQ
20.04.2012, 01:15     Указатель char* #12
balrak, вот и все дела
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
using namespace std;
 
char * remBegSpaces(char * str)
{
    while(str + 1 && *str == ' ')
        strcpy(str,str + 1);
    return str;
}
 
int main()
{
    char str[256] = {0};
    cout<<"Enter string : ";
    cin.getline(str,255);
    cout<<"Move spaces in begin : "<<strcpy(str, remBegSpaces(str))<<endl;
    system("pause");
    return 0;
}
Миниатюры
Указатель char*  
-=ЮрА=-
Заблокирован
Автор FAQ
20.04.2012, 01:35     Указатель char* #13
То же самое без функций стандартной библиотеки
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
#include <iostream>
using namespace std;
 
char * strcopy(char * str, char * cmp)
{
    char * ptr = str;
    while(*str && *cmp)
        *str++ = *cmp++;
    *str = 0;
    return ptr;
}
 
char * remBegSpaces(char * str)
{
    while(str + 1 && *str == ' ')
        strcopy(str,str + 1);
    return str;
}
 
int main()
{
    char str[] = "          test";
    cout<<"Input string : "<<str<<endl;
    cout<<"Move spaces in begin : "<<strcopy(str,remBegSpaces(str))<<endl;
    system("pause");
    return 0;
}
Отработка
Input string : test
Move spaces in begin : test
Для продолжения нажмите любую клавишу . . .
По ссылке несколько упрощённый вариант без ввода http://codepad.org/zAtUYMjL
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9373 / 5423 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
20.04.2012, 02:23     Указатель char* #14
Цитата Сообщение от balrak Посмотреть сообщение
Но так что бы не копировать строку , а оставить ее в том же куске памяти.
Не получится ничего хорошего из этой затеи. Вот выделили мы некоторый кусок памяти под строку
C++
1
char * ptr = new char[256];
прочитали в него строку
C++
1
cin.getline(ptr, 256);
определили, что первые три символа пробельные и нам не нужны. От большого ума взяли, да и передвинули указатель на три байта вправо. Вопрос - а что с этими тремя байтами будет? Пусть себе болтаются неучтёнными? И ещё вопрос, начиная с какого адреса и сколько памяти должно будет вернуться при попытке её освободить?
C++
1
delete [] ptr; // epic fail
Единственный способ ничего никуда не копировать - создать второй указатель и его двигать
C++
1
2
3
char * pptr = ptr;
while ( *pptr && isspace(*pptr) )
    ++pptr;
но освобождать память нужно будет с того места, с которого она выделена была
C++
1
delete [] ptr;
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.04.2012, 22:00     Указатель char*
Еще ссылки по теме:

Указатель на двумерный массив char С.Прата C++
array char* to char* (значения массива указателей в один указатель) C++
Сохранение/Загрузка указателя на указатель типа char C++

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

Или воспользуйтесь поиском по форуму:
balrak
6 / 6 / 1
Регистрация: 01.04.2012
Сообщений: 81
20.04.2012, 22:00  [ТС]     Указатель char* #15
easybudda, так в вашем способе всерано произойдет копирование
C++
1
return (char*)memmove(s, p, strlen(p) + 1);
можно создать такой указатель что бы он указывал на первый символ?
Yandex
Объявления
20.04.2012, 22:00     Указатель char*
Ответ Создать тему
Опции темы

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