61

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

Маю функцію запису у файл:

void newFile(string file_name, const Worker record[], int number_records)
{
    ofstream f_out(file_name, ios_base :: binary);
    f_out.write((char *) record, sizeof(Worker) * number_records);
    f_out.close();
}


Функція, ніби працює - файл створюється і заповнюється "кракозябрами", при цьому кількість "кракозябр" пропорційно зміється при зміні кількості записів.
І маю функцію зчитування з файлу:

void readFromFile(string file_name, Worker *&records, int &number_records )
{
    ifstream f_in(file_name, ios_base::binary);
    f_in.seekg(0, ios_base :: end);
    cout << f_in.tellg() << "\n";
    number_records = f_in.tellg() / sizeof(Worker);
    records = new Worker [number_records];
    f_in.seekg(0);
    f_in.read((char *)records, sizeof(Worker) * number_records);
    f_in.close();
}

Кількість записів (number_records) рахує правильно, курсор переводиться на початок, здавалось би все добре. Але нічого не зчитує, принаймні оцей масив records має такий вигляд (внизу, на скріншоті, показано, що він заповнений нулевими (порожніми) значеннями):

Прихований текст

http://i.imgur.com/jCt3byB.png

В чому ж проблема?

62

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

Задача: Написати програму, яка використовує структуру з наступними полями:
Name( Student name)
Idnum (Student ID number)
Tests (Pointer to an array of test scores)
Average (Average test score)
Grade (Course grade)
В програмі має бути динаміний масив таких структур.
Це я реалізувала так:

Прихований текст
#include <iostream>
#include <string>

using namespace std;

struct DataStudent
{
    string Name;
    int Idnum;
    int *Tests;
    double Average;
    char Grade; // A-F
};

DataStudent *createData(int &size_group, int &number_tests)
{
    if (size_group == 0 )
        size_group = 1;
    DataStudent *group = new DataStudent[size_group];
    for (int i = 0; i < size_group; ++i)
        group[i].Tests = new int[number_tests];
    return group;
}

bool validInput(int number)
{
    if (number < 0)
        return false;
    return true;
}
int main()
{
    int number_students, number_tests;

    do{
        cout << "How many students there are: ";
        cin >> number_students;
        cout << "How many test scores there are to be: ";
        cin >> number_tests;
        if (!validInput(number_students) || !validInput(number_tests))
            cout << "Incorrect input\n";
    } while (!validInput(number_students) && !validInput(number_tests));

    DataStudent *group_of_students = createData(number_students, number_tests);

    return 0;
}

І ще в задачі необхідно виконати перевірку на заповненість усіх полів. Так от, як це зробити для поля Name я знаю - просто перевірити чи рядок не пустий, а як зробити перевірку для числових полів - не знаю,  і взагалі, воно ж не дасть ввести "нічого", там де має бути число.
Підкажіть, будь ласка, як це зробити, або направте.

63

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

Дякую, запрацювало. Але хотілося б дізнатися чому так

64

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

Дякую, подумаю над цим

65

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

Задача: Написати програму, яка реалізує телефонну книгу з фіксованою(або динамічно змінюваною)
кількістю абонентів і всіма необхідними функціями. Використати вкладені структури(для адреси чи ПІБ).
Передбачити: добавлення запису у телефонну книгу, видалення запису, пошук даних про абонента по прізвищу
( чи імені), пошук даних по адресі(місту, селищу) та ін.
Реалізувала так:

Прихований текст
#include <iostream>
#include <cstring>
#include <conio.h>
#include <iomanip>

using namespace std;

struct Phonebook
{
    struct Name
    {
        char name[100];
        char surname[100];
    } name;
    char phone_number[50];
    struct Adress
    {
        char city[50];
        char street[50];
        int house_number;
        int flat_number;
    } adress;
};

void populateBaseWithTestData(Phonebook *&test, int size)
{
    const int TEST_NUMBER = 5;
    Phonebook members[5] = { { "Ivan", "Ivanov", "22-40-12", "Rivne", "Mlunivska", 40, 12 },
                             { "Olga", "Soroca", "23-34-45", "Rivne", "Kostromska", 12, 5 },
                             { "Alex", "James", "345-12-78", "Kyiv", "Khreshchatyk", 234, 12 },
                             { "Oleg", "Veremeyenko", "123-23-45", "Odessa ", "Sadova    ", 367, 123 },
                             { "Yana", "Kit      ", "2-78-12", "Kostopil", "Hrushevskoho", 65, 23 } };
    for (int i = 0; i < size; ++i)
        test[i] = members[i];
}

bool validInputPhoneNumber(const char *records)
{
    int i = 0;
    while (i < strlen(records))
    {
        if (!(isdigit(records[i]) || records[i] == '-'))
            return false;
        ++i;
    }
    return true;
}

bool validInputNameSurname(const char *records)
{
    int i = 0;
    while (i < strlen(records))
    {
        if (!(isalpha(records[i])))
            return false;
        ++i;
    }
    return true;

}

bool validInputNumber(const int records)
{
    if (records > 1)
        return true;
    else
        return false;
}

void inputRecord(Phonebook &records)
{
     
    do{
        cout << "Enter surname: ";
        cin.getline(records.name.surname, 100);
    } while (!validInputNameSurname(records.name.surname));
    cin.ignore(50, '\n');
    do{
        cout << "Enter name: ";
        cin.getline(records.name.name, 100);
    } while (!validInputNameSurname(records.name.name));

    do{
        cout << "Enter phone number: ";
        cin.getline(records.phone_number, 50);
    } while (!validInputPhoneNumber(records.phone_number));

    cout << "Enter city: ";
    cin.getline(records.adress.city, 50);
    
    cout << "Enter street: ";
    cin.getline(records.adress.street, 50);

    do{
        cout << "Enter the house number: ";
        cin >> records.adress.house_number;
    } while (!records.adress.house_number);
    do{
        cout << "Enter the flat number: ";
        cin >> records.adress.flat_number;
    } while (!records.adress.house_number);
    
}

Phonebook *createNewBase(int &size)
{
    size = 1;
    Phonebook *temp = new Phonebook[size];
    for (int i = 0; i < size; ++i)
        inputRecord(temp[i]);
    return temp;
}

void addRecord(Phonebook *&records, int &size)
{
    if (records == NULL)
    {
        records = createNewBase(size);
    }
    else
    {
        Phonebook *new_records = new Phonebook[size + 1];
        for (int i = 0; i < size; ++i)
            new_records[i] = records[i];
        delete[]records;
        records = new_records;
        inputRecord(records[size]);
        ++size;
    }
}

void headPrintRecord()
{
    cout << "N  " << "Name" << setw(15) << "Surname" << setw(15) << "Phone number" << setw(15) << "City" << setw(10) << "Street" << setw(10) << "House" << setw(6) << "Flat\n";
    cout << "-------------------------------------------------------------------------------\n";
}

void printRecord(const Phonebook record, int index)
{
    cout << index + 1 << "  " << record.name.name << setw(15) << record.name.surname << setw(15) << record.phone_number << setw(15);
    cout << record.adress.city << setw(15) << record.adress.street << setw(5) << record.adress.house_number << setw(4) << record.adress.flat_number << "\n";
}

void printAllRecords(const Phonebook *records, int size)
{
    if (records == NULL)
        cout << "Phonebook is empty\n";
    else
    {
        headPrintRecord();
        for (int i = 0; i < size; ++i)
        {
            cout << i + 1 << "  " << records[i].name.name << setw(15) << records[i].name.surname << setw(15) << records[i].phone_number << setw(15);
            cout << records[i].adress.city << setw(15) << records[i].adress.street << setw(5) << records[i].adress.house_number << setw(4) << records[i].adress.flat_number << "\n";
        }
    }
}
void searchRecordBySurname(const Phonebook *records, int size, char *search_key)
{
    if (records == NULL)
        cout << "Phonebook is empty\n";
    bool search = false;
    for (int i = 0; i < size; ++i)
    {
        if (strcmp(records[i].name.surname, search_key) == 0)
        {
            printRecord(records[i], i);
            search = true;
        }
    }
    if (!search)
        cout << "Not found " << search_key << "!\n";
}

void searchRecordByStreet(const Phonebook *records, int size, char *search_key)
{
    if (records == NULL)
        cout << "Phonebook is empty\n";
    bool search = false;
    for (int i = 0; i < size; ++i)
    {
        if (strcmp(records[i].adress.street, search_key) == 0)
        {
            printRecord(records[i], i);
            search = true;
        }
    }
    if (!search)
        cout << "Not found " << search_key << "!\n";
}

