С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/7: Рейтинг темы: голосов - 7, средняя оценка - 5.00
63 / 64 / 11
Регистрация: 27.02.2013
Сообщений: 1,116

Неопределенное поведение пользовательской функции

01.10.2014, 15:57. Показов 1419. Ответов 19
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
значит писал для лабы вот такой код:

town.h
Кликните здесь для просмотра всего текста
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
#include <Windows.h>
#include <conio.h>
#include <iostream>
#include <fstream>
 
using namespace std;
 
class town //класс населенный пункт
{
private:
    char* name; //название
    double latitude; //широта
    double longitude; //долгота
    char* transport; //виды общественного транспорта
 
    inline char* getname() { return name; }
public:
    //конструктор без параметров
    town();
    //конструктор с параметром задающим название
    town(char* _name);
    //конструктор с параметрами задающими все поля
    town(char* _name, size_t _population, double _latitude, double _longitude, char* _transport);
    //деструктор
    ~town();
    //метод Input выполняет ввод данных из файла
    bool Input();
    //метод Output печатает на экране данные класса
    bool Output();
protected:
    size_t population; //количество жителей
 
    inline size_t getpopulation() { return population; }
};
 
//Функция чистит консоль
bool ClearConsole();
//Функция печатает надпись (флаг inscription), возвращает код нажатой клавиши и, если надо, чистит консоль (флаг cls)
char pause(bool cls = false, bool inscription = true);
//Функция читает введенную строку из переданного потока в динамически выделяемый буфер
char* GetString(istream& stream);

town.cpp
Кликните здесь для просмотра всего текста
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
135
136
137
138
139
140
141
142
143
#include "town.h"
 
town::town()
{
    name = nullptr;
    population = 0;
    latitude = 0.0;
    longitude = 0.0;
    transport = nullptr;
}
 
town::town(char* _name)
{
    name = new char[strlen(_name) + 1];
    strcpy(name, _name);
    population = 0;
    latitude = 0.0;
    longitude = 0.0;
    transport = nullptr;
}
 
town::town(char* _name, size_t _population, double _latitude, double _longitude, char* _transport)
{
    name = new char[strlen(_name) + 1];
    strcpy(name, _name);
    population = _population;
    latitude = _latitude;
    longitude = _longitude;
    transport = new char[strlen(_transport) + 1];
    strcpy(transport, _transport);
}
 
town::~town()
{
    if (name) delete[] name;
    population = 0;
    latitude = 0.0;
    longitude = 0.0;
    if (transport) delete[] transport;
}
 
bool town::Input()
{
    cout << "filename: "; //запрос имени файла
    char* filename = GetString(cin); //имя файла
    char* tmp = new char[strlen("input\\") + strlen(filename) + 1];
    strcpy(tmp, "input\\"); //добавление папки в которой лежит файл
    strcat(tmp, filename); //добавление имени файла
    delete[] filename;
    ifstream stream(tmp); //открытие потока
    delete[] tmp;
    if (!stream.is_open()) return false; //если поток не открылся выход
 
    //читаю название
    char* str = GetString(stream);
    if (name) delete[] name;
    name = new char[strlen(str) - strlen("name=") + 1];
    sscanf(str, "name=%s", name);
    delete[] str;
 
    //читаю население
    str = GetString(stream);
    sscanf(str, "population=%d", &population);
    delete[] str;
 
    //читаю широту
    str = GetString(stream);
    sscanf(str, "latitude=%lf", &latitude);
    delete[] str;
 
    //читаю долготу
    str = GetString(stream);
    sscanf(str, "longitude=%lf", &longitude);
    delete[] str;
 
    //читаю виды транспорта
    str = GetString(stream);
    if (transport) delete[] transport;
    transport = new char[strlen(str) - strlen("transport=") + 1];
    sscanf(str, "transport=%s", transport);
    delete[] str;
 
    return true;
}
 
bool town::Output()
{
    cout << "name="       << ((name) ? name : "")           << endl
         << "population=" << population                     << endl
         << "latitude="   << latitude                       << endl
         << "longitude="  << longitude                      << endl
         << "transport="  << ((transport) ? transport : "") << endl << endl;
    return true;
}
 
bool ClearConsole()
{
    HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    DWORD written;
    COORD zeroPos = { 0, 0 };
 
    if (GetConsoleScreenBufferInfo(consoleHandle, &csbi))
    {
        DWORD numChars = csbi.dwSize.X * csbi.dwSize.Y;
 
        FillConsoleOutputCharacter(consoleHandle, ' ', numChars, zeroPos, &written);
        FillConsoleOutputAttribute(consoleHandle, csbi.wAttributes, numChars, zeroPos, &written);
    }
    SetConsoleCursorPosition(consoleHandle, zeroPos);
    return consoleHandle;
}
 
