Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 01.12.2009, 20:08   #1
GonZaleZ
Пользователь
 
Регистрация: 19.06.2009
Сообщений: 57
По умолчанию Корявое копирование строки. Помогите найти ошибку.

Вот недавно прочитал тему про классы в С++ и решил написать свою программу, использующую классы.
Для тестирования конструктора попробовал сначала просто ввести данные прямо из программы. Вот код
Код:
#include <cstdlib>
#include <iostream>
#include <string.h>
#include <windows.h>

using namespace std;

class tovar {
      public:
             tovar(char*, char*, int, double);
             void change_name(char*);
             void change_tipe(char*);
             void change_coast(double);
             void show_tovar();
             ~tovar();
      private:
              char name[];
              char tipe[];
              int art;
              double coast;
      };
      
      tovar::tovar(char* tname = "0", char* ttipe = "0", int tart = 0, double tcoast = 0) {
                        strcpy(name, tname);
                        strcpy(tipe, ttipe);
                        art = tart;
                        coast = tcoast;
                        };
      void tovar::change_name(char tname[]) {
           strcpy(name, tname);
           };
           
      void tovar::change_tipe(char ttipe[]) {
           strcpy(tipe, ttipe);
           };
           
      void tovar::change_coast(double tcoast) {
           coast = tcoast;
           };
      
      void tovar::show_tovar() {
           cout << "Артикул: " << art << endl
                << "Название: " << name << endl
                << "Тип: " << tipe << endl
                << "Стоимость: " << coast << endl;
           };
           
      tovar::~tovar() {
                      cout << "Объект с данными:\n";
                      show_tovar();
                      cout << "Был удалён из базы\n";
                      };

int main(int argc, char *argv[])
{
    ::SetConsoleCP(GetACP());
    ::SetConsoleOutputCP(GetACP());
    tovar hleb("Хлеб Бородинский", "Хлеб", 175835, 15.40);
    hleb.show_tovar();
    system("PAUSE");
    return EXIT_SUCCESS;
}
Программа спокойно компилируется, но при создании объекта hleb информация о названии и типе криво копируется при помощи strcpy().
Может я что-то намудрил с указателями?
Пишу в Dev-C++
GonZaleZ вне форума Ответить с цитированием
Старый 01.12.2009, 20:28   #2
netrino
Участник клуба
 
Аватар для netrino
 
Регистрация: 15.07.2008
Сообщений: 1,933
По умолчанию

name и tipe объявите как char* и выделяйте под них память в конструкторе
netrino вне форума Ответить с цитированием
Старый 01.12.2009, 23:23   #3
GonZaleZ
Пользователь
 
Регистрация: 19.06.2009
Сообщений: 57
По умолчанию

name и tipe как char* объявил, а как выделить под них память в конструкторе? а то я ещё не очень хорошо с этой темой знаком...
GonZaleZ вне форума Ответить с цитированием
Старый 01.12.2009, 23:26   #4
GonZaleZ
Пользователь
 
Регистрация: 19.06.2009
Сообщений: 57
По умолчанию

всё, вопрос решил сам. помогло предварительное определение размера массивов в самом классе
GonZaleZ вне форума Ответить с цитированием
Старый 01.12.2009, 23:51   #5
forsaken66
Куды бечь?
Форумчанин
 
Аватар для forsaken66
 
Регистрация: 05.10.2009
Сообщений: 104
По умолчанию

Код:
::SetConsoleCP(GetACP());
::SetConsoleOutputCP(GetACP());
а это что? объясни пожалуйста.
Не хватало всего одного байта. Да-да, того самого, что из восьми бит состоит.
forsaken66 вне форума Ответить с цитированием
Старый 01.12.2009, 23:56   #6
netrino
Участник клуба
 
Аватар для netrino
 
Регистрация: 15.07.2008
Сообщений: 1,933
По умолчанию

Цитата:
Сообщение от GonZaleZ Посмотреть сообщение
всё, вопрос решил сам. помогло предварительное определение размера массивов в самом классе
правильно, это один из способов. Из минусов - объект класса будет занимать много места и сложно предугадать размер строк, потому приходится брать с запасом, а не занятое место будет гулять )
Код:
      tovar::tovar(char* tname = "0", char* ttipe = "0", int tart = 0, double tcoast = 0) {
                        name = new char[strlen(tname) + 1];
                        tipe   = new char[strlen(ttipe) + 1];
                        strcpy(name, tname);
                        strcpy(tipe, ttipe);
                        art = tart;
                        coast = tcoast;
                        };
Также не следует забывать про освобождение памяти когда она уже больше не нужна с помощью delete[](в деструкторе и в методах change_name и change_tipe)
netrino вне форума Ответить с цитированием
Старый 02.12.2009, 00:21   #7
GonZaleZ
Пользователь
 
Регистрация: 19.06.2009
Сообщений: 57
По умолчанию

Цитата:
Сообщение от forsaken66 Посмотреть сообщение
Код:
::SetConsoleCP(GetACP());
::SetConsoleOutputCP(GetACP());
а это что? объясни пожалуйста.
если честно, я сам не знаю, как это работает, но оно работает =)
эти 2 функции используются для нормального отображения русского текста: одна для ввода, другая - для вывода. давно ещё где-то вычитал, а теперь уже в привычку вошло в начале всегда эти 2 функции писать.
только это работает при установке в консоли шрифта Lucida Console
GonZaleZ вне форума Ответить с цитированием
Старый 02.12.2009, 00:44   #8
GonZaleZ
Пользователь
 
Регистрация: 19.06.2009
Сообщений: 57
По умолчанию

