Вывод любых структур на экран

264
06 декабря 2017, 22:10

Как можно сделать универсальный код, что бы он выводил все поля любых структур. Пример:

//пример одной структуры, и как должна отрабатывать
#pragma pack(push, 1)
typedef struct {
    int a;
    float b;
} structEx;
#pragma pack(pop)
using namespace std;
int main()
{
    structEx x;
    x.a = 4;
    x.b = 4.2;
    cout << x.a << ";" << x.b << endl; // эту строчку хочу универсальной сделать!
    return 0;
}

вот пример второй программы

//пример второй структуры, и как должна отрабатывать
#pragma pack(push, 1)
typedef struct {
    char c;
    float bb;
    double d[4];
} structEx;
#pragma pack(pop)
using namespace std;
int main()
{
    structEx x;
    x.c = 21;
    x.bb = 14.2;
    x.d[0] = 1.2;
    x.d[1] = 2.62;
    x.d[2] = 3.24;
    x.d[3] = 4.32;
    cout << x.c << ";" << x.bb << ";"
           << x.d[0] << ";" << x.d[1] << ";" << x.d[2] << ";"
            << x.d[3] << endl; // эту строчку хочу универсальной сделать!
    return 0;
}

Понятно, без больших мучений - никак. А как можно хотя бы немного упростить/автоматизировать? Или использовать может язык c#? синтаксис там предельно близок.

Answer 1

Думаю, что самым простым для Вас будет определить операторы вывода для структур:

#include <iostream>
#include <ostream>
typedef struct {
    int a;
    float b;
} structEx;
std::ostream &operator <<(std::ostream &ss, const structEx &x)
{
    ss
            << x.a
            << ";"
            << x.b;
    return ss;
}
typedef struct {
    char c;
    float bb;
    double d[4];
} structEx2;
std::ostream &operator <<(std::ostream &ss, const structEx2 &x)
{
    ss
            << x.c
            << ";"
            << x.bb
            << x.d[0]
            << x.d[1]
            << x.d[2]
            << x.d[3];
    return ss;
}

using namespace std;
int main()
{
    {
        structEx x;
        x.a = 4;
        x.b = 4.2;
        std::cout << x << std::endl;
    }
    {
        structEx2 x;
        x.c = 21;
        x.bb = 14.2;
        x.d[0] = 1.2;
        x.d[1] = 2.62;
        x.d[2] = 3.24;
        x.d[3] = 4.32;
        std::cout << x << std::endl;
    }
    return 0;
}
Answer 2

В C# это можно написать метод, вроде:

void PrintFields<T>(T obj)
{
    foreach (var field in typeof(T).GetFields(BindingFlags.Instance|BindingFlags.Public))
    {
        Console.WriteLine($"{field.Name} = {field.GetValue(obj)}");
    }
}

который будет выводить значения всех публичных экземплярных полей структуры или класса. Вот небольшой пример:

class Test
{
    public int x;
    public int y;
}
var t = new Test
{
    x = 1,
    y = 2,
};
// здесь выведется
// x = 1
// y = 2
Print(t);

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

UPD

Написал небольшой пример:

class Program
{
    static void Main(string[] args)
    {
        var t1 = new T1
        {
            a = 4,
            b = 4.2f
        };
        var t2 = new T2
        {
            c = (char)21,
            bb = 14.2f,
            d = new[] { 1.2, 2.62, 3.24, 4.32 }
        };
        using (var sw = new StreamWriter("output.txt", false))
        {
            PrintFields(sw, t1);
            sw.WriteLine("***");
            PrintFields(sw, t2);
        }
        Console.ReadKey();
    }
    static void PrintFields<T>(StreamWriter sw, T obj)
    {
        foreach (var field in typeof(T).GetFields(BindingFlags.Instance | BindingFlags.Public))
        {
            sw.Write(ConvertFieldToString(field, obj));
        }
        sw.WriteLine();
    }
    static string ConvertFieldToString<T>(FieldInfo fieldInfo, T obj)
    {
        var value = fieldInfo.GetValue(obj);
        if (fieldInfo.FieldType.IsArray)
        {
            var sb = new StringBuilder();
            var array = (Array)value;
            for (var i = 0; i < array.Length; i++)
            {
                sb.Append($"{array.GetValue(i)};");
            }
            return sb.ToString();
        }
        return $"{value.ToString()};";
    }
}
class T1
{
    public int a;
    public float b;
}
class T2
{
    public char c;
    public float bb;
    public double[] d;
}

Вот, что выводит программа:

4;4,2;

;14,2;1,2;2,62;3,24;4,32;

Вроде, отвечает запросам в исходном примере.

READ ALSO
Как поставить checkbox вместо значение из бд

Как поставить checkbox вместо значение из бд

Суть вот в чемВ базе есть таблица "table1"

256
Пуля в 3D вид сверху

Пуля в 3D вид сверху

У меня 3д сцена, вид сверхуНужно сделать чтобы, при нажатии мышки появлялась пуля и летела в направление места нажатия курсора и в заданной...

212
Событие keypress не срабатывает

Событие keypress не срабатывает

Хочу сделать так, чтобы при нажатии на клавиши происходило определенное событиеПишу код:

214