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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 31, средняя оценка - 4.97
x-positive
1 / 1 / 0
Регистрация: 09.02.2011
Сообщений: 21
#1

Указатели char* - конкатенация без <string.h> - C++

10.06.2011, 02:03. Просмотров 4241. Ответов 16
Метки нет (Все метки)

C++
1
2
3
4
5
6
7
8
char *pp,*p,*s1;
 
[...] // p и s1 имеют свои значения, по сути необходимо из "p" сделать соединение "s1+p" (строго без <string.h> ! это значение будет храниться в "p")
 
*pp = *p;
*p = *s1;
while(*(p++));
*p = *pp;
В таком вот небольшом отрывочке кода есть один большой недостаток: он работает только с первыми символами строк. Я попытался как-то уладить эту проблему. Но следующий код работает вообще безобразно:

C++
1
2
3
4
while(*p)  { *pp++ = *p++; i++; } *pp-=i; *p-=i; i=0;
while(*s1) { *p++ = *s1++; i++; } *p-=i; *s1-=i; i=0;
while(*(p++));
while(*pp) { *p++ = *pp++; i++; } *p-=i; *pp-=i; i=0;
Подскажите, как решается данная проблема.
Код должен быть примерно таким, разница только в неучтённых ньюансах. Я только знакомлюсь с указателями, поэтому мог много чего не учесть. Подскажите, как мне исправиться.

Благодарю.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.06.2011, 02:03
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Указатели char* - конкатенация без <string.h> (C++):

Конкатенация без <string> - C++
Продемонстрируйте работу с указателями. Напишите полностью законченную функцию конкатенации (сложения) двух строк (char *). Использовать...

Добавить 3 переменные в массив char без использования библиотеки string - C++
задача такая: есть 3 переменные, которые вводит пользователь адрес сервера, юзер, сообщение. нужно запихнуть их в массив char без...

есть массив char. есть строка string. как присвоить значению string-a значение char-a? - C++
есть массив char. есть строка string. как присвоить значению string-a значение char-a?

конкатенация char - C++
Привет!!! Пытаюсь разобраться с указателями char ничего не получается. вот код: #include &lt;iostream&gt; using std::cout; using...

Перевод переменной из int в char и конкатенация строк - C++
вообщем вот кусок кода. max - это та самая переменная которую нужно было мне перевести в char, но потом у меня никак не получается...

Передача в функцию char*([Warning] deprecated conversion from string constant to 'char*' [-Wwrite-strings]) - C++
Почему компилятор на это матерится? ObjA.Show(&quot;A&quot;); deprecated conversion from string constant to 'char*' #include &lt;iostream&gt; ...

16
Kastaneda
Форумчанин
Эксперт С++
4655 / 2863 / 228
Регистрация: 12.12.2009
Сообщений: 7,274
Записей в блоге: 2
Завершенные тесты: 1
10.06.2011, 06:53 #2
Если нужно именно через указатели, то вот:
C++
1
2
3
4
5
char str1[12]={"Hello "};//в первой строке должно быть достаточно места, чтоб вместить вторую
char str2[]={"World"};
char *ptr1=str1+strlen(str1), *ptr2=str2;
while(*ptr1++=*ptr2++);
*ptr1='\0';
1
pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
10.06.2011, 07:02 #3
strlen разве не из string.h? надо сначала длину первой строки вычислить простым циклом пока нулевой символ не встретиться, а потом склеивать. Поэтому чар говно
0
Kastaneda
Форумчанин
Эксперт С++
4655 / 2863 / 228
Регистрация: 12.12.2009
Сообщений: 7,274
Записей в блоге: 2
Завершенные тесты: 1
10.06.2011, 07:11 #4
strlen разве не из string.h? надо сначала длину первой строки вычислить простым циклом
Это я так, чтоб показать, как конкатенировать строки.
Поэтому чар говно
??? Обычный массив байт.
0
pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
10.06.2011, 08:01 #5
ну всмысле скорости работы, его только в учебных целях и осталось использовать
0
accept
4822 / 3243 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
10.06.2011, 08:35 #6
Цитата Сообщение от x-positive
Подскажите, как решается данная проблема.
нужно читать про операции и циклы