Вот блин же... от одной проблемы избавился, так появилась другая...
После того, как задал изначальный размер массивов в классе, всё шло хорошо. Потом я захотел немного изменить конструктор так, чтобы он предлагал пользователю вручную ввести данные о товаре.
Весь класс и методы (с конструктором) компилируется нормально, но вот ругается уже под конец на строку 68
Код:
    hleb.show_tovar();
текст ругательства таков: request for member `show_tovar' in `hleb', which is of non-class type `tovar ()()'
причём тут какой-то tovar ()()? уже всё перепробовал, не получается(( думал, может нечаянно что-то удалил или дописал лишнего, но вроде всё осталось, как было...
вот ещё раз привожу весь код с внесёнными изменениями:
Код:
#include <cstdlib>
#include <iostream>
#include <string.h>
#include <windows.h>

using namespace std;

class tovar {
      public:
             tovar();
             void change_name(char*);
             void change_tipe(char*);
             void change_coast(double);
             void show_tovar();
             ~tovar();
      private:
              char name[128];
              char tipe[64];
              int art;
              double coast;
      };
      
      tovar::tovar() {
                        char tname[128] = "0";
                        char ttipe[64] = "0";
                        int tart = 0;
                        double tcoast = 0;
                        cout << "\nВведите артикул товара: "; cin >> tart;
                        cout << "\nВведите название товара: "; cin.getline(tname, 128);
                        cout << "\nОпределите тип товара: "; cin.getline(ttipe, 64);
                        cout << "\nНазначте цену товара : "; cin >> tcoast;
                        strcpy(name, tname);
                        strcpy(tipe, ttipe);
                        art = tart;
                        coast = tcoast;
                        };
      void tovar::change_name(char tname[]) {
           strcpy(name, tname);
           };
           
      void tovar::change_tipe(char ttipe[]) {
           strcpy(tipe, ttipe);
           };
           
      void tovar::change_coast(double tcoast) {
           coast = tcoast;
           };
      
      void tovar::show_tovar() {
           cout << "Артикул: " << art << endl
                << "Название: " << name << endl
                << "Тип: " << tipe << endl
                << "Стоимость: " << coast << endl;
           };
           
      tovar::~tovar() {
                      cout << "Объект с данными:\n";
                      show_tovar();
                      cout << "Был удалён из базы\n";
                      };

int main(int argc, char *argv[])
{
    ::SetConsoleCP(GetACP());
    ::SetConsoleOutputCP(GetACP());
    tovar hleb();
    hleb.show_tovar();
    system("PAUSE");
    return EXIT_SUCCESS;
}

Последний раз редактировалось GonZaleZ; 02.12.2009 в 00:47.
GonZaleZ вне форума Ответить с цитированием
Старый 02.12.2009, 00:54   #9
Ozerich
Студент 1 курса
Форумчанин Подтвердите свой е-майл
 
Аватар для Ozerich
 
Регистрация: 27.06.2008
Сообщений: 959
По умолчанию

Код:
#include <cstdlib>
#include <iostream>
#include <string.h>
#include <windows.h>

using namespace std;

class tovar {
      public:
             tovar();
             void change_name(char*);
             void change_tipe(char*);
             void change_coast(double);
             void show_tovar();
             ~tovar();
      private:
              char name[128];
              char tipe[64];
              int art;
              double coast;
      };
      
      tovar::tovar() {
                        char tname[128] = "0";
                        char ttipe[64] = "0";
                        int tart = 0;
                        double tcoast = 0;
                        cout << "\nВведите артикул товара: "; cin >> tart;
                        cout << "\nВведите название товара: "; cin.getline(tname, 128);
                        cout << "\nОпределите тип товара: "; cin.getline(ttipe, 64);
                        cout << "\nНазначте цену товара : "; cin >> tcoast;
                        strcpy(name, tname);
                        strcpy(tipe, ttipe);
                        art = tart;
                        coast = tcoast;
                        };
      void tovar::change_name(char tname[]) {
           strcpy(name, tname);
           };
           
      void tovar::change_tipe(char ttipe[]) {
           strcpy(tipe, ttipe);
           };
           
      void tovar::change_coast(double tcoast) {
           coast = tcoast;
           };
      
      void tovar::show_tovar() {
           cout << "Артикул: " << art << endl
                << "Название: " << name << endl
                << "Тип: " << tipe << endl
                << "Стоимость: " << coast << endl;
           };
           
      tovar::~tovar() {
                      cout << "Объект с данными:\n";
                      show_tovar();
                      cout << "Был удалён из базы\n";
                      };

int main(int argc, char *argv[])
{
    ::SetConsoleCP(GetACP());
    ::SetConsoleOutputCP(GetACP());
    tovar hleb=tovar();
    hleb.show_tovar();
    system("PAUSE");
    return EXIT_SUCCESS;
}
C++(STL, QT, WinInet) / DHTML(CSS) / JavaScript / PHP Developer
Ozerich вне форума Ответить с цитированием
Старый 02.12.2009, 01:10   #10
GonZaleZ
Пользователь
 
Регистрация: 19.06.2009
Сообщений: 57
По умолчанию

Спасибо. Попробовал написать просто tovar hleb; - тоже работает.
Но, блин, теперь ещё одна проблема... Надеюсь, последняя.
При выполнении программы почему-то пропускается cin.getline(tname, 128);, т.е. на экран выводится
Цитата:
Введите название товара:
а затем сразу
Цитата:
Определите тип товара:
и предложение ввести тип.
почему может пропускаться предложение ввести имя?
GonZaleZ вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Строки. Помогите найти ошибку. 5nizza77 Помощь студентам 1 16.10.2009 16:10
Помогите найти ошибку smitters Общие вопросы C/C++ 9 06.07.2009 18:42
Помогите найти ошибку REztor Помощь студентам 5 16.03.2009 20:04