void searchRecordByPhoneNumber(const Phonebook *records, int size, char *search_key)
{
    if (records == NULL)
        cout << "Phonebook is empty\n";
    bool search = false;
    for (int i = 0; i < size; ++i)
    {
        if (strcmp(records[i].phone_number, search_key) == 0)
        {
            printRecord(records[i], i);
            search = true;
        }
    }
    if (!search)
        cout << "Not found " << search_key << "!\n";
}

void deleteRecord(Phonebook *&records, int &size, int pos_record)
{
    if (records == NULL)
        cout << "Phonebook is empty\n";
    else
    {
        --pos_record;
        if (pos_record < 0 || pos_record >= size)
            cout << "Phonebook doesn't have any record with this number\n";
        else
        {
            Phonebook *new_records = new Phonebook[size - 1];
            for (int i = 0; i < pos_record; ++i)
                new_records[i] = records[i];
            for (int i = pos_record; i < size - 1; ++i)
                new_records[i] = records[i + 1];
            delete[]records;
            records = new_records;
            --size;
        }
    }
}

void deleteAllRecords(Phonebook *&records, int &size)
{
    if (records == NULL)
        cout << "Phonebook is empty\n";
    else
    {
        delete[]records;
        records = NULL;
        size = 0;
        cout << "Phonebook cleared\n";
    }
}

void printMenu()
{
    cout << "\tMENU\n\n";
    cout << "\t\t1 - Add records\n";
    cout << "\t\t2 - Show all records\n";
    cout << "\t\t3 - Delete record\n";
    cout << "\t\t4 - Search records by name\n";
    cout << "\t\t5 - Search records by street\n";
    cout << "\t\t6 - Search records by phone number\n";
    cout << "\t\t7 - Clear phonebook\n";
    cout << "\t\t0 - exit\n";
}

void menu(Phonebook *records, int size)
{
    enum action{EXIT, ADD_RECORDS, SHOW_ALL_RECORDS, DELETE_RECORD, SEARCH_RECORDS_BY_SURNAME,
                SEARCH_RECORDS_BY_STREET, SEARCH_RECORDS_BY_PHONE_NUMBER, CLEAR_PHONEBOOK};
    bool exit = false;
    do{
        system("cls");
        printMenu();
        cout << "\nYour choice: ";
        int user_choice;
        cin >> user_choice;
        switch (user_choice)
        {
        case ADD_RECORDS:
            system("cls");
            addRecord(records, size);
            cout << "Record added\n";
            break;
        case SHOW_ALL_RECORDS:
            system("cls");
            cout << "\n\tAll records in base\n\n";
            printAllRecords(records, size);
            break;
        case DELETE_RECORD:
            system("cls");
            int pos_delete_record;
            cout << "Enter the number of record which you want delete: ";
            cin >> pos_delete_record;
            deleteRecord(records, size, pos_delete_record);
            cout << "Record deleted\n";
            break;
        case SEARCH_RECORDS_BY_SURNAME:
            system("cls");
            char user_search_surname[100];
            cout << "Enter the surname what you want to find: ";
            cin >> user_search_surname;
            searchRecordBySurname(records, size, user_search_surname);
            break;
        case SEARCH_RECORDS_BY_STREET:
            system("cls");
            char user_search_street[50];
            cout << "Enter the name street what you want to find: ";
            cin >> user_search_surname;
            searchRecordBySurname(records, size, user_search_street);
            break;
        case SEARCH_RECORDS_BY_PHONE_NUMBER:
            system("cls");
            char user_search_phone_number[50];
            cout << "Enter the phone number what you want to find: ";
            cin >> user_search_surname;
            searchRecordBySurname(records, size, user_search_phone_number);
            break;
        case CLEAR_PHONEBOOK:
            deleteAllRecords(records, size);
            break;
        case EXIT:
            cout << "Good by!\n";
            exit = true;
            break;
        default:
            cout << "Incorrect choice!\n";
        }
        _getch();
    } while (!exit);
}

int main()
{
    int number_records = 5;
    //Phonebook *records = new Phonebook[number_records];
    //populateBaseWithTestData(records, number_records);
    Phonebook *records = NULL;
    menu(records, number_records);

    return 0;
}

І, ніби все працює, але при введенні даних у функції :

