1

Тема: Допоможіть будь ласка з перенесенням коду мовою Сі на С++.

Всім привіт. Зіткнувся з великими трудностями з перенесенням лаби мовою Сі на С++. Просидів доволі багато часу, навіть дописав її до кінця. Як на мою думку це б мало працювати, но звісно ж все не так).

Кому не важко, можете підказати, що мені варто переробити, що вся працювало. Отож, постановка задачі:

Сформувати файл “К”, що містить інформацію про кубики: розмір кожного кубика (довжина ребра в см), колір (червоний, жовтий, зелений або синій), матеріал (дерево, метал,  картон).
Переписати у файл “КІ” дані:
- кількість кубиків кожного з кольорів і їх сумарний об’єм;
- кількість дерев’яних кубиків з ребром 3 см.

===================================================================================
Код написаний мовою Сі:

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>

int main() {
    
    char size[][15] = { "3", "5", "7", "7", "5", "3", "5", "7", "3" };
    char color[][15] = { "red", "yellow", "blue", "blue", "yellow", "red",
     "yellow", "blue", "red" };
    char material[9][15] = { "wood", "metal", "carton", "carton", "metal",
     "wood", "metal", "wood", "carton" };
    int extent[9], counter=0;
    
    FILE* K;
    K = fopen("K.txt", "w");
    for (int i = 0; i < 9; i++) {
        fprintf(K, "\n%s \n%s \n%s", size[i], color[i], material[i]);
    }
    fclose(K);

    FILE* Info;
    Info = fopen("K.txt", "r");
    for (int i = 0; i < 9; i++){
        fscanf(Info,"%s %s %s", size[i], color[i], material[i]);
        if((strcmp(size[i], "3" ) == 0 && strcmp(material[i], "wood") == 0)) {
            counter++;
        }
    }
    fclose(Info);
    
    FILE *KI;
    KI = fopen("KI.txt", "w");
    for (int i = 0; i < 9; i++) {
        extent[i] = pow(atoi(size[i]),3);
        fprintf(KI, "\nExtent for Cube[%i]= %i;",i+1, extent[i]);
    }
        fprintf(KI, "\n\nAmount of cubes with size three and wood material = %i;",
         counter);
    fclose(KI);
}

===================================================================================

Розумію, можливо він не ідеальний, но і такий пройшов при перевірці.

І ось мої спроби переписати цей код мовою С++

===================================================================================

#include <iostream>
#include <fstream>
#include <cmath>
#include <cstring>
#include <string>

using namespace std;

int main() {

    char size[][15] = { "3", "5", "7", "7", "5", "3", "5", "7", "3" };
    char color[][15] = { "red", "yellow", "blue", "blue", "yellow", "red","yellow", "blue", "red" };
    char material[9][15] = { "wood", "metal", "carton", "carton", "metal","wood", "metal", "wood", "carton" };
    int extent[9], counter = 0;

    ofstream fout;
    fout.open("K.txt");
    if (!fout.is_open()) {
        cout << "Error! File isn't founded!" << endl;
    }
    else {
        for (int i = 0; i < 9; i++) {
            fout << size[i] << "\n" << color[i] << "\n" << material[i] << "\n" << endl;
        }
        fout.close();
    }
    ifstream fin;
    fin.open("K.txt");
    if (!fin.is_open()) {
        cout << "Error! File isn't founded!" << endl;
    }
    else {
        char info[i] = "";
        while (!fin.eof()) {
            fin >> info;
            cout << info << endl;
        }

        for (int i = 0; i < 256; i++) {
            if ((strcmp(info[i], "3") == 0 && strcmp(info[i], "wood") == 0)) {
                counter++;
            }
        }
    }
    fin.close();

    ofstream foutS;
    foutS.open("KI.txt");
    if (!foutS.is_open()) {
        cout << "Error! File isn't founded!" << endl;
    }
    else {
        for (int i = 0; i < 256; i++) {
            extent[i] = pow(atoi(info[i]), 3);
            foutS << "\nExtent for Cube[" << i + 1 << "] = " << extent[i] << ";" << endl;
        }
        foutS << "\nEAmount of cubes with size three and wood material" = << counter << endl;
    }

===================================================================================

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

2

Re: Допоможіть будь ласка з перенесенням коду мовою Сі на С++.

Прошу вибачення, опечатався, замітив аж після того як запостив.

========================================================================
що мені варто переробити, що вся працювало
що мені варто переробити, щоб все працювало

foutS << "\nEAmount of cubes with size three and wood material" = << counter << endl;
    }

