Способ печати массива данных ( язык Си)

Работаю над реализацией протокола(проперитарного) ,одна функция в качестве “заглушки” печатает полученые данные.

Интересно ,может подскажет кто то способ рапечатать массив данных более элегантным спсособом ,чем показан ниже, а конкретней , избавиться от строк 26-31
функция LogInfo печатает с переносом строки (‘\n’)

typedef struct
{
	uint16_t cmd;
	uint8_t *payload;
	uint8_t len;
}Protocol_CmdReceiveParams_t;

void Protocol_HandleReceivedLogData(Protocol_CmdReceiveParams_t received)
{
	char tmpArray[17];
	uint8_t wholePartsLen = (sizeof(tmpArray) - 1); // left space for /0
	uint8_t wholeParts = received.len / wholePartsLen;
	uint8_t leftovers =  received.len % wholePartsLen;


	for(uint8_t j = 0 ;  j < wholeParts ; j++)
	{
		memset(tmpArray , 0 , sizeof(tmpArray));
		for(uint8_t i = 0 ; i < wholePartsLen ; i++)
		{
			sprintf(&tmpArray[i],"%x",received.payload[(wholePartsLen * j) + i]);
		}
		LogInfo(("Received 0x%x %d/%d %s" , received.cmd  , j , wholeParts + 1 , tmpArray));
	}

	memset(tmpArray , 0 , sizeof(tmpArray));
	for(uint8_t i = 0 ; i < leftovers ; i++)
	{
		sprintf(&tmpArray[i],"%x",received.payload[wholeParts * wholePartsLen + i]);
	}
	LogInfo(("Received 0x%x %d/%d %s" , received.cmd  , wholeParts + 1 , wholeParts + 1 , tmpArray));
}

Возьми да удали. У тебя выше то же самое написано. Логику чуток поправь и всё.

Нахрена?

длина массива received.payload не всегда кратна длине массива tmpArray. поэтому вопрос как распечатать остаток только строками 16-24 , остается открытым .

очищение массива перед каждой итерацией , что бы небыло “мусора” с предидущих итераций

Отвецтвуй мне, отрок человеческий, занахуа ты каждую итерацию цикла передаешь в sprintf адрес буфера, где собирается HEX, со сдвигом на 1 байт

А печатаешь потом всё равно с нулевого?

идея в целом такова : я знаю длину приходящего массива ,допустим при конкретном пакете 37 байт, вся функция это “заглушка” что бы проверить как отработал протокол до какого-то моментса , как приходят данные (это просто набор числовых значений , потом будет уже парситься дальше)
я хочу пришеший массив распечатать построчно ,допустим по 16 чисел в строке.
функция sprintf(&tmpArray[i],“%x”,received.payload[(wholePartsLen * j) + i]); форматирует числа в строку которую потом можо передать в LogInfo. (сейчас заметил косяк - числа будут 2ух значные(т.е. 2 байта на печать) , и по 16 чисел на строку могут что то сломать так как печатаю сейчас)
штука в том что естественным образом длина принимаемого пакета будет не кратна размера буффера печати tmpArray , как печатать так что бы leftovers последних чисел тоже напечатать в цикле 16-24 ?

в конечно виде на экране увидеть

Received 0х06 1/3 : 000102030405060708090A0B0C0D0E0F
Received 0х06 2/3 : 101112131415161718191A1B1C1D1E1F
Received 0х06 3/3 : 202122232425

То, што ты сподобился написать, оно так нихрена не работает. Подумой.

да , косяк вроде осознал , пока что написал вот такой вариант

#include <stdio.h>
#include "stdint.h"
#include "stdbool.h"


#define TEST_SIZE               57
#define PRINT_SIZE              16


