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

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

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

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

19.09.2011, 22:11. Просмотров 2741. Ответов 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"... Как быть?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.09.2011, 22:11     strcpy - как быть?
Посмотрите здесь:

strcpy C++
strcpy/strcpy_s C++
C++ свой strcpy()
strcpy C++
C++ strdup(), strcpy()
Функция strcpy C++
C++ strcpy()
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ForEveR
Модератор
Эксперт С++
7958 / 4720 / 319
Регистрация: 24.06.2010
Сообщений: 10,525
Завершенные тесты: 3
19.09.2011, 22:13     strcpy - как быть? #2
manter, #include <cstring>
manter
0 / 0 / 0
Регистрация: 12.05.2011
Сообщений: 17
20.09.2011, 00:33  [ТС]     strcpy - как быть? #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 минуту
НУ, Ребята Помогите! Лабораторная на носу.... пожалуйста
xAtom
914 / 739 / 60
Регистрация: 09.12.2010
Сообщений: 1,346
Записей в блоге: 1
20.09.2011, 01:08     strcpy - как быть? #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;
}
-=ЮрА=-
Заблокирован
Автор FAQ
20.09.2011, 10:45     strcpy - как быть? #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 совпадать не будут, а значит их можно свободно юзать друг от друга)
rangerx
1931 / 1540 / 141
Регистрация: 31.05.2009
Сообщений: 2,905
20.09.2011, 16:58     strcpy - как быть? #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:
M128K145
Эксперт С++
8282 / 3501 / 143
Регистрация: 03.07.2009
Сообщений: 10,707
21.09.2011, 13:14     strcpy - как быть? #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
Kastaneda
Форумчанин
Эксперт С++
4470 / 2832 / 224
Регистрация: 12.12.2009
Сообщений: 7,202
Записей в блоге: 1
Завершенные тесты: 1
21.09.2011, 13:49     strcpy - как быть? #8
На самом деле это не ошибка, а т.н. предупреждение. Суть его в том, что майкрософт активно агитирует прогеров использовать их ф-ции вместо стандартных, чтоб код, кроме как в MSVC больше ни где не собирался. Так что можно смело пропусткать это "мимо ушей" и кодить дальше
OstapBender
583 / 521 / 35
Регистрация: 22.03.2011
Сообщений: 1,585
21.09.2011, 14:06     strcpy - как быть? #9
отличайте варнинги от ерроров)
M128K145
Эксперт С++
8282 / 3501 / 143
Регистрация: 03.07.2009
Сообщений: 10,707
21.09.2011, 14:17     strcpy - как быть? #10
Kastaneda, никто не говорил, что это ошибка(ну по крайней мере я не говорил), но наличие ворнингов тоже не есть хорошо
kazak
3032 / 2353 / 155
Регистрация: 11.03.2009
Сообщений: 5,401
21.09.2011, 14:29     strcpy - как быть? #11
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
копируешь блоки памяти, потом тронешь что то в одном єто потянет за собой изменения в другом
можно узнать, откуда это взято?
Nameless One
Эксперт С++
5767 / 3416 / 255
Регистрация: 08.02.2010
Сообщений: 7,441
21.09.2011, 14:45     strcpy - как быть? #12
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
копируешь блоки памяти, потом тронешь что то в одном єто потянет за собой изменения в другом
бредятина

Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Предлагаю замену strcpy на sprintf
оверхед
Kastaneda
Форумчанин
Эксперт С++
4470 / 2832 / 224
Регистрация: 12.12.2009
Сообщений: 7,202
Записей в блоге: 1
Завершенные тесты: 1
21.09.2011, 14:45     strcpy - как быть? #13
Цитата Сообщение от M128K145 Посмотреть сообщение
Kastaneda, никто не говорил, что это ошибка(ну по крайней мере я не говорил), но наличие ворнингов тоже не есть хорошо
Безусловно, но в данном случае думаю нужно разделять нужные варнинги, и варнинги такого типа. Т.е. к одним нужно прислушаться, а к другим совсем не обязательно. Нельзя ни согласиться, что strcpy() была протестирована миллион раз, перед тем, как ее внесли в стандарт языка С. И тут вдруг, компилятор от MS говорит нам, что она плохая, и нужно использовать другую (которой больше ни в одном компиляторе нет).
Nameless One
Эксперт С++
5767 / 3416 / 255
Регистрация: 08.02.2010
Сообщений: 7,441
21.09.2011, 14:48     strcpy - как быть? #14
Цитата Сообщение от Kastaneda Посмотреть сообщение
Нельзя ни согласиться, что strcpy() была протестирована миллион раз, перед тем, как ее внесли в стандарт языка С. И тут вдруг, компилятор от MS говорит нам, что она плохая
ну, она на самом деле небезопасна:
Выдержка из man
Код
ОШИБКИ РЕАЛИЗАЦИИ
       Если  целевая  строка  strcpy  недостаточно  велика  (такое  случается, если программист идиот/болван и не проверяет размер перед копированием), то может случится ужасное.
       Переполнение строк фиксированной длины является любимым методом крэкеров.