Прихований текст
void inputRecord(Phonebook &records)
{
     
    do{
        cout << "Enter surname: ";
        cin.getline(records.name.surname, 100);
    } while (!validInputNameSurname(records.name.surname));
    cin.ignore(50, '\n');
    do{
        cout << "Enter name: ";
        cin.getline(records.name.name, 100);
    } while (!validInputNameSurname(records.name.surname));

    do{
        cout << "Enter phone number: ";
        cin.getline(records.phone_number, 50);
    } while (!validInputPhoneNumber(records.phone_number));

    cout << "Enter city: ";
    cin.getline(records.adress.city, 50);
    
    cout << "Enter street: ";
    cin.getline(records.adress.street, 50);

    do{
        cout << "Enter the house number: ";
        cin >> records.adress.house_number;
    } while (!records.adress.house_number);
    do{
        cout << "Enter the flat number: ";
        cin >> records.adress.flat_number;
    } while (!records.adress.house_number);
    
}

не записує у змінну, яка для введення стоїть перша. Програма просить ввести значення, але його не записує.
Приклад,
основне меню програми:

Прихований текст

http://i.imgur.com/l0t9KC9.png

занесення даних:

Прихований текст

http://i.imgur.com/89Ee0I6.png

вивід:

Прихований текст

http://i.imgur.com/BznEDca.png

Поле Surname не заповнене. В чому може бути проблема?

66

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

Я вам дякую, але ми їх ще не вивчали, тому зробила ось так:

bool validInputPhoneNumber(const char *records)
{
    int i = 0;
    while (i < strlen(records))
    {
        if (!(isdigit(records[i]) || records[i] == '-'))
            return false;
        ++i;
    }
    return true;
}

67

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

Мені необхідно створити аналог телефонної книги. І я вирішла зробити перевірку на коректність введення номеру ось так:

bool validInputPhoneNumber(const char *records)
{
    int i = 0;
   while (records != '\0' && isdigit(records[i]))
        ++i;
    cout << i << endl;
    if (i <= strlen(records))
        return true;
    else
        return false;

}

Але так перевіряє чи в номері лише числа, а в номері може бути - чи () з кодом.
Підкажіть, як правильно зробити більш-менш нормальну валідацію номеру.

68

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

Задача:

Прихований текст

Multipurpose Payroll. Write a program that calculates pay for either an hourly paid worker or a
salaried worker. Hourly paid workers are paid their hourly pay rate times the number of hours worked.
Salaried workers are paid their regular salary plus any bonus they may have earned.
The program should declare two structures for the following data:
Hourly Paid: HoursWorked, HourlyRate
Salaried: Salary, Bonus
The program should also declare a union with two members. Each member should be a structure variable:
one for the hourly paid worker and another for the salaried worker.
The program should ask the user whether he or she is calculating the pay for an hourly paid worker or
a salaried worker. Regardless of which the user selects, the appropriate members of the union will be used
to store the data that will be used to calculate the pay.
Input Validation: Do not accept negative numbers. Do not accept values greater than 80 for HoursWorked.

Як я зрозуміла, мені необхідно створити дві структури. Ось вони:

struct HourlyPaid
{
    int hours_worked;
    double hourlyrate;
};

struct Salaried
{
    double salary;
    double bonus;
};

і створити Union з полями: одне поле - типу перша структура, друге - друга структура. Я це зробила так:

union Workers
{
    HourlyPaid first_worker;
    Salaried second_worker;
};

Але я невпевнена чи це правильно, можливо я не так умову переклала.
Допоможіть, будь ласка, зробити правильно.
P.S. Яке в даному випадку практичне значення юніон, чому не просто окремі дві змінні?

69

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

Ось виправила щодо від'ємних чисел:

Прихований текст
#include <iostream>
#include <cstring>
#include <cstdlib>

using namespace std;

/** Gets input from keyboard
 *
 *  @return - char *expr
 */
char *input_expression()
{
    cout << "Enter expression: ";
    char *expr = new char[256];
    cin.getline(expr, 256);
    return expr;
}

/** Deletes element from array
 *
 * @param arr - array of any type
 * @param size - size of array arr
 * @param pos - index of element to delete
 */
template <class T>
void delete_element(T *arr, int &size, int pos)
{
    for (int i = pos; i < size; i++)
        arr[i]=arr[i+1];
    --size;
}

