61

(14 відповідей, залишених у C++)

Доброго усім дян. Допоможіть, будь ласка розібратися.Створюю програму "бібліотека" і запоровся на додаванні джерела. Я вже погуглив і туди прохання не відправляти.
Проблема в наступному: коли функція get_sources_from_user переходить до заповнення другого елементу структури source_type, програма просто вирубається. Допоможіть розібратися в чому проблема.

#include <ctime>
#include <iomanip>
#include <iostream>
#include <string>
#include <fstream>
#include<windows.h>

using namespace std;

struct Item
{
    int serial_number;
    string source_type;
    string name;
    string author;
    int year;
    string genre;
    string publisher;
    string is_given;
};

#pragma region Show_library
//Вивід бібліотеки на екран
void print_source(Item *source)
{
    cout << setw(17) << "Serial number" << " :   " << source->serial_number << endl
        << setw(17) << left << "Type" << " :   " << source->source_type << endl
        << setw(17) << left << "Name" << " :   " << source->name << endl
        << setw(17) << left << "Author" << " :   " << source->author << endl
        << setw(17) << left << "Date" << " :   " << source->year << endl
        << setw(17) << left << "Genre" << " :   " << source->genre << endl
        << setw(17) << left << "Publiher" << " :   " << source->publisher << endl
        << setw(17) << left << "Given to" << " :   " << source->is_given << endl
        << "--------------------------------------------------------------------------------" << endl;
}

void print_sources(Item *sources, const int quantity)
{
    //cout << setw(20) << "Book name" << setw(20) << "Author" << setw(15) << "Publisher" << setw(15) << "Genre" << endl;
    cout << "List of sources" << endl << endl;
    for (Item *ptr = sources; ptr < sources + quantity; ++ptr)
    {
        print_source(ptr);
    }
}
#pragma endregion

#pragma region Add_source
//заповнення бібліотеки користувачем
void get_sources_from_user(Item *source, int index)
{
    source->serial_number = index; // копіюється без проблем
    int type = 0;
    do
    {
        cout << "Choose source type :" << endl
            << "1. Book" << endl
            << "2. Magazine" << endl
            << "3. News paper" << endl << endl
            << "Make a choice : ";
        cin >> type;
    } while (type < 1 || type > 3);
    switch (type) // тут починаються проблеми. який би вибір не зробили - програма "вилітає"
    {
    case 1: source->source_type = "book";
        break;
    case 2: source->source_type = "magazine";
        break;
    case 3: source->source_type = "news paper";
        break;
    default:
        cout << "Wrong choice!" << endl;
        break;
    }
    cin.ignore();
    cout << "Type the name of a source : ";
    getline(cin, source->name);
    cout << "Type the author of a source : ";
    getline(cin, source->author);
    cin >> source->year;
    cout << "Type the publisher of a source : ";
    getline(cin, source->publisher);
    cout << "Type the genre of a source : ";
    getline(cin, source->genre);
}

void move_source(Item *src, const int count, Item *dst)
{
    for (Item *src_ptr = src, *dst_ptr = dst; src_ptr < src + count; ++dst_ptr, ++src_ptr)
    {
        *dst_ptr = *src_ptr;
        //src_ptr = nullptr;
    }
}

Item* AddStruct(Item* source, int *file_size)
{
    int newSize = *file_size + 1;
    if (file_size == 0)
    {
        source = new Item[newSize]; // виділення пам'яті для першої структури
    }
    else
    {
        Item *new_source = new Item[newSize]; //створюємо масив структур розміром +1 книга
        move_source(source, *file_size, new_source); //копіюємо в новий масив існуючі книги

        get_sources_from_user((new_source + newSize), newSize); // в останній елемент масиву вводимо дані нової книги

        delete[] source;
        source = new_source;
        delete[] new_source;
    }
    *file_size = newSize;
    return source;
}

void add_source(Item *sources, int file_size) // додаємо нові книги
{
    char YesOrNot;
    do
    {
        sources = AddStruct(sources, &file_size); //додаємо до масиву нову структуру

        file_size++;
        do
        {
            cout << "Add onather source? (y/n): ";
            cin >> YesOrNot;
            cin.get();
        } while (YesOrNot != 'y' || YesOrNot != 'n');
        if (YesOrNot = 'n')
        {
            save_file(sources, file_size);
        }
    } while (YesOrNot != 'n');

    print_source(sources + file_size);

}
#pragma endregion

