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

С++ для начинающих

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

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

19.04.2012, 15:02. Просмотров 2885. Ответов 14
Метки нет (Все метки)

программа которая удаляет из введенной с клавиатуры строки начальные пробелы

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';
}
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.04.2012, 15:02
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Указатель char* (C++):

Объяснить работу функции, возвращающей указатель на указатель на char - C++
Добрый день! Сможете объяснить что означает запись char **InputFile(int &amp;strings);? Почему именно двойное **? Буду очень благодарна...

array char* to char* (значения массива указателей в один указатель) - C++
Как сложить(или вывести в формате char*) все значения массива указателей(char *) воедино, то есть сложить строки и назначить результату...

Указатель на char - C++
Есть программка: #include&lt;iostream&gt; using namespace std; int main() { char *i; char str=&quot;1234567890&quot;; i=str; cout&lt;&lt;&amp;i; ...

Указатель char* - C++
Есть структура struct ITEM { struct { char N, A, S; } NAS; }; struct LIST { ITEM* arr; int count;

Указатель на char - C++
Есть вопрос про указатель на чар: char *x = &quot;okay&quot;; cout &lt;&lt;*x; Объявляю указатель на чар и присваиваю ему строку &quot;окау&quot;....

Char указатель - C++
При current=2 выдает Bad Ptr при работе с указателем вот такой вот код: FILE* file; if( (file=fopen(&quot;E:/input.txt&quot;,&quot;rt&quot;))==NULL) ...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
dimcoder
Полярный
463 / 435 / 68
Регистрация: 11.09.2011
Сообщений: 1,135
19.04.2012, 15:47 #2
Цитата Сообщение от balrak Посмотреть сообщение
char* p = new char;
Начнем с того что это всего лишь выделение памяти для одного символа. Для массива так:
C++
1
char *p = new char[256];
1
Kuzia domovenok
1891 / 1746 / 118
Регистрация: 25.03.2012
Сообщений: 5,925
Записей в блоге: 1
19.04.2012, 15:50 #3
так ты зачем одновременно и p++ и i++ делаешь, да ещё потом p[i] берёшь?
Ты не понял, что при p++ ты уже двигаешь начало строки вперёд. и после этой операции p[0] и будет первой буквой без пробела???

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

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

Добавлено через 15 минут
Может я не правильно понимаю то что сделал?
Я хотел функции передать указатель на строку, что бы строка не копировалась заново
далее в функции найти первый символ , после начальных пробелов
изменить указатель , так что бы он указывал на первый символ найденый раньше
0
Kuzia domovenok
1891 / 1746 / 118
Регистрация: 25.03.2012
Сообщений: 5,925
Записей в блоге: 1
19.04.2012, 16:32 #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;
}
не проверял, писал прямо в форуме.
это с созданием новой строки и копированием в неё.
1
balrak
6 / 6 / 1
Регистрация: 01.04.2012
Сообщений: 81
19.04.2012, 18:50  [ТС] #8
Kuzia domovenok, да я понял свою ошибку на счет сдвигания
я ее исправил
С использованием копирования я могу сделать, но я хотел попробовать сделать что бы не копировать строку . Типа функции передается место начала масива строки , а функция меняет указатель начала этой строки на первый символ после начальных пробелов и что бы этот указатель изменился в main
0
taras atavin
Ушёл с форума.
3569 / 1753 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
19.04.2012, 19:07 #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)
В вызывающей программе значение указателя, то есть адрес начала строки поменяться не может. Надо передавать или ссылку на указатель, или указатель на указатель, или в самой функции физически перемещать сами данные (символы) вместо модификации адреса.
1
easybudda
Модератор
Эксперт CЭксперт С++
9632 / 5580 / 948
Регистрация: 25.07.2009
Сообщений: 10,714
19.04.2012, 19:19 #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;
}
1
balrak
6 / 6 / 1
Регистрация: 01.04.2012
Сообщений: 81
20.04.2012, 01:05  [ТС] #11
Спасибо конечно всем за помошь
но я и сам могу создать еще 1 переменую и вернуть ее функцией.

Цитата Сообщение от taras atavin Посмотреть сообщение
В вызывающей программе значение указателя, то есть адрес начала строки поменяться не может. Надо передавать или ссылку на указатель, или указатель на указатель.
А как передать ссылку на указатель? или как эту задачу решить с помошью указателя на указател?
Но так что бы не копировать строку , а оставить ее в том же куске памяти.
0
-=ЮрА=-
Заблокирован
Автор FAQ
20.04.2012, 01:15 #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;
}
0
Миниатюры
Указатель char*  
-=ЮрА=-
Заблокирован
Автор FAQ
20.04.2012, 01:35 #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
0
easybudda
Модератор
Эксперт CЭксперт С++
9632 / 5580 / 948
Регистрация: 25.07.2009
Сообщений: 10,714
20.04.2012, 02:23 #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;
0
balrak
6 / 6 / 1
Регистрация: 01.04.2012
Сообщений: 81
20.04.2012, 22:00  [ТС] #15
easybudda, так в вашем способе всерано произойдет копирование
C++
1
return (char*)memmove(s, p, strlen(p) + 1);
можно создать такой указатель что бы он указывал на первый символ?
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.04.2012, 22:00
Привет! Вот еще темы с ответами:

Указатель на массив char - C++
Здравствуйте! помогите найти ошибку в коде void getHosts () { char* h; int i = 0; FILE *stream; char line; if( (stream =...

Char и указатель на переменную - C++
void silavetra(pogoda *arr, int size) { int max=arr.sila_vetra; char ind_napravlenie = *arr.n_vetra; char ind_gorod = *arr.gorod;...

Указатель не указывает на CHAR - C++
Доброго всем здравия, совсем запутался, написал примитивный код, а он гад не работает. Как такое возможно? #include &quot;stdafx.h&quot; ...

Сравнение с 0 через указатель *char - C++
wr указатель char. вот так сравниваю с пробелом все работает *wr!= ' '; вот так сравниваю с 0 ошибка программы( не видит нули) ...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
20.04.2012, 22:00
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru