9 / 9 / 8
Регистрация: 20.07.2012
Сообщений: 67
1

ошибка в strcpy

24.10.2013, 22:46. Показов 2010. Ответов 22
Метки нет (Все метки)

я переводил программу с другого языка программирования на С-язык. Там была функция substr.
substr собственно имеет 3 параметра:
1) строка
2) номер начального символа
3) количество символов.

В С-языке её не оказалось (в стандарте). Но я вспомнил, что когда-то вышел из этого положения где-то таким образом
C
1
strncpy(t, (char *)s + 2, 3)
(то есть, вместо функции substr(s, 2, 3) )
то есть, вместо того, чтобы начать копировать строку s с самого начала я её сдвинул на 2 позиции.
сработало нормально.

ну и естественно, пришлось завести дополнительную переменную t. В общем-то в этом и проблема. Я потом захотел скопировать строку t в s, и таким образом освободить память t

вот приблизительный пример.
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
 
void main(void) {
 
char *s = "Hello World";
char *t = (char *)malloc(strlen(s) + 1);
 
memset(t, 0, strlen(s) + 1);
strncpy(t, (char *)s + 2, 3);
strcpy(s, t);
//free(t);
}
На VC++6 strcpy завершает программу аварийно. Что не так?
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
24.10.2013, 22:46
Ответы с готовыми решениями:

Ошибка с strcpy
В данном коде в функции findNearEquals вылетает ошибка доступа к памяти, помогите найти её Вот...