Зробив. Все працює. Але є питання: чи можна оптимізувати даний код?

#include<iostream>
#include<iomanip>
#include<time.h>

using namespace std;


void init_arr(int *arr, int x_size) //ініціалізація змінних в рядку
{
    for (int *arr_ptr = arr; arr_ptr < arr + x_size; ++arr_ptr)
    {
        *arr_ptr = rand() % 50 - 25;
    }
}

void arr_initialization(int **arr, int lines, int columns) //ініціалізація масиву
{
    for (int **arr_ptr_ptr = arr; arr_ptr_ptr < arr + lines; ++arr_ptr_ptr)
    {
        *arr_ptr_ptr = new int[columns];
        init_arr(*arr_ptr_ptr, columns);
    }
}


void print_arr(int **arr, int lines, int columns) //вивід масиву на екран
{
    for (int **arr_ptr_ptr = arr; arr_ptr_ptr < arr + lines; ++arr_ptr_ptr)
    {
        for (int *arr_ptr = *arr_ptr_ptr; arr_ptr < *arr_ptr_ptr + columns; ++arr_ptr)
        {
            cout << setw(4) << *arr_ptr;
        }
        cout << endl << endl;
    }
}


void clear_arr(int **arr, int lines) //видалення масиву
{
    for (int **arr_ptr_ptr = arr; arr_ptr_ptr < arr + lines; ++arr_ptr_ptr)
    {
        delete[] * arr_ptr_ptr;
    }
    delete[] arr;
}


//Написать функцию, добавляющую столбец двухмерному массиву в указанную позицию.
void add_column(int **scr, const int lines, const int columns, int **dst, const int index)
{
    for (int **scr_ptr = scr, **dst_ptr = dst; scr_ptr < scr + lines; ++scr_ptr, ++dst_ptr) //проходимося по ігрикам
    {
        for (int *scr_ptr_2 = *scr_ptr, *dst_ptr_2 = *dst_ptr; scr_ptr_2 < *scr_ptr + columns;) //проходимося по іксам
        {
            for (; scr_ptr_2 < *scr_ptr + index; ++scr_ptr_2, ++dst_ptr_2) //копіюємо значення по іксу від початку до індекса
            {
                *dst_ptr_2 = *scr_ptr_2;
            }
            *dst_ptr_2 = 1; // ініціалізація змінної індекса (можна і написати, щоб користувач вводив, або рандомно)
            ++dst_ptr_2; // переходимо до наступного ікса, щоб не скопіювати значення в індекс повторно
            for (; scr_ptr_2 < *scr_ptr + columns; ++scr_ptr_2, ++dst_ptr_2) //копіюємо значення по іксу від індекса до кінця
            {
                *dst_ptr_2 = *scr_ptr_2;
            }
        }
    }
}

int **add_column_to_arr(int **arr, int lines, int *columns, int index)
{
    int new_size = *columns + 1;
    int **arr_dst = new int*[lines];
    for (int **arr_ptr = arr_dst; arr_ptr < arr_dst + lines; ++arr_ptr)
    {
    *arr_ptr = new int[new_size];//створюємо масив на один ствпчик більший існуючого
    }

    add_column(arr, lines, *columns, arr_dst, index);
    *columns = new_size; //присвоюємо змінній нове значення, а масиву, відповідно, новий розмір
    return arr_dst;
    clear_arr(arr_dst, lines); //не забуваємо очистити пам'ять
}

void task1()
{
    int lines = 0;
    int columns = 0;
    cout << "Array initialization." << endl;
    cout << "Enter lines quantity : ";
    cin >> lines;
    cout << "Enter columns quantity : ";
    cin >> columns;
    int **dimm2_arr;
    dimm2_arr = new int *[lines];

    arr_initialization(dimm2_arr, lines, columns);
    print_arr(dimm2_arr, lines, columns);

    int index;
    do
    {
        cout << "Enter the index of column to add : ";
        cin >> index;
    } while (index < 0 || index > columns);

    dimm2_arr = add_column_to_arr(dimm2_arr, lines, &columns, index);
    print_arr(dimm2_arr, lines, columns);

    clear_arr(dimm2_arr, lines);
}