C
1
2
3
4
5
6
7
8
    char s1[100] = "abcd";
    char s2[] = "efgh";
    char *p1, *p2;
 
    for (p1 = s1; *p1 != '\0'; p1++)
        ;
    for (p2 = s2; (*p1 = *p2) != '\0'; p1++, p2++)
        ;
0
x-positive
1 / 1 / 0
Регистрация: 09.02.2011
Сообщений: 21
10.06.2011, 08:43  [ТС] #7
На счёт длины: они все имеют равную длину, больше длины содержащегося в них текста.
Что касается char*pp в моём коде - я решил объявлять её так - char *pp=(char*)malloc(MAX);

вообще, мой код выглядит подобным образом, но вызывает сбой программы и завершение с ошибкой.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
char* StrIns(char*s,char*s1,char*p)
{
 int i=1;
 char *pp=(char*)malloc(MAX);
 
 while(*p)  { *pp++ = *p++; i++; } *pp = '\0'; *pp-=i; *p-=i; i=0;
 while(*s1) { *p++ = *s1++; i++; } *p = '\0'; *p-=i; *s1-=i; i=0;
 while(*(p++));
 while(*pp) { *p++ = *pp++; i++; } *p = '\0'; *p-=i; *pp-=i; i=0;
 
 free(pp);
 return s;
}
пересылаемые строки char*s,char*s1,char*p оглашаются char s[MAX],*space="_",*find; и инициализируются пользователем с клавиатуры, кроме find - сохраняет значение одной искомой подстроки... да что уж там
полный код программы
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#define MAX 128
#define ENTER '\r'
 
char* StrStr(char*s, char*s1)
{
 char *copy_s, *copy_s1 = s1;
 while (*s)
  {
   copy_s = s;
   if(*s++ == *s1++) return copy_s;
   s1 = copy_s1;
  }
 return NULL;
}
 
char* StrIns(char*s,char*s1,char*p)
{
 int i=1;
 char *pp=(char*)malloc(MAX);
 
 while(*p)  { *pp++ = *p++; i++; } *pp = '\0'; *pp-=i; *p-=i; i=0;
 while(*s1) { *p++ = *s1++; i++; } *p = '\0'; *p-=i; *s1-=i; i=0;
 while(*(p++));                                        
 while(*pp) { *p++ = *pp++; i++; } *p = '\0'; *p-=i; *pp-=i; i=0;
 
 free(pp);
 return s;
}
 
main()
{
 char s[MAX],s1[MAX],*space="_",*find=(char*)malloc(MAX);
 int i=0,len_S1;
 char* StrStr(char*,char*);
 char* StrIns(char*,char*,char*);
 
 printf("s = ");
 do s[i]=getche();
 while(s[i++]!=ENTER);
 s[i-1]='\0';
 i=0;
 
 printf("\n\ns1= ");
 do s1[i]=getche();
 while(s1[i++]!=ENTER);
 s1[i-1]='\0';
 len_S1=i-1;
 
 puts("\n\nResults:\n");
 
 if (find = StrStr(s,s1))
 {
  do
  {
    StrIns(s,space,find);
    StrIns(s,space,find+len_S1+1);
    find+=len_S1+2;
  }
  while (find = StrStr(find+=len_S1,s1));
  puts(s);
 }
 else printf("Not found s1 in s.");
 
 getch();
 return 0;
}
(причём всё работало безупречно, кроме второй функции. она то и вызывает сбой.)
0
x-positive
1 / 1 / 0
Регистрация: 09.02.2011
Сообщений: 21
10.06.2011, 08:57  [ТС] #8
Цитата Сообщение от accept Посмотреть сообщение
нужно читать про операции и циклы
Кстати, первой мое попыткой было реализовать это с помощью for. Попытка оказалась намного более громоздкой и провальной, к тому же запутаннее. Возможно потому что нужно читать про циклы.

А вот здесь по-моему так нужно? :
Цитата Сообщение от accept Посмотреть сообщение
нужно читать про операции и циклы

C
1
2
3
4
5
6
7
8
9
    char s1[100] = "abcd";
    char s2[] = "efgh";
    char *p1, *p2;
 
    for (p1 = s1; *p1 != '\0'; p1++)
        ;
    for (p2 = s2; (*p1 = *p2) != '\0'; p1++, p2++)
        ;
   *p1 = '\0' ;