/** Gets intermediate result and makes appropriate changes in expression
 * which represented by array of numbers and array of operations.
 *
 * Example: 4 + 2 * 3  => numbers=(4, 2, 3), operations=(+, *)
 * After applaying mid result: numbers=(4, 6), operations=(+,)
 *
 * @param operations - array of operations in expression
 * @param numbers - array of numbers in expression
 * @param op_counter - size of array operations
 * @param num_counter - size of array num_counter
 * @param i - index of changed elements
 * @param mid_result - result of calculation of current operation
 */
void apply_mid_result(char *operations, double *numbers,
                        int op_counter, int num_counter,
                        int i, double mid_result)
{
    delete_element(operations, op_counter, i);
    delete_element(numbers, num_counter, i);
    numbers[i] = mid_result;
}

/** Parses given expression as string to arrays of numbers and operations.
 *
 * @param expr - arithmetic expression, stored in array of char
 * @param numbers - array of double, used as storage of all operands
 * @param num_counter - size of array numbers
 * @param operations - array of char, used as storage of all operations
 * @param op_counter - size of array operations
 */
void parse_expression(char *expr, double *numbers, int &num_counter,
                                  char *operations, int &op_counter)
{
    char oper_signs[] = "*/+-";
    double number;
    char *pch = expr;
    while (pch != NULL)
    {
       number = strtod(pch, &pch);
       numbers[num_counter] = number;
       ++num_counter;
       pch = strpbrk(pch, oper_signs);
       if (pch != NULL)
       {
           operations[op_counter] = *pch;
           ++op_counter;
           ++pch;
       }
    }
}

/** Calculates according to priority of operations, returns result of calculation.
 *
 * NOTE: can calculate expressions without brackets and with standard
 * arithmetic operations - addition, subtraction, multiplication, division.
 *
 * @param expr - arithmetic expression, stored in array of char
 * @return double result
 */
double calculate(char *expr)
{
    char operations[127];
    int op_counter = 0;

    double numbers[128];
    int num_counter = 0;

    parse_expression(expr, numbers, num_counter, operations, op_counter);

    double result = 0, mid_result;
    int i = 0;

    // first - high priority operations
    while (i < op_counter)
    {
        if (operations[i] == '*')
        {
            mid_result = numbers[i] * numbers[i+1];
            apply_mid_result(operations, numbers, op_counter, num_counter, i, mid_result);
        }
        else if (operations[i] == '/')
        {
            mid_result = numbers[i] / numbers[i+1];
            apply_mid_result(operations, numbers, op_counter, num_counter, i, mid_result);
        }
        else ++i;
    }

    // last - low priority operations
    i = 0;
    while (i < op_counter)
    {
        if (operations[i] == '+')
        {
            mid_result = numbers[i] + numbers[i+1];
            apply_mid_result(operations, numbers, op_counter, num_counter, i, mid_result);
        }
        else if (operations[i] == '-')
        {
            mid_result = numbers[i] - numbers[i+1];
            apply_mid_result(operations, numbers, op_counter, num_counter, i, mid_result);
        }
        else ++i;
    }

    return mid_result;
}


int main()
{
    char *expr = input_expression();
    cout << "\nExpression: " << expr;
    double result = calculate(expr);
    cout << "\nResult: " << result << "\n";
    return 0;
}

1. Підкажіть, будь ласка, як правильно виконати перевірку на коректність.
2. Як можна покращити код у функції calculate?

70

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

0xDADA11C7 написав:

Перевірте чи консольну ви програму створюєте в VS (в командному рядку для компілера мусить бути аргумент /SUBSYSTEM:CONSOLE)

Так, програма консольна



koala написав:
        char *expr = new char;
        cin.getline(expr, 256);

Виділяєте 1 символ і записуєте туди 256...

В цілому ж:
1. Програма ніби на C++, але з рядками і масивами працює, ніби це голий C. std::vector і std::string сильно полегшують життя. Так, дурнувата умова, але це виглядає як їздити на мотоциклі, відштовхуючись ногами від землі.
2. Немає унарних операцій; -1*-1 - цілком відповідає умові і має сенс, але викличе збій програми.
3. Немає перевірки на коректність коду.
В цілому я б радив скористатися або рекурсією, або ПОЛІЗом для кращого узагальнення роботи програми.