foutS << "\nEAmount of cubes with size three and wood material = "  << counter << endl;
========================================================================

3

Re: Допоможіть будь ласка з перенесенням коду мовою Сі на С++.

Старався виконати, но безрезультатно. Кому

Підказка. Зазвичай, компілятори щось кажуть, якщо програму не можуть скомпілювати. В прикладі з джерельним кодом на С++ ви заьули ще додати закриваючу дужку хвункції int main() {, можливо вона є у вас на комп'ютері, а тут ви забули просто додати її, а можливо і нема. Ми не екстрасенси. Тягніть сюди те, що каже компілятор.
Наступне:
оцей код працює виключно у мові С++

            fout << size[i] << "\n" << color[i] << "\n" << material[i] << "\n" << endl;

Але це не значить, що наступний код не буде працювати на С++. Цей код так само коректний і для С++.

fprintf(K, "\n%s \n%s \n%s", size[i], color[i], material[i]);

Я, здається, бачу ще одну помилку, але озвучте, будь ласка її самі(компілятор має написати) - тоді ми зможемо вам допомогти, а не зробити завдання за вас.

Подякували: Vitaliy.l0k11

4 Востаннє редагувалося koala (08.01.2022 09:52:28)

Re: Допоможіть будь ласка з перенесенням коду мовою Сі на С++.

0. Саме завдання видається дещо дивним. C та C++, всупереч схожій назві та навіть досить високій сумісності - різні мови з різними підходами до програмування. Загалом, якщо ви хочете програмувати якісно, то не треба перекладати з мови на мову - максимум підглядати ідеї в коді іншою мовою. Бо "програміст на Basic може написати програму на Basic будь-якою мовою програмування", такі справи.
1. Практично весь код працюватиме і на C, і на C++. Якщо вас це влаштовує - могли не переходити з FILE* на stream; якщо ні, і ви не бажаєте користуватися бібліотеками C - то незрозуміло, чому при цьому вас strcmp влаштовує. Стандартний тип для стрічок у C++ - це std::string, а не char[].
2. В цілому, що на C, що на C++, тут варто було б проголосити новий тип (struct і class, відповідно), і кілька функцій для роботи з ним. Це значно б спростило читання коду (хоча правда, він став би довшим).
3. Код на C не містить обробки помилок. Код на C++ містить імітацію такої обробки (виводяться повідомлення про деякі проблеми з файлом, але виконання продовжується). Якщо ви вже перекладаєте - то перекладайте.
4. У коді на C середній цикл читає з файлу до масивів всі дані. У коді на C++ він читає у змінну info (до речі, на C++ такі проголошення заборонені, у вас компілятор нестандартний) недостатньої довжини (тобто ще й з UB) дані з файлу, виводить їх і перезаписує наступними даними. А потім ви некоректно шукаєте в останніх прочитаних даних, з UB і несумісними умовами. Те саме стосується і останнього циклу. Звідки ви взяли, що в exnent та info буде 256 елементів? Ба більше, info ж і не проголошена для останнього циклу.
5. Минулий час від to find - found (знаходити - знайшов). Минулий час від to found - founded (засновувати - заснував).

Коротше - погано у вас вийшло. Якщо вам так важливо переписати саме код на C у код на C++ - спробуйте зробити це ближче до оригіналу, без зайвих дій, щоб бачити, що саме у що саме перейшло. Можете старий код лишити як коментарі для нового, порядково.

Подякували: 0xDADA11C7, Vitaliy.l0k12

5

Re: Допоможіть будь ласка з перенесенням коду мовою Сі на С++.

Стандартний тип для стрічок у C++ - це std::string, а не char[].

Це правда. Але правдою є і те, що городити скрізь динамічні стрічки безглуздо, лише тому, що так буде "плюсовіше".

Подякували: Vitaliy.l0k11

6

Re: Допоможіть будь ласка з перенесенням коду мовою Сі на С++.

Ну і маленький бонус.

    FILE* K;
    K = fopen("K.txt", "w");

можна скоротити до

    FILE* K = fopen("K.txt", "w");

а stream у C++ - навіть до

    {
        ofstream fout("K.txt");
        ...
    } //fout.close не потрібен, бо змінна fout проголошена в фігурних дужках і буде знищена при виході з них
    //а при знищенні ofstream закриває файл

Звісно, ще красивіше це було б до окремих функцій повиносити.

Подякували: Vitaliy.l0k11

7

Re: Допоможіть будь ласка з перенесенням коду мовою Сі на С++.

Спасибі Koala та 0xDADA11C7 за допомогу. Так я дещо переосмислив, зрозумів в чому були мої помилки. Вибачте за мою некомпетентність в поданні постів, наступного разу візьму все вами сказане до уваги.

Koala, так я знаю про те як можна скороти 

[tt]FILE* K = fopen("K.txt", "w");[/tt]

Но за ось це:

{
        ofstream fout("K.txt");
        ...
    } //fout.close не потрібен, бо змінна fout проголошена в фігурних дужках і буде знищена при виході з них
    //а при знищенні ofstream закриває файл

Велике спасибі, буду знати.

Також, я знаю що бібліотеки з Сі сумісні з С++ і код по суті можна було б майже і не змінювати. В умові перенесення коду мовою Сі на С++ не було звісно сказано про те, що обов'язково використовувати бібліотеки stream, но хіба ж так цікаво? xD
Но все рівно дякую і за це!)