char pause(bool cls, bool inscription)
{
    if (inscription) cout << "Для продолжения нажмите любую клавишу . . . ";
    char key = getch();
    if (cls) ClearConsole();
    return key;
}
 
char* GetString(istream& stream)
{
    const double k = 1.25;
    size_t index = 0, length = 10;
    char *str = new char[length], *tmp, c;
    while (stream.get(c) && (c != '\n'))
    {
        if (index == length)
        {
            tmp = new char[length *= k];
            memcpy(tmp, str, index + 1);
            delete[] str;
            str = tmp;
        }
        str[index++] = c;
    }
    tmp = new char[index + 1];
    memcpy(tmp, str, index);
    delete[] str;
    tmp[index] = 0;
    return tmp;
}

lab2.cpp
Кликните здесь для просмотра всего текста
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
#include "town.h"
 
int main()
{
    setlocale(LC_ALL, "RUSSIAN");
 
    //использование конструктора по умолчанию
    town* a = new town;
    cout << "использование конструктора по умолчанию" << endl << endl;
    a.Output();
    pause(true);
    delete a;
 
    //использование конструктора с параметром задающим название
    town b = new town("Пенза");
    cout << "использование конструктора с параметром задающим название" << endl << endl;
    b.Output();
    pause(true);
 
    //использование конструктора с параметрами задающими все поля
    cout << "использование конструктора с параметрами задающими все поля" << endl << endl;
    town c = new town("Пенза", 517311, 53.19, 45.00, "автобусы, тролейбусы");
    c.Output();
    pause(true);
    delete b;
    delete c;
 
    //использование массива экземпляров класса с заполнением из файла
    const size_t size = 3;
    town* d[size];
    for (int i = 0; i < size; i++)
    {
        d[i] = new town;
        cout << "использование массива экземпляров класса с заполнением из файла" << endl << endl;
        d[i].Input();
        cout << endl;
        d[i].Output();
        pause(true);
    }
    for (int i = 0; i < size; i++) delete d[i];
 
    return 0;
}


не парьтесь особо с разбором реализации, там все правильно... значит суть в том что препод сказал что нельзя использовать функцию system (типа system("pause"), system("cls")) совместно с cin, cout... я написал ему аналоги рукописные... и теперь у меня при вводе массива (в main в конце там) то нормально вводится и выводится, то вывод не показывает сразу стирает... т.е. там должно быть так: вводишь имя файла (в Input запрашивается), объект заполнился из файла, объект вывелся на экран (Output), и дальше просто ожидание нажатия клавиши, а у меня иногда это ожидание нажатия клавиши есть, а иногда нет... совершенно непонятно почему так выходит помогите пожалуйста...
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
01.10.2014, 15:57
Ответы с готовыми решениями:

Неопределенное поведение С++
Вот такой вопрос: что из этого обязательно вызовет неопределенное поведение ? 1) Разыменование нулевого указателя 2) Выход за...

Создание массива, неопределенное поведение
Пишу такой код: #include &lt;iostream&gt; #include &lt;stdlib.h&gt; using namespace std; struct GL{ GL () { } virtual...

Неопределенное поведение в Debug и Release
Писал программу для сложения больших чисел (в файле содержатся числа с количеством цифр от 1 до 30). При запуске через компилятор всё...

19
1123 / 794 / 219
Регистрация: 15.08.2010
Сообщений: 2,185
01.10.2014, 16:05
GetHelp, некоторые клавиши передают два кода в буфер (к примеру стрелки)
Поищи, как очистить буфер клавы и сделай это до getch()

Не по теме:

Цитата Сообщение от GetHelp Посмотреть сообщение
return 0;
КТО этот человек, который убедил/заставил тебя возвращать 0, а не символ???!!! :D

0
63 / 64 / 11
Регистрация: 27.02.2013
Сообщений: 1,116
01.10.2014, 16:07  [ТС]
Цитата Сообщение от КОП Посмотреть сообщение
GetHelp, некоторые клавиши передают два кода в буфер (к примеру стрелки)
Поищи, как очистить буфер клавы и сделай это до getch()
пробовал cin.clear() не помогло а другого не знаю...
Цитата Сообщение от КОП Посмотреть сообщение
КТО этот человек, который убедил/заставил тебя возвращать 0, а не символ???!!!
это из main? какой еще символ возвращать?
0
Эксперт по математике/физикеЭксперт С++
 Аватар для Ilot