0. Додала квадратні дужки до new char - не допомогло.
1. Таке завдання - не я придумала, мені лише потрібно придумати як її реалізувати.
2. Над цим попрацюю - вилетіло геть з голови :[
3. Що саме перевірити? Вхідний рядок?
4. Що таке ПОЛІЗ? Ми, скоріш за все, його ще не вивчали.

71

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

Завдання: Дано вираз без дужок, у якому зустрічаються операції +, -,* та /. Обчислити значення виразу. Наприклад, для виразу 11 * 2  +  5 * 3 повинні отримати 37. Використати бібліотечні функції на вибір atoi() , atof(),strpbrk(), strcspn() strtod() strtol().

Реалізувала так:

Прихований текст
#include <iostream>
#include <cstring>
#include <cstdlib> // this include is not needed for Visual Studio

using namespace std;

/** Gets input from keyboard
 *
 *  @return - char *expr
 */
char *input_expression()
{
    cout << "Enter expression: ";
    char *expr = new char;
    cin.getline(expr, 256);
    return expr;
}

/** Deletes element from array
 *
 * @param arr - array of any type
 * @param size - size of array arr
 * @param pos - index of element to delete
 */
template <class T>
void delete_element(T *arr, int &size, int pos)
{
    for (int i = pos; i < size; i++)
        arr[i]=arr[i+1];
    --size;
}

/** Gets intermediate result and makes appropriate changes in expression
 * which represented by array of numbers and array of operations.
 *
 * Example: 4 + 2 * 3  => numbers=(4, 2, 3), operations=(+, *)
 * After applaying mid result: numbers=(4, 6), operations=(+,)
 *
 * @param operations - array of operations in expression
 * @param numbers - array of numbers in expression
 * @param op_counter - size of array operations
 * @param num_counter - size of array num_counter
 * @param i - index of changed elements
 * @param mid_result - result of calculation of current operation
 */
void apply_mid_result(char *operations, double *numbers,
                        int op_counter, int num_counter,
                        int i, double mid_result)
{
    delete_element(operations, op_counter, i);
    delete_element(numbers, num_counter, i);
    numbers[i] = mid_result;
}

/** Parses given expression as string to arrays of numbers and operations.
 * Calculates according to priority of operations, returns result of calculation.
 *
 * NOTE: can calculate expressions without brackets and with standard
 * arithmetic operations - addition, subtraction, multiplication, division.
 *
 * @param expr - arithmetic expression, stored in array of char,
 * @return double result
 */
double calculate(char *expr)
{
    // get all operations
    char operations[127];
    int op_counter = 0;
    char oper_signs[] = "*/+-";

    char *pch = expr;
    pch = strpbrk(pch, oper_signs);
    while (pch != NULL)
    {
      operations[op_counter] = *pch;
      pch = strpbrk(pch+1, oper_signs);
      ++op_counter;
    };
    cout << "\n";

    // get all numbers
    double numbers[128];
    int num_counter = 0;
    double number;

    pch = expr;
    while (*pch != '\0')
    {
       number = strtod(pch, &pch);
       numbers[num_counter] = number;
       ++num_counter;
       pch += strcspn(pch, oper_signs) + 1;
    }

    // make calculation
    double result = 0, mid_result;
    int i = 0;

    // first - high priority operations
    while (i < op_counter)
    {
        if (operations[i] == '*')
        {
            mid_result = numbers[i] * numbers[i+1];
            apply_mid_result(operations, numbers, op_counter, num_counter, i, mid_result);
        }
        else if (operations[i] == '/')
        {
            mid_result = numbers[i] / numbers[i+1];
            apply_mid_result(operations, numbers, op_counter, num_counter, i, mid_result);
        }
        else ++i;
    }

    // last - low priority operations
    i = 0;
    while (i < op_counter)
    {
        if (operations[i] == '+')
        {
            mid_result = numbers[i] + numbers[i+1];
            apply_mid_result(operations, numbers, op_counter, num_counter, i, mid_result);
        }
        else if (operations[i] == '-')
        {
            mid_result = numbers[i] - numbers[i+1];
            apply_mid_result(operations, numbers, op_counter, num_counter, i, mid_result);
        }
        else ++i;
    }

    return mid_result;
}


int main()
{
    char *expr = input_expression();
    cout << "\nExpression: " << expr;
    double result = calculate(expr);
    cout << "Result: " << result;
    return 0;
}

GCC(g++) скомпілював і все працює, але при спробі перенести цей код у Visual Studio програма вилітає на етапі виведення результату. В режимі відлагодження все порахувало нормально, вивело результат - нічого поганого не помітила.
В чому може бути проблема?
P.S. Чи можна покращити код?

72

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

Yola написав:

Можливо g++ ініціалізує виділену пам"ять нулями. Покладіть у new_str 0 після останнього символу. І знов у вас витік пам'яті.

Чому? Тому що нема delete?

Yola написав:

Подумайте про використання unique_ptr

На жаль, ми його ще не вивчали.

73

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

Задача: Написати функцію SubStr(const char * str, int pos, int len), яка повертає фрагмент  рядка,
починаючи з вказаної позиції(pos) та вказаної довжини(len). Рядок повертати як динамічний.
Реалізувала так :

Прихований текст
#include<iostream>
#include<cstring>

using namespace std;

char *SubStr(const char * str, int pos, int len)
{
    char *new_str = new char[len];
    if (pos >= 0 && pos < strlen(str) && (strlen(str) - len) > 0)
    {
        for (int i = pos, j = 0; i < len; ++i, ++j)
            *(new_str + j) = *(str + i);
    }
    return new_str;
}

int main()
{
    const int STRING_SIZE = 256;
    char text[STRING_SIZE] = "\0";
    char *new_text = NULL;

    cout << "Enter the text. Input complete the point\n";
    cin.getline(text, STRING_SIZE, '.');
    cin.ignore(STRING_SIZE, '\n');

    int new_length;
    cout << "Enter the length for new string: ";
    cin >> new_length;

    int new_pos;
    cout << "Enter the position that start copy to new string: ";
    cin >> new_pos;

    new_text = SubStr(text, new_pos, new_length);

    cout << "Your text:\n";
    cout << "\t" << text << "\n";

    cout << "New text:\n";
    cout << "\t" << new_text << "\n";

    return 0;
}

І ніби працює, але є одне "але": в результаті виконання вона видає мені таке (писала програму і компілювала у Visual Studio)

Прихований текст

http://i.imgur.com/gDEc9wf.png

Також компілювала програму за допомогою g++ - працює так, як потрібно. В чому може бути проблема?

74

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

Yola написав:

Зверніть увагу, що & у типах параметрів функції каже про те, що це посилання, тобто ви можете їх змінювати.

Дякую, я про це знаю))