Що до функцій то нам заборонили розбивати код на функції, все повинно було міститись в одній функції.. Нажаль така умова. А за англійську, це просто тупняк серед ночі, навіть не помітив при перевірці, дякую що поправили :)

І ось, що я намудрив за сьогодні:

#include <iostream>
#include <fstream>
#include <cmath>
#include <cstring>
#include <string>

using namespace std;

int main() {

    string size[9] = { "3", "5", "7", "7", "5", "3", "5", "7", "3" };
    string color[9] = { "red", "yellow", "blue", "blue", "yellow", "red","yellow", "blue", "red" };
    string material[9] = { "wood", "metal", "carton", "carton", "metal","wood", "metal", "wood", "carton" };
    int extent, counter = 0;
    const int sizeOfArray = 9;
    string findSize3 = "3";
    string findMaterialWood = "wood";
    string findColorRed = "red";
    int extentForAllCubes;


    ofstream fout;
    fout.open("K.txt");
    if (!fout.is_open()) {
        cout << "Error! File isn't founded!" << endl;
    }
    else {
        for (int i = 0; i < sizeOfArray; i++) {
            fout << size[i] << "\n" << color[i] << "\n" << material[i] << "\n" << endl;
        }
        fout.close();
    }
    ifstream fin;
    fin.open("K.txt");
    if (!fin.is_open()) {
        cout << "Error! File isn't founded!" << endl;
    }
    else {
        for (int i = 0; i < sizeOfArray; i++) {
            if (!(size[i].compare(findSize3)) && !(material[i].compare(findMaterialWood))) {
                counter++;
                extent = pow((stoi(size[i])), 3) * counter;
            }
        }

    }
    fin.close();

    ofstream foutS;
    foutS.open("KI.txt");
    if (!foutS.is_open()) {
        cout << "Error! File isn't founded!" << endl;
    }
    else {
        for (int i = 0; i < sizeOfArray; i++){
        extentForAllCubes = pow((stoi(size[i])), 3);
            foutS << "\n" << "Extent for Cube[" << i + 1 << "] = " << extentForAllCubes << endl;
}
        foutS << "\nAmount of cubes, which have size 3 and material wood = " << counter << ";" << endl;
        foutS << "Total extent of cubes with size 3 = " << extent << ";" << endl;
    }

}

В консолі все без помилок, і ось що виводиться в файли.

І так, я розумію що цей код далеко неідеальний, можливо навіть мої порівняння через функцію compare неправильно оформлені. Отож, буду дуже вдячний правкам більш компетентніших кодерів. Ще раз велике дякую!)

