Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 21, средняя оценка - 4.95
manter
0 / 0 / 1
Регистрация: 12.05.2011
Сообщений: 17
#1

strcpy - как быть? - C++

19.09.2011, 22:11. Просмотров 3208. Ответов 36
Метки нет (Все метки)

Всем Доброго времени суток.
Возник вопрос.
В процессе работы над заданием, столкнулся с проблемой, которую не хватает сил обойти.
Вот Код программы:
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include <iostream>
#include <string>
#include<iomanip>
 
using namespace std;
 
struct worker{
    char *name;
    char *spets;
    int   razread;
    
};
 
void init(worker *w, char* Name, char* Spets, int razread){
    w->razread = razread;
    w->name = new char[strlen(Name)+1];
    w->spets = new char[strlen(Spets)+1];
    strcpy(w->name, Name);
    strcpy(w->spets,Spets);
};
    void clearmem(worker *w) {
        delete[] w->name; w->name=NULL;
        delete[] w->razread; w->razread=NULL;
        delete[] w->spets; w->spets=NULL;
    };
 
    int compare(worker* w1, worker* w2) {
        if(w1->razread>w2->razread)
                return 1;
        else
                return 0;
    };
 
    int main(void){
        int n,r,option; //kolvo i razread
        worker W[10];
        worker tmp;
        char *nName, *nSpets;
 
        nName = new char [256];
        nSpets = new char [256];
 
        while(1) {
            cout << "Menu: " << endl;
            cout << "1. Data input " << endl;
            cout << "2. Data output " << endl;
            cout << "3. Data sorting " << endl;
            cout << "4. Data fields change" << endl;
            cout << "5.Exit" << endl;
            cout << "Choose an option: " << endl;
            cin >> option;
 
            switch(option){
            case 1:
                {
                    cout << "Enter the number of workers: "  << endl;
                    cin >> n;
                    for(int i=0;i<n;i++)
                    {
                        cout << "Name: " << endl;
                        cin >> nName;
                        cout << "Spetsialinosti:"  << endl;
                        cin >> nSpets;
                        cout <<"Razread : " << endl;
                        cin >> r;
                        init(&W[i], nName, nSpets, r);
                    }
                }
                break;
            case 2:
                {
                    cout<< "Data array : " << endl;
                    for(int i=0;i<n;i++)
                    {
                        cout << " Item no. " << i+1 << endl;
                        cout << " Name: " << W[i].name;
                        cout << " Spetsialinosti: " << W[i].spets;
                        cout << " Razread: " << W[i].razread << endl;
                    }
                }
                break;
            case 3:
                {
                    for(int i=1;i<n;i++)
                    {
                        if(compare(&W[i-1],&W[i]))
                        {
                            strcpy(nName, W[i].name);
                            strcpy(nSpets, W[i].spets);
                            r=W[i].razread;
                            clearmem(&W[i]);
                            init(&W[i], W[i-1].name, W[i].razread);
                            clearmem(&W[i-1]);
                            init(&W[i-1], nName, nSpets, r);
                        }
                        else break;
                    }
                }
                break;
            case 4:
                {
                    long i;
                    cout << "Enter the index of the item to be changed:"<<endl;
                    cin >> i;
                    cout << "Enter the new Name : " <<endl;
                    cin >> nName;
                    cout << "Enter the new spetsialinosti : "  <<endl;
                    cin >> nSpets ;
                    cout << " Enter the new razread: "  <<endl;
                    cin >> r;
 
                    init(&W[i-1],nName,nSpets,r);
                }
                break;
case5:
    {
        for(int i=0;i<n;i++)
        {
            clearmem(&W[i]);
        }
        return 1;
    }
    break;
            default:
                {
                    cout << "Wrong menu item chosen! Try again, please."<<endl;
                }
            }
        }
        delete [] nName; nName = NULL;
        delete [] nSpets; nSpets = NULL;
        cout << "Done !" << endl;
        return 1;
    };
