Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > строка в структуре


Автор: IKM2007 9.5.2008, 19:15
Поздравляю Всем со днем победы.
У меня в програмее что-то не так, когда выводится строка на экран, то правильно выводится только первая буква строки, а остальное что-то типа ||||||||||||||||||. В чем ошыбка? Вот код

main.cpp

Код

#include <iostream.h>
#include "h.h"
void main()
{
Train a;
char s[17];
cout<<"city->";
cin.getline(s,17);
int n;
cout<<"number->";
cin>>n;
double d;
cout<<"time->";
cin>>d;
a.set(s,n,d);
a.out(a);
}


h.cpp

Код

#include <iostream.h>
#include <stdlib.h>
#include <iomanip.h>
#include "h.h"
void Train::set(char *a,int b,double c)
{
*city=*a;
number=b;
time=c;
}
void Train::out(Train a)
{
    cout<<"The train number "<<a.number<<" go to "<<a.city<<" in "
        <<setprecision(2)<<setiosflags(ios::fixed|ios::showpoint)<<a.time<<" o'clock.\n";
}


h.h

Код

#ifndef H_H
#define H_H
struct Train
{
public:
void set(char *,int,double);
void out(Train);
private:
char city[17];
int number;
double time;
};
#endif

Автор: IKM2007 9.5.2008, 20:11
Ладно, понял, в чем ошибка.
Если кому интересно, то в коде h.cpp 7-ом строке написал
Код

*city=*a;

а должен был написать
Код

strcpy(city,a);

так как массив не динамический. smile

Автор: bronislav 9.5.2008, 20:12
Я немного поправил, твой код
У тебя не правильно передавался указатель в структуру

Так все работает
Код

// Заголовочный файл iostream.h исполльзуется без окончания .h
// Правильное его использование такое:
#include <iostream>

#include "cl.h"
int main()
{
    Train a;
    /*
    char s[17];
    Лучше использовать динамически массивы вот так:
    */
    char* s = new char [17];
    std::cout << "city->";
    std::cin.getline(s,17);
    
    int n;
    std::cout << "number->";
    std::cin >> n;
    
    double d;
    std::cout << "time->";
    std::cin >> d;
    
    a.set( s, n, d );
    a.out( a );
    
    return 0;
}


Код

#include <iostream>
// Заголовчный файл stdlib.h был переименован в 
// cstdlib. И в нем также используется пространство имен std
#include <cstdlib>
#include <iomanip>
#include "cl.h"

void Train::set(char *a,int b,double c)
{
    /*
    Лучше не передавать указатель, а скопировать
    *city=*a;
    */
    city = new char[17];
    memcpy(city,a,sizeof(char)*17);
    number = b;
    time = c;
}

void Train::out(Train a)
{
    std::cout << "The train number " << a.number 
         << " go to " << a.city << " in "
         << std::setprecision(2) << std::setiosflags( std::ios::fixed|std::ios::showpoint )
         << a.time <<" o'clock.\n";
}


Код

#ifndef CL_H_
#define CL_H_

struct Train
{    
public:
    void set(char *,int,double);
    void out(Train);
private:
    char* city;
    int number;
    double time;
};

#endif /*CL_H_*/

Автор: archimed7592 9.5.2008, 20:26
Если ещё немного подправить, то получится более адекватный с т.з. ООП код:
Код

// h.h

struct Train
{    
public:
    Train();
    ~Train();
    void set(char *,int,double);
    void out() const;
private:
    void releaseResources();

    char* city;
    int number;
    double time;
};

// h.cpp
Train::Train()
    : city()
{ }

Train::~Train()
{
    this->releaseResources();
}


Train::releaseResources()
{
    if (this->city)
    {
        delete [] city;
        city = 0;
    }
}

Train::set( ... )
{
    this->releaseResources();
    this->city = new ...
    ...
}

void Train::out() const
{
    std::cout << "The train number " << this->number 
         << " go to " << this->city << " in "
         << std::setprecision(2) << std::setiosflags( std::ios::fixed|std::ios::showpoint )
         << this->time <<" o'clock.\n";
}

// main.cpp
...
a.out();


Ключевый здесь моменты:
1. Освобождение ресурсов(удаление выделенной памяти), дабы не было их утечки.
2. out(Train a) - это нечто не похожее на ООП... Тебе же не приходится писать cin.getline(cin, s, 17) smile Зачем же писать такие классы, в которых приходится писать a.out(a)?

Добавлено через 5 минут и 12 секунд
Цитата(bronislav @  9.5.2008,  20:12 Найти цитируемый пост)
Лучше использовать динамически массивы вот так:

Не знаю, чем в данном случаее это лучше, но, если уж на то пошло, то неплохо было бы ещё удалять их.

К слову, о дин. массивах: http://forum.vingrad.ru/index.php?showtopic=189118

Автор: IKM2007 9.5.2008, 20:36
БОЛЬШОЕ Спасибо.
И еще...
может обясните, в чем разница использования <iostream.h> как <iostream> и другие заголовочние файлы без .h.
С ".h" более удобно

Автор: archimed7592 9.5.2008, 20:40
Цитата(IKM2007 @  9.5.2008,  20:36 Найти цитируемый пост)
может обясните, в чем разница использования <iostream.h> как <iostream> и другие заголовочние файлы без .h.
С ".h" более удобно 

В принципе ни в чём, кроме того, что с .h использовать неправильно(уже лет 10 как), только почему-то все книги, учителя в школах и преподаватели в универах начинают обучение с .h.

Более подробно: http://forum.vingrad.ru/index.php?show_type=forum&showtopic=205361

Автор: bronislav 9.5.2008, 20:51
Цитата(archimed7592 @  9.5.2008,  20:26 Найти цитируемый пост)
1. Освобождение ресурсов(удаление выделенной памяти), дабы не было их утечки.


Что-то всегда забываю про освобождение памяти. Наверно опыта программирования еще мало :(

Цитата(archimed7592 @  9.5.2008,  20:26 Найти цитируемый пост)
2. out(Train a) - это нечто не похожее на ООП...


Начинал правку с мысли, что надо это исправить и не исправил :(

Автор: IKM2007 9.5.2008, 20:54
А как узнать,в каких из заголовочных файлов следует спереди написать "c", типа <stdlib.h> на <cstdlib>?

Автор: archimed7592 9.5.2008, 21:03
Цитата(IKM2007 @  9.5.2008,  20:54 Найти цитируемый пост)
А как узнать,в каких из заголовочных файлов следует спереди написать "c", типа <stdlib.h> на <cstdlib>? 

Ну, для сишных нужно писать, для не-сишных не нужно... никогда не задумывался над тем как их различать - всегда было понятно, какой из них сишный, какой - нет smile (обычно плюсовые хэдеры предоставляют какие-нибудь классы)
Ну, 'c' нужно писать в этих случаях: http://www.cplusplus.com/reference/clibrary/

Цитата(bronislav @  9.5.2008,  20:51 Найти цитируемый пост)
Наверно опыта программирования еще мало :(

Ничего страшного - желание и труд усё перетрут smile.

Автор: IKM2007 9.5.2008, 21:14
archimed7592, БОЛЬШОЕ СПАСИбо за интересный сайт!!! smile (дал бы +1 Репутация, но
Код

Обнаружена ошибка:


У Вас недостаточно постов, чтобы изменять репутацию пользователей. Необходимо 100 постов.

)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)