Чтож, я учусь ещё. Не судите строго. Я за C++ взялся только с Февраля...

Добавлено через 6 минут
Кстати заметил что вместо

C++
1
2
3
4
while(*p)  { *pp++ = *p++; i++; } *pp = '\0'; *pp-=i; *p-=i; i=0;
while(*s1) { *p++ = *s1++; i++; } *p = '\0'; *p-=i; *s1-=i; i=0;
while(*(p++));                                        
while(*pp) { *p++ = *pp++; i++; } *p = '\0'; *p-=i; *pp-=i; i=0;
Можно написать

C++
1
2
3
 while(*p)  { *pp++ = *p++; i++; } *pp = '\0'; *pp-=i; *p-=i; i=0;
 while(*s1) { *p++ = *s1++; i++; } i=0;
 while(*pp) { *p++ = *pp++; i++; } *p = '\0'; *p-=i; *pp-=i; i=0;
И что будет то же самое..
0
accept
4822 / 3243 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
10.06.2011, 09:33 #9
C
1
*p1 = '\0' ;
это не нужно

не пиши код в одну строчку, это мешает поддержке(maintenance)
отладчик сообщает строку, а когда в ней несколько операторов, непонятно, в каком именно ошибка
1
x-positive
1 / 1 / 0
Регистрация: 09.02.2011
Сообщений: 21
10.06.2011, 09:53  [ТС] #10
Цитата Сообщение от accept Посмотреть сообщение
не пиши код в одну строчку, это мешает поддержке(maintenance)
отладчик сообщает строку, а когда в ней несколько операторов, непонятно, в каком именно ошибка
да я обычно и не пишу, это я сейчас пока программу не дописал.
тем более что компиляция ошибок не выдаёт, а в отладчике я пока не понимаю указаний на ошибки...

Добавлено через 11 минут
Вот, может вам будет легче:

C++
1
2
3
4
5
6
7
8
 while(*p)  { *pp++ = *p++; i++; } *pp = '\0';
 *pp-=i;
 *p-=i;
 i=0;
 while(*s1) { *p++ = *s1++; i++; };
 i=0;
 while(*pp) { *p++ = *pp++; i++; } *p = '\0';
 *p-=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
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#define MAX 128
#define ENTER '\r'
 
char* StrStr(char*s, char*s1)
{
 char *copy_s, *copy_s1 = s1;
 while (*s)
  {
   copy_s = s;
   if(*s++ == *s1++) return copy_s;
   s1 = copy_s1;
  }
 return NULL;
}
 
char* StrIns(char*s,char*s1,char*p)
{
 int i=1;
 char *pp=(char*)malloc(MAX);
 
 while(*p)  { *pp++ = *p++; i++; } *pp = '\0';
 *pp-=i;
 *p-=i;
 i=0;
 while(*s1) { *p++ = *s1++; i++; };
 i=0;
 while(*pp) { *p++ = *pp++; i++; } *p = '\0';
 *p-=i;
 
 free(pp);
 return s;
}
 
main()
{
 char s[MAX],s1[MAX],*space="_",*find=(char*)malloc(MAX);
 int i=0,len_S1;
 char* StrStr(char*,char*);
 char* StrIns(char*,char*,char*);
 
 printf("s = ");
 do s[i]=getche();
 while(s[i++]!=ENTER);
 s[i-1]='\0';
 //len_S=i-1;
 i=0;
 
 printf("\n\ns1= ");
 do s1[i]=getche();
 while(s1[i++]!=ENTER);
 s1[i-1]='\0';
 len_S1=i-1;
 
 puts("\n\nResults:\n");
 
 if (find = StrStr(s,s1))
 {
  do
  {
    StrIns(s,space,find);
    StrIns(s,space,find+len_S1+1);
    find+=len_S1+2;
  }
  while (find = StrStr(find+=len_S1,s1));
  puts(s);
 }
 else printf("Not found s1 in s.");
 
 getch();
 return 0;
}
(ага, и всё также выдаёт сбой...)