Файл K:

  • 3
    red
    wood

    5
    yellow
    metal

    7
    blue
    carton

    7
    blue
    carton

    5
    yellow
    metal

    3
    red
    wood

    5
    yellow
    metal

    7
    blue
    wood

    3
    red
    carton

Файл KI:

  • Extent for Cube[1] = 27

    Extent for Cube[2] = 125

    Extent for Cube[3] = 343

    Extent for Cube[4] = 343

    Extent for Cube[5] = 125

    Extent for Cube[6] = 27

    Extent for Cube[7] = 125

    Extent for Cube[8] = 343

    Extent for Cube[9] = 27

    Amount of cubes, which have size 3 and material wood = 2;
    Total extent of cubes with size 3 = 54;

8

Re: Допоможіть будь ласка з перенесенням коду мовою Сі на С++.

В умові сказано "кількість кубиків кожного з кольорів і їх сумарний об’єм". Замість цього ви рахуєте об'єм кожного кубика без урахування його кольору. Причому на C теж.
Порівняння з compare працюють, але якщо вам треба перевіряти стрічки на рівність, то звичайного оператора == достатньо:

if (size[i]==findSize3 && material[i]==findMaterialWood))

Але тепер ви не читаєте нічого з файлу K.txt.

Ну і раз ви почали виносити "магічні значення" в константи на початок, що загалом дуже правильно, то робіть це вже послідовно (великі літери для констант - загальноприйнята норма, але, звісно, можете залишити ваш snakeCase, якщо вам так приємніше):

const int TOTAL_CUBES = 9;
const string FIND_SIZE_3 = "3";
const string FIND_MATERIAL_WOOD = "wood";
const string FIND_COLOR_RED = "red";
string size[TOTAL_CUBES ] = { "3", "5", "7", "7", "5", "3", "5", "7", "3" };
string color[TOTAL_CUBES ] = { "red", "yellow", "blue", "blue", "yellow", "red","yellow", "blue", "red" };
string material[TOTAL_CUBES ] = { "wood", "metal", "carton", "carton", "metal","wood", "metal", "wood", "carton" };
Подякували: Vitaliy.l0k1, 0xDADA11C72

9

Re: Допоможіть будь ласка з перенесенням коду мовою Сі на С++.

Так краще не робити!

string size[9] = { "3", "5", "7", "7", "5", "3", "5", "7", "3" };
string color[9] = { "red", "yellow", "blue", "blue", "yellow", "red","yellow", "blue", "red" };
string material[9] = { "wood", "metal", "carton", "carton", "metal","wood", "metal", "wood", "carton" };

Коли загубиш один із елементів в цих масивах важкувато тобі прийдеться. Тай читається воно якось не дуже. Обгорни їх в struct/class.

struct CUBE{
  size_t ribLength;
  string color;
  string material;
};

struct CUBE cub[9];

string size[9] = { "3", "5", "7", "7", "5", "3", "5", "7", "3" };

Чому не цілочисельний тип даних? Навіщо собі далі ускладнювати задачу?

Та й навіщо тобі цей STRING для змінних кольору та матеріалу. Перелічи кольори в ENUM, а матеріали занеси до іншого переліку і буде тобі щастя. Сподіваюсь ти знаєш, що таке enum раз потоки вчиш?

enum Color { red, yellow, green, blue };
enum Material { wood, metal, cardboard };

typedef struct {
  size_t ribLength;
  Color color;
  Material material;
} Cube;

/* Десь далі у коді . . . */

  Cube cube[] = {{4, blue, cardboard},
                 {3, red, wood},
                 {3, green, metal},
                 {3, blue, wood},
                 {8, green, cardboard}};

Організуй для початку правильне представлення змінних у пам'яті, щоб робити щось далі. І тоді легше буде писати код і не відволікатись на різну маячню типу переписування коду.

Подякували: leofun011

10

Re: Допоможіть будь ласка з перенесенням коду мовою Сі на С++.

Та тут купа помилок, але питання більше в тому, що саме потрібне топікстартеру. Завдання "перекласти з C на C++" йому, схоже, не задавали (не давали ж їм код на C, бо код не для цієї задачі), але він чомусь тримається саме цього завдання, чим значно ускладнює життя собі і тим, хто йому хоче допомагати.