Привіт. Забув вказати, що мова програмування С++.
ntkrnlpa.exe, у вас в коді використовуються індекси
for(i = 0; i < lines; i++); таким способом я цю задачу зробив без особливих проблем.
На жаль, індекси використовувати не дозволяється, тому потрібно робити все через вказівники
for(int **arr_ptr = arr; arr_ptr = arr + lines; ++arr_ptr)
де **arr_ptr - вказівник на масив вказівників
arr - вказівкник на двовимірний масив

Думаю, що я майже зрозумів в чому проблема і сьогодні на свіжу голову спробую поправити код.

Привіт. Потрібна допомога в наступній задачі
Дано двовимірний масив, розміри якого задає користувач. В даний масив потрібно вставити стовбчик у вказану користувачем позицію. Використовувати можна лише вказівники. Жодних індексів!!!
У мене зациклює функція  copy_arr. Що з нею не так?
Дякую

void init_arr(int *arr, int x_size)
{
    for (int *arr_ptr = arr; arr_ptr < arr + x_size; ++arr_ptr)
    {
        *arr_ptr = rand() % 50 - 25;
    }
}

void arr_initialization(int **arr, int lines, int columns) // ініціалізація масиву
{
    for (int **arr_ptr_ptr = arr; arr_ptr_ptr < arr + lines; ++arr_ptr_ptr)
    {
        *arr_ptr_ptr = new int[columns];
        init_arr(*arr_ptr_ptr, columns);
    }
}


void print_arr(int **arr, int lines, int columns) // друк масиву
{
    for (int **arr_ptr_ptr = arr; arr_ptr_ptr < arr + lines; ++arr_ptr_ptr)
    {
        for (int *arr_ptr = *arr_ptr_ptr; arr_ptr < *arr_ptr_ptr + columns; ++arr_ptr)
        {
            cout << setw(4) << *arr_ptr;
        }
        cout << endl;
    }
}

void copy_arr(int **arr_scr, int lines, int columns, int **arr_dst) //копіювання масиву
{
    for (int **arr_scr_ptr_ptr = arr_scr; arr_scr_ptr_ptr < arr_scr + lines; ++arr_scr_ptr_ptr)
    {
        for (int *arr_scr_ptr = *arr_scr_ptr_ptr; arr_scr_ptr < *arr_scr_ptr_ptr + columns; ++arr_scr_ptr, ++arr_dst)
        {
            *arr_dst = arr_scr_ptr;
            arr_scr_ptr = nullptr;
        }
    }
}

int **add_column_to_arr(int **arr, int lines, int *columns, int index)
{
    int new_size = *columns + 1;
    int **arr_ptr_ptr = new int*[lines];
    for (int y = 0; y < lines; ++y)
    {
        arr_ptr_ptr[y] = new int[new_size];
    }

    copy_arr(arr, lines, index, arr_ptr_ptr);

    copy_arr(arr + index, lines, *columns - index, arr_ptr_ptr + index + 1);

    for (int y = 0; y < lines; ++y)
    {
        arr_ptr_ptr[y][index] = 1;
    }

    *columns = new_size;
    return arr_ptr_ptr;
    for (int y = 0; y < lines; ++y)
        arr_ptr_ptr[y] = new int[*columns];
    clear_arr(arr_ptr_ptr, lines);
}

void task1()
{
    int lines = 0;
    int columns = 0;
    cout << "Array initialization." << endl;
    cout << "Enter number of lines : ";
    cin >> lines;
    cout << "Enter number of columns : ";
    cin >> columns;
    int **dimm2_arr;
    dimm2_arr = new int *[lines];
    for (int i = 0; i < lines; i++)
    {
        dimm2_arr[i] = new int[columns];
    }
    arr_initialization(dimm2_arr, lines, columns);
    print_arr(dimm2_arr, lines, columns);

    int index;
    do
    {
        cout << "Enter the index of column to add : ";
        cin >> index;
    } while (index < 0 || index > columns);

    dimm2_arr = add_column_to_arr(dimm2_arr, lines, &columns, index);
    print_arr(dimm2_arr, lines, columns);

    clear_arr(dimm2_arr, lines);
}