P.S. Пытаюсь понять что пишет отладчик, но он указывает на адрес, который я вообще не могу найти в программе. С отладчиком я пока не дружу..
0
accept
4822 / 3243 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
10.06.2011, 10:52 #11
Цитата Сообщение от x-positive
да я обычно и не пишу, это я сейчас пока программу не дописал.
C++
1
    while(*p)  { *pp++ = *p++; i++; } *pp = '\0';
C++
1
2
3
4
5
    while (*p) {
        *pp++ = *p++;
        i++;
    }
    *pp = '\0';
Добавлено через 11 минут
Цитата Сообщение от x-positive
полный код программы выглядит следующим образом
функция getche(), которая может отсутствовать в каком-нибудь компиляторе, или работать не так, как ожидается

C
1
while (find = StrStr(find+=len_S1,s1));
запутанные конструкции
изменение find, когда там адрес выделенной памяти
нет free(find) в конце

C
1
if (find = StrStr(s,s1))
потеря указателя из find происходит ещё на раннем этапе

C
1
2
3
4
5
6
7
8
9
10
11
char* StrStr(char*s, char*s1)
{
 char *copy_s, *copy_s1 = s1;
 while (*s)
  {
   copy_s = s;
   if(*s++ == *s1++) return copy_s;
   s1 = copy_s1;
  }
 return NULL;
}
strstr() ищет подстроку в строке, здесь даже близко этого не происходит

C++
1
2
3
char* StrIns(char*s,char*s1,char*p)
{
 int i=1;
функция получает три указателя зачем-то
функция использует переменную i, которая вообще не нужна
1
Kastaneda
Форумчанин
Эксперт С++
4655 / 2863 / 228
Регистрация: 12.12.2009
Сообщений: 7,274
Записей в блоге: 2
Завершенные тесты: 1
10.06.2011, 10:59 #12
Цитата Сообщение от pito211 Посмотреть сообщение
ну всмысле скорости работы, его только в учебных целях и осталось использовать
String'и медленне в работе, чем массив char'ов. Потому как string - это тот же массив char, только там еще затраты на выделение/перевыделение памяти.

Или имелась ввиду скорость работы программиста? Тогда да, string конечно удобнее.
0
pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
10.06.2011, 11:41 #13
Цитата Сообщение от Kastaneda Посмотреть сообщение
String'и медленне в работе, чем массив char'ов. Потому как string - это тот же массив char, только там еще затраты на выделение/перевыделение памяти.
в данной теме речь идёт о конкатенации и строки в стиле си явно не самые быстрые в этом плане. Из-за алгоритма маляра Шлемиля
0
-=ЮрА=-
Заблокирован
Автор FAQ
10.06.2011, 12:42 #14
Насколько понял нужно реализовать поиск подстроки и вставку строки без string.h, вот мой код
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <stdio.h>
#include <windows.h>
 
int sLen = 0;
int str_get_len(char * str);
char * str_text = (char *) malloc(sizeof(char));
char * get_text(char * str, char ch_end,int &sLen);
char * str_str(char * str, char * fnd);
char * str_ins(char * str, char * ins, int pos);//Вставить ins в str с позиции pos
 
void main()
{
    printf("ENTER INPUT TEXT\r\n");
    //Проверял на вводе с клавиатуры строки "123 567"
    str_text = get_text(str_text, '\n',sLen);
    printf("%s\r\n",str_text);
    printf("%d\r\n",str_get_len(str_text));
    printf("%s\r\n",str_str(str_text, "567"));
    printf("%s\r\n",str_ins(str_text, "89", 3));
}
 
char * get_text(char * str, char ch_end,int &sLen)
{
    if(str)
    {
        sLen = 0;
        while((str[sLen] = getchar()) != ch_end)
            str = (char *)realloc(str, 
            (1 + (sLen = sLen + 1))*sizeof(char));
        str[sLen] = '\0';
    }
    return str;
}
 
int str_get_len(char * str)
{
    int sLen = 0;
    while((str + sLen)[0] != '\0')
        sLen++;
    return sLen;
}
 
char * str_str(char * str, char * fnd)
{
    int i = 0,j = 0,sLen = 0, fLen = 0;
    if(str != NULL && fnd != NULL)
    {
        sLen = str_get_len(str);
        fLen = str_get_len(fnd);
        while(i < sLen)
        {
            if(str[i] == fnd[j])
            {
                while(j < fLen)
                {
                    if(str[i + j] != fnd[j])
                        break;
                    j++;
                }
                if(j == fLen)
                    break;
                else
                    j = 0;
            }
            i++;
        }
        if(i == sLen)
            i = 0;
        str += i;
    }
    return str;
}
 
char * str_ins(char * str, char * ins, int pos)
{
    int i = 0,n_chr =0,sLen = 0,iLen = 0;
    if(str != NULL && ins != NULL)
    {
        sLen = str_get_len(str);
        iLen = str_get_len(ins);
        if(pos < sLen)
        {
            n_chr = sLen - pos;
            str = (char *)realloc(str,(sLen += iLen));
            memcpy(&str[pos + iLen],&str[pos],n_chr);
            while(i < iLen)
            {
                str[pos + i] = ins[i];
                i++;
            }
            str[sLen] = '\0';
        }
    }
    return str;
}
1
Миниатюры
Указатели char* - конкатенация без <string.h>  
x-positive
1 / 1 / 0
Регистрация: 09.02.2011
Сообщений: 21
10.06.2011, 22:00  [ТС] #15
Всё по порядку:

accept, разделять на строки не было времени, старался срочно успеть решить программу, потому задался целью найти и устранить ошибки )

уже когда вішел из дому, обнаружил отсутствие строки free(find); в конце.
добавил.

что касается алгоритма поиска.
изначально он был устроен иначе и работал.
тем не менее сбои были и без того.
это не из-за поиска.
добавил необходимые изменения, которые вчера почему-то спросонья стёр)))
опять же обнаружил уже уехав.

вот как выглядит поиск. тут уже кажется без ошибок:
C++
1
2
3
4
5
6
7
8
9
10
11
12
char* StrStr(char*s, char*s1)
{
 char *copy_s, *copy_s1 = s1;
 while (*s)
  {
   copy_s = s;
   while(*s++ == *s1++)
    if (!s1) return copy_s;
   s1 = copy_s1;
  }
 return NULL;
}


На счёт трёх указателей, это хорошо подмечено) Можно обойтись и двумя в данном случае.

Да впринципе всё хорошо подмечено, глаз зоркий)))

Ну конечно getche().... даже не знаю что сказать.
Считывание должно быть посимвольным, для того чтобы длина строки могла не ограничиваться 128.
Важное условие.
А что мне в этом случае поможет лучше чем getche() не знаю. Может getc() лучше.. Я не знаю разницу между ними ещё...

Запутанные конструкции...мой метод. Лучше пока не придумал, да и не задавался целью. Опять же потому что эта часть кода срабатывала на ура без использования функции вставки. Поэтому не думал что это может вызвать сбой...

Не выделять память? Изменение то необходимо. А выделение памяти поставил на фонарь... Искал пути решения проблемы...и... Убираю...)

"потеря указателя из find происходит ещё на раннем этапе"
Стоп. А мне он необходим? Если это важно, расскажите поподробнее.. Я в работу указателей только начинаю вникать... Никак не могу разобраться. Со строками начал знакомится. С выделением памяти вообще не знаком. Просто знаю, что важно. Очень интересно разобраться.

Спасибо!

-=ЮрА=-

Сейчас буду разбирать и изучать. Отпишусь. Спасибо!
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.06.2011, 22:00
Привет! Вот еще темы с ответами:

Строка: чем отличается строки string, char, char*? - C++
Помогите разобраться,совсем плохо идёт,чем отличается строки string,char,char* И если можно пару примеров Буду весьма признательна

Как преобразовать char* в string и вывести переменную string на экран? - C++
for (int k = 0; k &lt; 10; k++) { int x = (int)rand() / RAND_MAX + rand() % 6 + 2; char *chars = new char; ...

Где и почему используют ту или иную строку std::string, char[], System::String^ ? - C++
Где и почему используют ту или иную строку std::string, char, System::String^ ? Объясните пожалуйста где нужно использовать...

char char* string и константные значения - C++
Робот может перемещаться в 4 направлениях c-Север, u- Юг, z- Запад, v- Восток ипринемать 3 цифровые команды 0-продолжать движение 1 на...


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

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

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