75

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

Дякую, зробила так:

template <int size1, int size2>
void concatAllWords(char (&word[size1]), char (&rezult[size2]))
{
    strcat_s(word, " ");
    strcat_s(rezult, word);

}

Так добре?

76

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

Yola написав:

У main ви використовуєте перевантаження strcat_s, яке є шаблоном що приймає рядки виду char[SIZE], це зовсім не те саме, що char*.

Тут

void concatAllWords(char *word, char *rezult)

губиться інформація про розмір рядка.

тобто, мені можна прописати таким чином:

template <int size>
void concatAllWords(char word[size], char rezult[size])

?

77

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

Ось код програми, коли всі етапи задачі реалізовані лише в main(), з використанням функції strcat_s

Прихований текст
#include <iostream>
#include <cstring>

using namespace std;

int main()
{
    const int TEMP_LENGTH = 20, STRING_LENGTH = 256;

    int number_words;
    cout << "Enter number of words: ";
    cin >> number_words;

    char temp_word[TEMP_LENGTH] = "\0";
    char all_words[STRING_LENGTH] = "\0";
    char words_without_first_last_letters[STRING_LENGTH] = "\0";
    char words_with_same_first_last_letters[STRING_LENGTH] = "\0";

    while (number_words)
    {
        cout << "Enter word: ";
        cin >> temp_word;
        
        strcat_s(all_words, temp_word);
        strcat_s(all_words, " ");

        int length_copy = strlen(temp_word) - 2;
        strncat_s(words_without_first_last_letters, temp_word + 1, length_copy);
        strcat_s(words_without_first_last_letters, " ");

        if (temp_word[0] == temp_word[strlen(temp_word) - 1])
        {
            strcat_s(words_with_same_first_last_letters, temp_word);
            strcat_s(words_with_same_first_last_letters, " ");
        }   
        
        --number_words;
    }

    cout << "\nString with all input words: \n\t" << all_words << "\n";
    cout << "\nString without first and last letters in each word: \n\t" << words_without_first_last_letters << "\n";
    cout << "\nString with same first and last letters in each word: \n\t" << words_with_same_first_last_letters << "\n";

    return 0;
}

