Hi,
I have a C++ program :

// ConsoleApplication14.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <list>
#include <queue>
#include <vector>
#include <string>

using namespace std;
class RectangularVectors
{
public:
    static std::vector<std::vector<int>> ReturnRectangularIntVector(int size1, int size2)
    {
        std::vector<std::vector<int>> newVector(size1);
        for (int vector1 = 0; vector1 < size1; vector1++)
        {
            newVector[vector1] = std::vector<int>(size2);
        }

        return newVector;
    }
    static std::vector<std::vector<bool>> ReturnRectangularBoolVector(int size1, int size2)
    {
        std::vector<std::vector<bool>> newVector(size1);
        for (int vector1 = 0; vector1 < size1; vector1++)
        {
            newVector[vector1] = std::vector<bool>(size2);
        }

        return newVector;
    }

};
class Cell {
public:
    int x;
    int y;
    int dis;
    Cell(int x, int y,  int dis);  // This is the constructor
};

// Member functions definitions including constructor
Cell::Cell(int x, int y, int dis) {
    this->x = x;
    this->y = y;
    this->dis = dis;

}
int minStepToReachTarget(std::vector<int> knightPos, std::vector<int> targetPos, int N, int M);

int main()
{
    int n, m, r, c;
    cout << "Enter the number of rows : ";
    cin >> n;
    cout << "Enter the number of cells : ";
    cin >> m;
    cout <<  "Enter the number of knight position row : ";
    cin >> r;
    cout << "Enter the number of knight position cell : ";
    cin >> c;
    std::vector<std::vector<int>> Moves = RectangularVectors::ReturnRectangularIntVector(n, m);
    std::vector<int> knightPos = { r - 1, c - 1 };
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            std::vector<int> targetPos = { i, j };
            Moves[i][j] = minStepToReachTarget(knightPos, targetPos, n, m);
        }
    }

    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            std::wcout << std::to_wstring(Moves[i][j]) << L"   ";
        }
    }

    int test;
    cin >> test;

}
bool isInside(int x, int y, int N, int M)
{
    if (x >= 0 && x <= N && y >= 0 && y <= M)
        return true;
    return false;
}
int minStepToReachTarget(std::vector<int> knightPos, std::vector<int> targetPos, int N, int M)
{
    // x and y direction, where a knight can move 
    int dx[] = { -2, -1, 1, 2, -2, -1, 1, 2 };
    int dy[] = { -1, -2, -2, -1, 1, 2, 2, 1 };

    // queue for storing states of knight in board 
    queue<Cell> q;

    // push starting position of knight with 0 distance 
    q.push(Cell(knightPos[0], knightPos[1], 0));

    Cell t = Cell(0,0,0);
    int x, y;
    const int N2 = N;
    const int M2 = M;

    std::vector<std::vector<bool>> visit = RectangularVectors::ReturnRectangularBoolVector(N + 1, M + 1);

    // make all cell unvisited 
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < M; j++)
        {
            visit[i][j] = false;
        }
    }

    // visit starting state 
    visit[knightPos[0]][knightPos[1]] = true;

    // loop untill we have one element in queue 
    while (!q.empty())
    {
        t = q.front();
        q.pop();

        // if current cell is equal to target cell, 
        // return its distance 
        if (t.x == targetPos[0] && t.y == targetPos[1])
            return t.dis;

        // loop for all reachable states 
        for (int i = 0; i < 8; i++)
        {
            x = t.x + dx[i];
            y = t.y + dy[i];

            // If reachable state is not yet visited and 
            // inside board, push that state into queue 
            if (isInside(x, y, N, M) && !visit[x][y])
            {
                visit[x][y] = true;
                q.push(Cell(x, y, t.dis + 1));
            }
        }

    }
    return 0;
}

And I just want to convert it to C language.
please help me.

Recommended Answers

All 2 Replies

What part are you having trouble with?

commented: I have problem with making Cell class and properties and queue too. +0

In your original functions, I would pass the std::vectors by reference, not by value. If a value is not expected to change, apply a const modifier to the argument. Now the compiler will warn you if you try to change it. Do not use the same name for your data members as the function parameter that is being used to manipulate it; you are just asking for confusion.

In general, converting this kind of C++ code to C would need you to:

  • Convert all class definitions to struct definitions (simple enough).
  • Redefine any member function into a regular function, taking your struct instance as a parameter, maybe a pointer to the struct instance if you need to modify the original struct.
  • Remove all constructors and destructors. The beautiful automatic allocation and clean-up provided by these member functions must be managed seperately in C.
  • All local variable declarations must be at the beginning of your functions, before any executable statements. In C++ you can declare variables and objects anywhere inside the function, even inside flow-control structures like loops.
  • public member functions should be declared in a header (.h) file so they can be #include'd in other source files in your project.
  • private or protected member functions should be declared only in the source (.c) file with a static modifier to indicate that the function can not be called outside of that source file.
  • cout >> calls get converted to puts() and printf() calls. The layouts are significantly different, so read the documentation.
  • cin << calls get converted to scanf() calls. I personally prefer using fgets() and sscanf() to get input to avoid buffer overflows and input loops. Always check the return value of sscanf() to make sure all your variables are filled.
  • std::vector objects are much easier to use than dynamic arrays in C, but that is what you have to convert those to and make sure you manage your heap memory properly, to avoid memory leaks and deferencing NULLs, as well as growing the array when full. You may want to put all that stuff in its own source file, like my_vector.c.
  • std::queue objects are also much easier to use than reinventing the wheel and having to create your own my_queue.c to manage it. The same dynamic memory management warnings apply to the queue, but even more so; make sure you do not pop from an empty queue. Are you going to grow your array (realloc()) when full or return a NULL?
  • convert bool to int. 0 is false, anything else is true. True results are usually 1.

Those are some general tips for this kind of conversion. Is there something specific you want to know?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.