void print_rows(uint8_t cmd , uint8_t* payload , uint8_t len)
{
  char printBuff[PRINT_SIZE * 2 + 1];// left space for \0
	uint8_t maxPrintLength = (PRINT_SIZE * 2); 
	uint8_t parts = len / PRINT_SIZE;
	parts += (uint8_t)((len % PRINT_SIZE) > 0) ;
	uint8_t currByteIdx = 0;
	uint8_t printLength = 0;
	do
	{
		printLength += snprintf(&printBuff[printLength] , maxPrintLength - printLength , "%02x" , payload[currByteIdx]);
		currByteIdx++;
		if(((printLength) == maxPrintLength) || (currByteIdx == len))
		{
		    printf("Received 0x%02x %d/%d %s\n" , cmd  ,(currByteIdx < len) ?  currByteIdx/PRINT_SIZE : currByteIdx/PRINT_SIZE + 1 , parts , printBuff);
			printLength = 0;
		}
		
	}while(currByteIdx < len);
}


int main()
{
    
    uint8_t test_data[TEST_SIZE];
    for(uint8_t i = 0 ; i < TEST_SIZE ; i++)
    {
        test_data[i] = i;
    }
    print_rows(0x06  , test_data  , TEST_SIZE);
    return 0;
}

Исправить немного

P.S. Был не прав, подкинул в Proteus(#7), всё равно ошибка, не хватает одного символа в конце строки

Спойлер

Screenshot_82

Вот мой вариант для Wokwi, вроде норм

Спойлер
#include "printf.h"

#define TEST_SIZE               75
#define PRINT_SIZE              16

void print_rows(uint8_t cmd,  uint8_t* payload , uint8_t len)
{
  uint8_t num_row = 0;//номер строки
  uint8_t sum_row = 0;//число строк
  int16_t remain = len;//остаток
  uint8_t offset = 0;//смещение адреса
  sum_row = len/PRINT_SIZE;
  if(len % PRINT_SIZE) sum_row++;
  while((int)(remain -= PRINT_SIZE) > - PRINT_SIZE)
  {  
    num_row++;
     printf("Received 0x%02x %d/%d % " , cmd , num_row, sum_row); 
     for(uint8_t f = 0; f < PRINT_SIZE; f++)
     {
    
      if(f + offset < len)
      printf("%02x", *(payload + f + offset ));
      else
      {
        printf("%c", '\n' );
        return; 
      }
     }
    offset +=(uint8_t) PRINT_SIZE;
     printf("%c", '\n' );
  }  
}


void setup() {
 Serial.begin(9600);
 delay(300);

  static uint8_t test_data[TEST_SIZE];
    for(uint16_t i = 0 ; i < TEST_SIZE ; i++)
    {
        test_data[i] = i;
    }
    print_rows(0x06  , test_data  , TEST_SIZE);
}

void loop() {}

printf.h

Спойлер

/*

	Using printf on the Arduino.
	by Michael McElligott
	
	Usage:
	Set a buffer size with _PRINTF_BUFFER_LENGTH_, default is 64 bytes, or about a single line
	Set output stream with _Stream_Obj_. eg; SerialUSB
	
	printf(format string, argument(s) list).
	printfn(): As above but appends a new line on each print; aka serial.println()
	
	eg; printf("%.2f, 0x%X", 1234.5678f, 32768);
	
	For a detailed list on printf specifiers:
	http://www.cplusplus.com/reference/cstdio/printf/
	and
	http://man7.org/linux/man-pages/man3/printf.3.html


		
	Tested with the Arduino Due 1.6.6
	Jan 2016	

*/





#ifndef _printf_h_
#define _printf_h_

#define _PRINTF_BUFFER_LENGTH_		64
#define _Stream_Obj_				Serial




#if 1
static char _pf_buffer_[_PRINTF_BUFFER_LENGTH_];
#else
extern char _pf_buffer_[_PRINTF_BUFFER_LENGTH_];
#endif


#define printf(a,...)														\
	do{																		\
	snprintf(_pf_buffer_, sizeof(_pf_buffer_), a, ##__VA_ARGS__);			\
	_Stream_Obj_.print(_pf_buffer_);										\
	}while(0)

#define printfn(a,...)														\
	do{																		\
	snprintf(_pf_buffer_, sizeof(_pf_buffer_), a"\r\n", ##__VA_ARGS__);		\
	_Stream_Obj_.print(_pf_buffer_);										\
	}while(0)



#endif
Спойлер