2223 / 1425 / 420
Регистрация: 16.05.2013
Сообщений: 3,642
Записей в блоге: 6
01.10.2014, 16:09
Цитата Сообщение от GetHelp Посмотреть сообщение
пробовал cin.clear() не помогло а другого не знаю...
Ну почему же? Если научились пользоваться выходным буфером учитесь и входным.
0
63 / 64 / 11
Регистрация: 27.02.2013
Сообщений: 1,116
01.10.2014, 16:09  [ТС]
Цитата Сообщение от Ilot Посмотреть сообщение
Ну почему же? Если научились пользоваться выходным буфером учитесь и входным.
что почему? говорю не помогло, не понял в чем вопрос...
0
1123 / 794 / 219
Регистрация: 15.08.2010
Сообщений: 2,185
01.10.2014, 16:14

Не по теме:

Цитата Сообщение от GetHelp Посмотреть сообщение
это из main? какой еще символ возвращать?
ели мне не изменяет память, ты всегда возвращал cin.get() или что-то в этом роде. а сейчас все правильно, нуль.


попробуй нажимать любую буквенную клавишу всегда, возникнет ли ошибка?
ну или вот так:
C++
1
2
cin.clear();
while(cin.get() != '\n');
Добавлено через 2 минуты
а не, не совсем то, в общем гугл в помощь.

PS: какая-то неприязнь у меня к этому cin, никак не могу найти в себе силы почитать про него. работает и ладно.
0
63 / 64 / 11
Регистрация: 27.02.2013
Сообщений: 1,116
01.10.2014, 16:18  [ТС]
Цитата Сообщение от КОП Посмотреть сообщение
ели мне не изменяет память, ты всегда возвращал cin.get() или что-то в этом роде. а сейчас все правильно, нуль.
я был не прав
Цитата Сообщение от КОП Посмотреть сообщение
попробуй нажимать любую буквенную клавишу всегда, возникнет ли ошибка?
хмм вроде не возникает но все таки мне это не нравится в идеале должно быть все нормально с любой клавишей, а не только с буквенными...
Цитата Сообщение от КОП Посмотреть сообщение
ну или вот так:
че то не то кажется...
0
Эксперт по математике/физикеЭксперт С++
 Аватар для Ilot
2223 / 1425 / 420
Регистрация: 16.05.2013
Сообщений: 3,642
Записей в блоге: 6
01.10.2014, 16:18
У консоли есть выходной буфер, который вы доблесно чистите, а есть еще и входной. Вот и пользуйтесь им.
Примерно так:
C++
1
2
3
4
5
hStdln = GetStdHandle(STD_INPUT_HANDLE); 
//...
WaitForSingleObject(hStdIn, INFINITE); 
//...
ReadConsoleInput(/*Тута ваши параметры*/);
1
1123 / 794 / 219
Регистрация: 15.08.2010
Сообщений: 2,185
01.10.2014, 16:23
Ilot, господи иисусе, страсти то какие пишите! Неужели нет более простой команды, чтобы проигнорить доп код?
Может проверять первый код клавиши, и если он предполагает второй, то выполнять еще getch? (просто не в курсе, какие коды предполагают после себя еще что-то)
0
63 / 64 / 11
Регистрация: 27.02.2013
Сообщений: 1,116
01.10.2014, 16:28  [ТС]
Ilot, ушасть какая то -_- буду читать

Добавлено через 53 секунды
Цитата Сообщение от КОП Посмотреть сообщение
Ilot, господи иисусе, страсти то какие пишите!
эта жи винапи))))
0
1123 / 794 / 219
Регистрация: 15.08.2010
Сообщений: 2,185
01.10.2014, 16:34
GetHelp, if (key == -32) getch(); после getch добавь
(если -32 не прокатит, посмотри, что возвращает стрелка первым кодом)
1
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
01.10.2014, 16:41
Может вам это поможет: Распространенные ошибки
0
63 / 64 / 11
Регистрация: 27.02.2013
Сообщений: 1,116
01.10.2014, 16:49  [ТС]
Цитата Сообщение от castaway Посмотреть сообщение
Может вам это поможет: Распространенные ошибки
читал уже, не то это все...