Линейный список и ошибка Warning: passing arg 1 of `strcpy' from incompatible pointer type
Проблема с написанием проги (линейный список). Язык Си. #include &lt;stdio.h&gt; #include &lt;string.h&gt;...

Ошибка с 'strcpy'
Решил после сдачи курсовой, для себя сделать курсовую до конца, и брать не честно стыренную у...

Ошибка в strcpy
Прошу помощи. Ругается на вторую строку char* EnteredText = new char; strcpy(EnteredText,...

22
titavich
24.10.2013, 22:59
  #2

Не по теме:

прошу прощения, ошибся

0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
25.10.2013, 08:26 3
Цитата Сообщение от wp2 Посмотреть сообщение
Что не так?
UB при попытке модифицировать *s. Пишите s[] = "Hello ...";
Но вообще ф-ция выглядит странно. Зачем пляски с копией если Вы модифицируете оригинал.
0
Эксперт С++
4974 / 3082 / 456
Регистрация: 10.11.2010
Сообщений: 11,160
Записей в блоге: 10
25.10.2013, 10:09 4
Потому что s - эту указатель на константу, хоть и объявлен без модификатора const.
Изменение этих данных вызывает исключение и программа завершается.
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
25.10.2013, 10:21 5
Цитата Сообщение от castaway Посмотреть сообщение
Потому что s - эту указатель на константу, хоть и объявлен без модификатора const.
Это не правда.
0
Эксперт С++
4974 / 3082 / 456
Регистрация: 10.11.2010
Сообщений: 11,160
Записей в блоге: 10
25.10.2013, 10:25 6
Цитата Сообщение от g_u_e_s_t Посмотреть сообщение
Это не правда.
Это правда.
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
25.10.2013, 10:44 7
Цитата Сообщение от castaway Посмотреть сообщение
Это правда.
Можно пруф на любой из стандартов языка?
0
Эксперт С++
4974 / 3082 / 456
Регистрация: 10.11.2010
Сообщений: 11,160
Записей в блоге: 10
25.10.2013, 11:11 8
Строковой литерал имеет тип const char []. Разве это новость?
Выше происходит преобразование типов: const char [] -> char *. GCC выдает по этому поводу предупреждение.
Позже поищу это в стандарте.

Дополнительно:
http://msdn.microsoft.com/en-u... 71%29.ASPX
http://stackoverflow.com/quest... deprecated
http://en.cppreference.com/w/c... ng_literal
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
25.10.2013, 11:20 9
Цитата Сообщение от castaway Посмотреть сообщение
Строковой литерал имеет тип const char []. Разве это новость?
Нет, не новость, это ваши фантазии. Т.е. опять неправда.
Цитата Сообщение от castaway Посмотреть сообщение
Позже поищу это в стандарте.
Я только этого этого и просил, вместо домослов и сказок...
0
Эксперт С++
4974 / 3082 / 456
Регистрация: 10.11.2010
Сообщений: 11,160
Записей в блоге: 10
25.10.2013, 11:22 10
Честно говоря, я вообще не понимаю почему я вам что-то должен доказывать. Хотите - опровергайте.
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
25.10.2013, 11:30 11
Цитата Сообщение от castaway Посмотреть сообщение
Честно говоря, я вообще не понимаю почему я вам что-то должен доказывать. Хотите - опровергайте.
Недолжны конечно, мне просто любопытно откуда такие тараканы в голове могут появиться

Добавлено через 3 минуты
Чтоб вы так не нервничали кусочек из c99/6.5.8:
EXAMPLE 8 The declaration
char s[] = "abc", t[3] = "abc";
defines ‘ ‘plain’’ char array objects s and t whose elements are initialized with character string literals.
This declaration is identical to
char s[] = { 'a', 'b', 'c', '\0' },
t[] = { 'a', 'b', 'c' };
The contents of the arrays are modifiable.
On the other hand, the declaration
char *p = "abc";
defines p with type ‘‘pointer to char’’ and initializes it to point to an object with type ‘‘array of char’’ with length 4 whose elements are initialized with a character string literal. If an attempt is made to use p to modify the contents of the array, the behavior is undefined.
0
9 / 9 / 8
Регистрация: 20.07.2012
Сообщений: 67
25.10.2013, 12:16  [ТС] 12
да, если использовать char s[]="Hello world"; теперь срабатывает.


Добавлено через 14 минут
и теперь, похоже понятно, почему я не мог использовать только одну s:
strncpy(s, (char *)s + 2, 3) - потому что была константой. Теперь норм.
только надо еще добавить:
s[3] = '\0';




зато не работает такая конструкция:
s = strncpy(s, (char *)s + 2, 3);

а вот так работает:

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
 
void main(void) {
 
char *s;
 
 
s = (char *)malloc(12);
strcpy(s, "Hello World");
s = strncpy(s, (char *)s + 2, 3);
s[3] = '\0';
printf("s = %s\n", s);
 
 
}
то есть, malloc теперь обязателен. Мда...
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
25.10.2013, 12:35 13
Цитата Сообщение от wp2 Посмотреть сообщение
то есть, malloc теперь обязателен.
Почему???
0
2015 / 1614 / 489
Регистрация: 31.05.2009
Сообщений: 3,005
25.10.2013, 12:45 14
Цитата Сообщение от g_u_e_s_t Посмотреть сообщение
Это не правда.
Это правда, но относительно C++ В стандарте C99 действительно не упомянается слово const, и тем не менее попытка изменение строкого литерала обозначена как UB.
1
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
25.10.2013, 12:50 15
,rangerx, чудесно, а что говорит об этом стадарт языка foo?
Цитата Сообщение от rangerx Посмотреть сообщение
Это правда, но относительно C++
чудесно, а что говорит об этом стадарт языка foo? А причем тут язык foo?
Цитата Сообщение от rangerx Посмотреть сообщение
обозначена как UB.
Именно. там же сказано какой тип имеет строковый литерал
0
9 / 9 / 8
Регистрация: 20.07.2012
Сообщений: 67
25.10.2013, 13:31  [ТС] 16
Цитата Сообщение от g_u_e_s_t Посмотреть сообщение
Почему???
что почему? Не знаю, почему...

если объявить так:
char s[]="Hello world";

то возникнет ошибка при компиляции s = strncpy(s, (char *)s + 2, 3);

error C2106: '=' : left operand must be l-value
0
Эксперт С++
4974 / 3082 / 456
Регистрация: 10.11.2010
Сообщений: 11,160
Записей в блоге: 10
25.10.2013, 13:35 17

Не по теме:

Цитата Сообщение от rangerx Посмотреть сообщение
Это правда, но относительно C++ :)
Да, я не сразу заметил что зашел в раздел Си. Да и для Си это вроде как UB, хоть и не упомянуто слово const.



Добавлено через 3 минуты
Цитата Сообщение от wp2 Посмотреть сообщение
то возникнет ошибка при компиляции s = strncpy(s, (char *)s + 2, 3);
Тут нет смысла указывать s = , т.к. возвращается первый параметр, а он у тебя и есть s.
0
9 / 9 / 8
Регистрация: 20.07.2012
Сообщений: 67
25.10.2013, 13:39  [ТС] 18
Цитата Сообщение от castaway Посмотреть сообщение
Тут нет смысла указывать s = , т.к. возвращается первый параметр, а он у тебя и есть s.
я знаю. Но всё таки, просто интересно, почему?

кстати, вот так кое-что получается:
*s = strncpy(s, (char *)s + 2, 3);

только выводит не "llo", а "tlo".
Откуда эта t выплыла непонятно...
0
Эксперт С++
4974 / 3082 / 456
Регистрация: 10.11.2010
Сообщений: 11,160
Записей в блоге: 10
25.10.2013, 13:42 19
Цитата Сообщение от wp2 Посмотреть сообщение
кстати, вот так кое-что получается:
*s = strncpy(s, (char *)s + 2, 3);
Ну это глупость. Это равносильно *s = s
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
25.10.2013, 13:55 20
wp2, если хочется обходиться без вспомогательного буфера, то str[n]cpy() вообще не годиться (но работает в большенстве случаев). посмотри на memmove() она разрешает использовать пересекающиеся области памяти.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
25.10.2013, 13:55

Ошибка с strcpy
Ребят, помогите! Я только начинаю изучение с++, подскажите почему при отладке компилятор выдает...

Ошибка использования strcpy
Добрый вечер. В строке 24 появляется ошибка: error C4996: 'strcpy': This function or variable may...

Ошибка при использовании strcpy
Здравствуйте, возникла такая проблема Объявляю массив char * char *names = {&quot;asdfg&quot;,...

Ошибка на шаге strcpy в MVS2015
Выдаёт ошибку на шаге strcpy? Что не так и как исправить? #include &quot;stdafx.h&quot; #include...


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

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

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