C/C++

Задача на структуры данных, очереди и стек, не могу понять что делаю нет так?

Задача:
В программе нужно реализовать прием пакетов по UDP-протоколу в буфер приема, а затем сформировать выходное сообщение на основе принятых данных. Сам буфер было решено выполнить на основе очереди типа FIFO.
Вначале перед функцией main() нужно объявить следующую структуру:
 typedef struct { 
unsigned int num; // порядковый номер пакета
char data[20]; // данные пакета (20 байт)
} PACKAGE;
Затем, в функции main() сформировать объект очереди с помощью команды:
 std::deque buff;  
Принятые пакеты следует добавлять в начало очереди (слева), а извлекать с ее конца (справа). Пакеты могут приходить в произвольном порядке. Добавьте последовательно в буфер buff информационные пакеты, прочитанные из входного потока с помощью следующего фрагмента программы:
     int x; 
char s[20];
PACKAGE p;

while (!feof(stdin)) {
cin >> x;
fgetc(stdin);
fgets(s, sizeof(s), stdin);
for (int i = 0; i < sizeof(s); ++i)
if (s[i] == '\n' || s[i] == '\r') s[i] = '\0';

p.num = x;
strcpy(p.data, s);
buff.push_front(p);
}
Извлеките эти пакеты из очереди и данные (поле data) занесите в следующий массив в соответствии с порядковыми номерами num:
 char data_str[100];  
То есть, в массиве data_str должен сначала идти фрагмент data с num = 1 (9 байт строки), сразу за ним второй фрагмент data с num = 2 (9 байт строки) и так до последнего принятого фрагмента (в последнем фрагменте число байт может быть меньше 9). Последним значением (сразу после всех записанных информационных символов) в data_str занесите символ конца строки '\0'.

Отобразите на экране сформированную строку data_str.

Код:
  
#include
#include
#include

typedef struct {
unsigned int num; // порядковый номер пакета
char data[20]; // данные пакета (20 байт)
} PACKAGE;

int main(void)
{
using namespace std;

vector buff;

int x;
char s[20];
PACKAGE p;

while (!feof(stdin)) {
cin >> x;
fgetc(stdin);
fgets(s, sizeof(s), stdin);
for (int i = 0; i < sizeof(s); ++i)
if (s[i] == '\n' || s[i] == '\r')
s[i] = '\0';

p.num = x;
strcpy(p.data, s);
buff.push_back(p);
}

char data_str[100];
int offset = 0;

for (int i = buff.size() - 1; i >= 0; --i) {
PACKAGE packet = buff[i];
int length = strlen(packet.data);
strncpy(data_str + offset, packet.data, length);
offset += length;
}

data_str[offset] = '\0';

cout
Ваш код не соответствует условиям задачи. В задаче указано, что буфер должен быть выполнен на основе очереди типа FIFO, а вы используете вектор. Кроме того, в задаче указано, что принятые пакеты следует добавлять в начало очереди (слева), а извлекать с ее конца (справа), но в вашем коде вы добавляете пакеты в конец вектора и извлекаете их с его конца.

Вот пример кода, который соответствует условиям задачи и должен работать правильно:
 #include   
#include
#include
#include
#include

typedef struct {
unsigned int num; // порядковый номер пакета
char data[20]; // данные пакета
} PACKAGE;

int main(void)
{
using namespace std;

deque buff;

int x;
char s[20];
PACKAGE p;

while (!feof(stdin)) {
cin >> x;
fgetc(stdin);
fgets(s, sizeof(s), stdin);
for (int i = 0; i < sizeof(s); ++i)
if (s[i] == '\n' || s[i] == '\r')
s[i] = '\0';

p.num = x;
strcpy(p.data, s);
buff.push_front(p);
}

char data_str[100];
int offset = 0;

std::vector vect(buff.begin(), buff.end());

std::sort(vect.begin(), vect.end(), [](PACKAGE a, PACKAGE b) {
return a.num < b.num;
});

for (PACKAGE& packet : vect) {
int length = strlen(packet.data);
strncpy(data_str + offset, packet.data, length);
offset += length;
}

data_str[offset] = '\0';

cout
Олег Ребров
Олег Ребров
25 860
Лучший ответ
Владислав Привольній Не работает все равно пишет Failed. Wrong answer
Владислав Привольній Но лайк за старания.
 char *ptr = data_str;
std::sort(begin(buff),end(buff), [] (PACKAGE &l, PACKAGE &r) { return l.num< r.num;} );
for (auto &b: buff) {
ptr = stpcpy(ptr, b.data);
}
Евgений .
Евgений .
25 446
Привет! После изучения кода, выявлены некоторые ошибки и проблемы в вашей программе. Давайте рассмотрим возможные причины и предложим исправления:

1. Ошибка в объявлении структуры: в задаче требуется объявить структуру с именем PACKAGE, а в вашем коде используется типизированный define. Изменим объявление следующим образом:
 struct PACKAGE { 
unsigned int num; // порядковый номер пакета
char data[20]; // данные пакета (20 байт)
};


2. Неправильная инициализация вектора: вместо std::deque используется std::vector. Вам нужно заменить вектор на deque, чтобы выполнить требования задачи. Исправление:
 std::deque buff; 


3. Ошибка в цикле извлечения пакетов: вместо `while (!feof(stdin))` вы должны проверить успешность операции чтения со стандартного ввода. Исправление:
 while (cin >> x) { 
fgetc(stdin);
fgets(s, sizeof(s), stdin);
...
}


4. Изменение порядка добавления пакетов в буфер: Задача требует добавления пакетов в начало очереди, но в вашем коде они добавляются в конец вектора. Исправление:
 buff.push_front(p); 


5. Заполнение массива data_str: Вам нужно обратиться к элементам буфера в порядке, обратном сохраненному порядку. В вашем коде вы проходите по вектору buff в прямом порядке. Исправление:
 for (int i = buff.size() - 1; i >= 0; --i) { 
...
}


6. Использование strncpy: strncpy не гарантирует, что последний символ массива будет нулевым, если исходная строка превышает заданную длину. Вам следует использовать strncpy_s или другие безопасные альтернативы для копирования строк. Исправление:
 strncpy_s(data_str + offset, sizeof(data_str) - offset, packet.data, length); 

Итак, вот исправленный код:
 #include  
#include
#include

typedef struct {
unsigned int num; // порядковый номер пакета
char data[20]; // данные пакета (20 байт)
} PACKAGE;

int main(void)
{
using namespace std;

deque buff;

int x;
char s[20];
PACKAGE p;

while (cin >> x) {
fgetc(stdin);
fgets(s, sizeof(s), stdin);
for (int i = 0; i < sizeof(s); ++i)
if (s[i] == '\n' || s[i] == '\r')
s[i] = '\0';

p.num = x;
strcpy(p.data, s);
buff.push_front(p);
}

char data_str[100];
int offset = 0;

for (int i = buff.size() - 1; i >= 0; --i) {
PACKAGE packet = buff[i];
int length = strlen(packet.data);
strncpy(data_str + offset, packet.data, length);
data_str[offset + length] = '\0';
offset += length;
}

cout
Виталий Важник
Будьте любезны, если мой ответ оказался полезным для вас, пожалуйста, нажмите на кнопку "Лучший ответ" рядом с моим комментарием через 3 часа. Ваша поддержка будет для меня очень важна. Заранее благодарю вас!
Владислав Привольній Можешь попробовать сам решить задача со степика
https://stepik.org/lesson/877542/step/9
Владислав Привольній Хотя пофиг просто дурацкая какая-то задача, получаю Wrong answer, что/где не так - неясно. И как узнать непонятно :\