Проблема в том, что компилятор кричит на "strcpy"... Как быть?
http://www.cyberforum.ru/cpp-beginners/thread700648.html
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.09.2011, 22:11
Я подобрал для вас темы с готовыми решениями и ответами на вопрос strcpy - как быть? (C++):

Как работает strcpy(), где ошибка
Всем привет) Писал задачу, которая из 10 строк выводит самое короткое и первое...

Как заменить функцию fgets на strlen и strcpy?
while (fgets(s1, sz_line, fp)) //будет прочитано 120 символов { // считаем...

Как работает strcpy с точки зрения распределения памяти?
Уважаемые знатоки С++, объясните, пожалуйста, как работает strcpy с точки...

Как установить конец строки при своей реализации функции strcpy()?
Доброго времени суток, попробовал сам реализовать функцию strcpy(). Программа...

strcpy
Недавно начал программировать на C++, в типах плохо ещё разбираюсь... не могу...

36
ForEveR
В астрале
Эксперт С++
7994 / 4753 / 651
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
19.09.2011, 22:13 #2
manter, #include <cstring>
0
manter
0 / 0 / 1
Регистрация: 12.05.2011
Сообщений: 17
20.09.2011, 00:33  [ТС] #3
добавил, никаких изменений... вот что выдает аутпут..:
1>------ Build started: Project: 1, Configuration: Debug Win32 ------
1> 1.cpp
1>c:\users\mhp\documents\visual studio 2010\projects\1\1\1.cpp(19): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> d:\programs\microsoft visual studio 10.0\vc\include\string.h(105) : see declaration of 'strcpy'
1>c:\users\mhp\documents\visual studio 2010\projects\1\1\1.cpp(20): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> d:\programs\microsoft visual studio 10.0\vc\include\string.h(105) : see declaration of 'strcpy'
1>c:\users\mhp\documents\visual studio 2010\projects\1\1\1.cpp(24): error C2541: 'delete' : cannot delete objects that are not pointers
1>c:\users\mhp\documents\visual studio 2010\projects\1\1\1.cpp(93): error C2660: 'init' : function does not take 3 arguments
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Добавлено через 1 час 38 минут
есть у кого-то ещё какие-то идеи?

Добавлено через 31 минуту
НУ, Ребята Помогите! Лабораторная на носу.... пожалуйста
0
xAtom
917 / 742 / 299
Регистрация: 09.12.2010
Сообщений: 1,346
Записей в блоге: 1
20.09.2011, 01:08 #4
manter, вот накидал на встроенном ASM вставь себе эту функции и используй.
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 <stdio.h>
 
char* strcpy(char* dst, const char* src) {
   char* tmp = dst;
   __asm {
          mov edi, dword ptr dst
          mov esi, dword ptr src
prev:
          mov al, byte ptr [esi]
          mov byte ptr[edi], al
          or  al, '\0'
          jz  end;
          inc esi
          inc edi
          jmp prev;
end:
   };
   return tmp;
}
 
int  main(void) {
   char buf[24];
   strcpy(buf, "Apple Talk tokenize");
   puts(buf);
 
   getchar();
   return 0;
}
0
-=ЮрА=-
Заблокирован
Автор FAQ
20.09.2011, 10:45 #5
Цитата Сообщение от manter Посмотреть сообщение
strcpy(w->name, Name);
* * * * strcpy(w->spets,Spets);
- копируешь блоки памяти, потом тронешь что то в одном єто потянет за собой изменения в другомПредлагаю замену strcpy на sprintf + чтобы блоки уж точно не перекрывались делать так

C++
1
sprintf(w->name,"~%s", Name);//100% развели блоки памяти w->name и  Name
Правда в теле функции w->name нужно будет юзать w->name + 1(как раз исключаем первый от балды вбитый символ ~ - главное чтобы он был тогда адреса нулевых элементов w->name и Name совпадать не будут, а значит их можно свободно юзать друг от друга)
0
rangerx
1941 / 1550 / 478
Регистрация: 31.05.2009
Сообщений: 2,913
20.09.2011, 16:58 #6
Цитата Сообщение от manter Посмотреть сообщение
delete[] w->razread; w->razread=NULL;
razread у тебя переменная типа int...
Цитата Сообщение от manter Посмотреть сообщение
init(&W[i], W[i-1].name, W[i].razread);
void init(worker *w, char* Name, char* Spets, int razread)
Цитата Сообщение от manter Посмотреть сообщение
case5:
C++
1
case 5:
0
M128K145
Эксперт JavaЭксперт С++
8320 / 3540 / 419
Регистрация: 03.07.2009
Сообщений: 10,708
21.09.2011, 13:14 #7
Цитата Сообщение от manter Посмотреть сообщение
1>c:\users\mhp\documents\visual studio 2010\projects\1\1\1.cpp(19): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
Необходимое выделено. Используйте вместо strcpy - strcpy_s
0
Kastaneda
Jesus loves me
Эксперт С++
4760 / 2963 / 340
Регистрация: 12.12.2009
Сообщений: 7,523
Записей в блоге: 2
Завершенные тесты: 1
21.09.2011, 13:49 #8
На самом деле это не ошибка, а т.н. предупреждение. Суть его в том, что майкрософт активно агитирует прогеров использовать их ф-ции вместо стандартных, чтоб код, кроме как в MSVC больше ни где не собирался. Так что можно смело пропусткать это "мимо ушей" и кодить дальше
1
OstapBender
584 / 523 / 75
Регистрация: 22.03.2011
Сообщений: 1,585
21.09.2011, 14:06 #9
отличайте варнинги от ерроров)
0
M128K145
Эксперт JavaЭксперт С++
8320 / 3540 / 419
Регистрация: 03.07.2009
Сообщений: 10,708
21.09.2011, 14:17 #10
Kastaneda, никто не говорил, что это ошибка(ну по крайней мере я не говорил), но наличие ворнингов тоже не есть хорошо
0
kazak
3057 / 2378 / 255
Регистрация: 11.03.2009
Сообщений: 5,438
Завершенные тесты: 1
21.09.2011, 14:29 #11
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
копируешь блоки памяти, потом тронешь что то в одном єто потянет за собой изменения в другом
можно узнать, откуда это взято?
0
Nameless One
Эксперт С++
5785 / 3434 / 351
Регистрация: 08.02.2010
Сообщений: 7,448
21.09.2011, 14:45 #12
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
копируешь блоки памяти, потом тронешь что то в одном єто потянет за собой изменения в другом
бредятина

Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Предлагаю замену strcpy на sprintf
оверхед
0
Kastaneda
Jesus loves me
Эксперт С++
4760 / 2963 / 340
Регистрация: 12.12.2009
Сообщений: 7,523
Записей в блоге: 2
Завершенные тесты: 1
21.09.2011, 14:45 #13
Цитата Сообщение от M128K145 Посмотреть сообщение
Kastaneda, никто не говорил, что это ошибка(ну по крайней мере я не говорил), но наличие ворнингов тоже не есть хорошо
Безусловно, но в данном случае думаю нужно разделять нужные варнинги, и варнинги такого типа. Т.е. к одним нужно прислушаться, а к другим совсем не обязательно. Нельзя ни согласиться, что strcpy() была протестирована миллион раз, перед тем, как ее внесли в стандарт языка С. И тут вдруг, компилятор от MS говорит нам, что она плохая, и нужно использовать другую (которой больше ни в одном компиляторе нет).
0
Nameless One
Эксперт С++
5785 / 3434 / 351
Регистрация: 08.02.2010
Сообщений: 7,448
21.09.2011, 14:48 #14
Цитата Сообщение от Kastaneda Посмотреть сообщение
Нельзя ни согласиться, что strcpy() была протестирована миллион раз, перед тем, как ее внесли в стандарт языка С. И тут вдруг, компилятор от MS говорит нам, что она плохая
ну, она на самом деле небезопасна:
Выдержка из man
Код
ОШИБКИ РЕАЛИЗАЦИИ
       Если  целевая  строка  strcpy  недостаточно  велика  (такое  случается, если программист идиот/болван и не проверяет размер перед копированием), то может случится ужасное.
       Переполнение строк фиксированной длины является любимым методом крэкеров.

Тут тот же самый случай, что и с функциями gets/fgets
. Но в стандарте есть еще и функция strncpy специально на этот случай.
1
M128K145
Эксперт JavaЭксперт С++
8320 / 3540 / 419
Регистрация: 03.07.2009
Сообщений: 10,708
21.09.2011, 14:49 #15
Kastaneda, мб это фича у cl такая и реализация strcpy в нем действительно небезопасна
0
Kastaneda
Jesus loves me
Эксперт С++
4760 / 2963 / 340
Регистрация: 12.12.2009
Сообщений: 7,523
Записей в блоге: 2
Завершенные тесты: 1
21.09.2011, 14:59 #16
Если целевая строка strcpy недостаточно велика (такое случается, если программист идиот/болван и не проверяет размер перед копированием), то может случится ужасное.
Ну на то он и Си, что нужно думать над тем, что пишешь Безопасность подобных ф-ций означает лишние проверки внутри нее, а значит затраченное время. А сишники, как известно, в этом отношении очень привередливы. Думаю именно поэтому в стандарт был внесен вариант strcpy() без дополнительных проверок, чтобы не увеличивать время работы и объем кода.
1
Nameless One
Эксперт С++
5785 / 3434 / 351
Регистрация: 08.02.2010
Сообщений: 7,448
21.09.2011, 15:01 #17
Kastaneda, тем более проверка на переполнение буфера в общем случае невозможна.
0
prik
8 / 8 / 1
Регистрация: 01.03.2011
Сообщений: 62
21.09.2011, 15:04 #18
Цитата Сообщение от Nameless One Посмотреть сообщение
Kastaneda, тем более проверка на переполнение буфера в общем случае невозможна.
Может покажите пример? язык си.
0
Kastaneda
Jesus loves me
Эксперт С++
4760 / 2963 / 340
Регистрация: 12.12.2009
Сообщений: 7,523
Записей в блоге: 2
Завершенные тесты: 1
21.09.2011, 15:12 #19
Цитата Сообщение от Nameless One Посмотреть сообщение
Kastaneda, тем более проверка на переполнение буфера в общем случае невозможна.
Ну да, без дополнительного параметра (как в strncpy()). В С++ можно реализовать, если передать указатель по ссылке и если это указатель на массив в стеке, а не на динамически выделенную память. Что говорит от том, что да - в общем случае невозможно

Добавлено через 1 минуту
Цитата Сообщение от Kastaneda Посмотреть сообщение
В С++ можно реализовать, если передать указатель по ссылке
забыл, в С тоже можно, если ф-ция будет принимать указатель на указатель, а передавать в нее адрес указателя
0
yulicesar
4 / 4 / 0
Регистрация: 21.09.2011
Сообщений: 20
21.09.2011, 15:15 #20
в начало файла
#define _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_WARNINGS

или в свойствах проекта прописать
0
21.09.2011, 15:15
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.09.2011, 15:15
Привет! Вот еще темы с решениями:

strcpy()
Ребята! Помогите с задачкой! С помощью функции strcpy() заменить в строке три...

strcpy
прога пашет,но после сортировки по результату,он выдает какойто корявый...

strcpy/strcpy_s
Добрый вечер! Есть класс (упрощенно): class const_string { public:...

strcpy и VS2012
// newintro.cpp // познакомимся с оператором new #include &lt;iostream&gt;...


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

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

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