І вона робоча.

78

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

Задача: Вводиться послідовність N слів. Утворити рядок із :
o        всіх введених слів,  слова у створюваному тексті розділити пропусками(чи комами);
o        слів, що мають однакові першу і останню букви;
o        всіх слів, відкидаючи першу та  останню букви слів.
Використати бібліотечні функції strcat(), strncat().

Реалізувала так:

Прихований текст
#include <iostream>
#include <cstring>

using namespace std;

void concatAllWords(char *word, char *rezult)
{
    strcat(word, " ");
    strcat(rezult, word);

}

void concatWordsWithoutLetters(char *word, char *rezult)
{
    int length_copy = strlen(word) - 3;
    strncat(rezult, word + 1, length_copy);
    strcat(rezult, " ");
}

void concatWordsWithSameLetters(char *word, char *rezult)
{
    if (word[0] == word[strlen(word) - 2])
    {
        strcat(rezult, word);
        strcat(rezult, " ");
    }
}


int main()
{
    const int TEMP_LENGTH = 20, STRING_LENGTH = 256;
    
    int number_words;
    cout << "Enter number of words: ";
    cin >> number_words;

    char temp_word[TEMP_LENGTH] = "\0";
    char all_words[STRING_LENGTH] = "\0";
    char words_without_first_last_letters[STRING_LENGTH] = "\0";
    char words_with_same_first_last_letters[STRING_LENGTH] = "\0";

    while (number_words)
    {
        cout << "Enter word: ";
        cin >> temp_word;
        concatAllWords(temp_word, all_words);
        concatWordsWithoutLetters(temp_word, words_without_first_last_letters);
        concatWordsWithSameLetters(temp_word, words_with_same_first_last_letters);    
        --number_words;
    }

    cout << "\nString with all input words: \n\t" << all_words << "\n";
    cout << "\nString without first and last letters in each word: \n\t" << words_without_first_last_letters <<"\n";
    cout << "\nString with same first and last letters in each word: \n\t" << words_with_same_first_last_letters << "\n";

    return 0;
}

Але проблема в тому, що коли всі етапи задачі реалізовані лише в main(), то програма працює і я можу без проблем використовувати функцію strcat_s. Проте, коли хочу структурувати програму, розбити на функції, то, при використанні strcat_s, видає помилку:

Прихований текст

IntelliSense: no instance of overloaded function "strcat_s" matches the argument list
            argument types are: (char *, const char [2])

відповідно, у коді strcat_s замінюю на strcat і у відповідь знову ж таки помилка:

Прихований текст

Error    1    error C4996: 'strcat': This function or variable may be unsafe. Consider using strcat_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS.

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

79

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

Задача: Створити рядок у динамічній пам’яті. Замінити у рядку всі великі букви на малі і навпаки.
При обробці рядка використати вказівник.

Реалізувала так:

Прихований текст
#include <iostream>
#include <cstring>

using namespace std;

int main()
{
    const int STRING_LENGTH = 100;
    char *text = new char[STRING_LENGTH];
    cout << "Enter the string: \n";
    cin.getline(text, STRING_LENGTH);
    system("cls");
    cout << "Your text: " << text << "\n";
    cin.ignore(STRING_LENGTH, '\n');
    char *p = text;
    while (p < text + STRING_LENGTH && *p != '\0')
    {
        if (isupper(*p))
            *p = tolower(*p);
        else 
            *p = toupper(*p);
        p++;
    }
    
    cout << "\nYour changed text: " << text << "\n";
    delete[]text;
 
    return 0;
}

Запитання: чи потрібно при виділенні динамічної пам'яті для рядків і видаляти. Теоретично - так, але як це робиться на практиці - нам про це нічого не сказали. І в прикладах, які показував викладач, видалення пам'яті не відбувається. То як правильно?

80

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

Дякую, вийшло. Зробила ось так:

 int find_element;
    cout << "Enter number wich you want find in the matrix: ";
    cin >> find_element;
    int *first_entry_elements = searchFirstEntryElement(numbers, rows, find_element);
    if (first_entry_elements != 0)
        cout << "The first entry of the desired element: " << *first_entry_elements << "\n";
    else
        cout << "The desired element is not found\n";