Тут тот же самый случай, что и с функциями gets/fgets
. Но в стандарте есть еще и функция strncpy специально на этот случай.
M128K145
Эксперт С++
8282 / 3501 / 143
Регистрация: 03.07.2009
Сообщений: 10,707
21.09.2011, 14:49     strcpy - как быть? #15
Kastaneda, мб это фича у cl такая и реализация strcpy в нем действительно небезопасна
Kastaneda
Форумчанин
Эксперт С++
4470 / 2832 / 224
Регистрация: 12.12.2009
Сообщений: 7,202
Записей в блоге: 1
Завершенные тесты: 1
21.09.2011, 14:59     strcpy - как быть? #16
Если целевая строка strcpy недостаточно велика (такое случается, если программист идиот/болван и не проверяет размер перед копированием), то может случится ужасное.
Ну на то он и Си, что нужно думать над тем, что пишешь Безопасность подобных ф-ций означает лишние проверки внутри нее, а значит затраченное время. А сишники, как известно, в этом отношении очень привередливы. Думаю именно поэтому в стандарт был внесен вариант strcpy() без дополнительных проверок, чтобы не увеличивать время работы и объем кода.
Nameless One
Эксперт С++
5767 / 3416 / 255
Регистрация: 08.02.2010
Сообщений: 7,441
21.09.2011, 15:01     strcpy - как быть? #17
Kastaneda, тем более проверка на переполнение буфера в общем случае невозможна.
prik
8 / 8 / 1
Регистрация: 01.03.2011
Сообщений: 62
21.09.2011, 15:04     strcpy - как быть? #18
Цитата Сообщение от Nameless One Посмотреть сообщение
Kastaneda, тем более проверка на переполнение буфера в общем случае невозможна.
Может покажите пример? язык си.
Kastaneda
Форумчанин
Эксперт С++
4470 / 2832 / 224
Регистрация: 12.12.2009
Сообщений: 7,202
Записей в блоге: 1
Завершенные тесты: 1
21.09.2011, 15:12     strcpy - как быть? #19
Цитата Сообщение от Nameless One Посмотреть сообщение
Kastaneda, тем более проверка на переполнение буфера в общем случае невозможна.
Ну да, без дополнительного параметра (как в strncpy()). В С++ можно реализовать, если передать указатель по ссылке и если это указатель на массив в стеке, а не на динамически выделенную память. Что говорит от том, что да - в общем случае невозможно

Добавлено через 1 минуту
Цитата Сообщение от Kastaneda Посмотреть сообщение
В С++ можно реализовать, если передать указатель по ссылке
забыл, в С тоже можно, если ф-ция будет принимать указатель на указатель, а передавать в нее адрес указателя
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.09.2011, 15:15     strcpy - как быть?
Еще ссылки по теме:

C++ Функция strcpy () - строка должна быть пустой?
Как работает strcpy с точки зрения распределения памяти? C++
Как заменить функцию fgets на strlen и strcpy? C++
Как установить конец строки при своей реализации функции strcpy()? C++

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

Или воспользуйтесь поиском по форуму:
yulicesar
4 / 4 / 0
Регистрация: 21.09.2011
Сообщений: 20
21.09.2011, 15:15     strcpy - как быть? #20
в начало файла
#define _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_WARNINGS

или в свойствах проекта прописать
Yandex
Объявления
21.09.2011, 15:15     strcpy - как быть?
Ответ Создать тему
Опции темы

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