Ilot, залез в самые дебри винапи -_- вот что вышло
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
char pause(bool cls, bool inscription)
{
    if (inscription) cout << "Для продолжения нажмите любую клавишу . . . ";
    cin.clear();
    cout.clear();
    HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE);
    WaitForSingleObject(hStdIn, INFINITE);
    PINPUT_RECORD pir = new INPUT_RECORD;
    ReadConsoleInput(hStdIn, pir, 1, 0);
    char key = pir->Event.KeyEvent.uChar.AsciiChar;
    delete pir;
    if (cls) ClearConsole();
    return key;
}
только апшипка вылетает "Необработанное исключение по адресу 0x755BD4C4 (kernel32.dll) в lab2.exe: 0xC0000005: нарушение прав доступа при записи по адресу 0x00000000."
0
1123 / 794 / 219
Регистрация: 15.08.2010
Сообщений: 2,185
01.10.2014, 16:50
GetHelp,
Цитата Сообщение от КОП Посмотреть сообщение
if (key == -32) getch(); после getch добавь
не работает разве?
0
63 / 64 / 11
Регистрация: 27.02.2013
Сообщений: 1,116
01.10.2014, 16:53  [ТС]
Цитата Сообщение от КОП Посмотреть сообщение
не работает разве?
не проверял... а вроде бы работает кривоватое немного решение конечно... может через апи щас прямо свой getch напишем
0
1123 / 794 / 219
Регистрация: 15.08.2010
Сообщений: 2,185
01.10.2014, 16:55
Цитата Сообщение от GetHelp Посмотреть сообщение
кривоватое немного решение конечно...
по сути, -32 это код функциональной клавиши, и если мы его встречаем, надо просто проигнорировать дополнителный 2ой байт, который она передает. Что ж тут кривоватого?
а через винапи для консольной программы это явно перебор.
0
63 / 64 / 11
Регистрация: 27.02.2013
Сообщений: 1,116
01.10.2014, 16:56  [ТС]
Цитата Сообщение от КОП Посмотреть сообщение
по сути, -32 это код функциональной клавиши, и если мы его встречаем, надо просто проигнорировать дополнителный 2ой байт, который она передает. Что ж тут кривоватого?
как это код функциональной клавиши? функциональные клавиши это типа enter, delete, backscape... но у них же разные коды... да и отрицательные коды клавиш разве бывают?
0
1123 / 794 / 219
Регистрация: 15.08.2010
Сообщений: 2,185
01.10.2014, 17:00
Лучший ответ Сообщение было отмечено GetHelp как решение

Решение

Цитата Сообщение от GetHelp Посмотреть сообщение
как это код функциональной клавиши?
а черт его знает. Обычная клавиша возвращает чар (1 байт), функциональная же (из примеров знаю только стрелки, может еще мультимедиа клавиши или некоторые сочетания) поместит в буфер 2 байта (первый является знаком, что был передан 2ой байт). НО getch ждет только 1, а второй оставляет там для следующего getch() к примеру. Поэтому и обрабатываем ручками такие случаи.
1
63 / 64 / 11
Регистрация: 27.02.2013
Сообщений: 1,116
01.10.2014, 17:03  [ТС]
Цитата Сообщение от КОП Посмотреть сообщение
а черт его знает. Обычная клавиша возвращает чар (1 байт), функциональная же (из примеров знаю только стрелки, может еще мультимедиа клавиши или некоторые сочетания) поместит в буфер 2 байта (первый является знаком, что был передан 2ой байт). НО getch ждет только 1, а второй оставляет там для следующего getch() к примеру. Поэтому и обрабатываем ручками такие случаи.
познавательно
0
Эксперт по математике/физикеЭксперт С++
 Аватар для Ilot
2223 / 1425 / 420
Регистрация: 16.05.2013
Сообщений: 3,642
Записей в блоге: 6
01.10.2014, 17:55
КОП,
Цитата Сообщение от GetHelp Посмотреть сообщение
Ilot, залез в самые дебри винапи -_- вот что вышло
Ну и нафиг это вам надо?
Как только дождались сигнала от входного потока проверяем, что бы это было сообщение от клавиатуры:
C++
1
pir.EventType == KEY_EVENT
и далее пишем свой код.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
01.10.2014, 17:55
Помогаю со студенческими работами здесь

Неопределенное поведение при приведении типа
Суть проблемы в том что, после принудительного приведения типа деструктор наследника не вызывается, вызывается деструктор базового типа.Но...

Один и тот же объект в одном выражении модифицируется несколько раз - неопределенное поведение
Уважаемые форумчане! Недавно столкнулся с интересным на мой взгляд необычным поведением компилятора c++ от keil. Определил класс шаблон...

"Неопределенное поведение" при выходе вводимых данных за пределы массива
В условии задачи написано, что функция не проверяет индексы. И если введенные пользователем входные данные будут выходить за пределы...

Как принять в функции main неопределенное количество параметров?
Добрый день) Нужно что бы функция main принимала от одного до трех параметров в виде маcсива значений { 0x1d ,0x72, 0x01} Вызов...

Ошибка агрументов в пользовательской функции
Делал функцию, которая бы переспрашивала вопрос, в случае некорректного ответа void answer(bool &amp;flag); int main() { ...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru