Come si converte un array di byte in una stringa esadecimale in C?


88

Io ho:

uint8 buf[] = {0, 1, 10, 11};

Voglio convertire l'array di byte in una stringa in modo da poter stampare la stringa usando printf:

printf("%s\n", str);

e ottieni (i due punti non sono necessari):

"00:01:0A:0B"

Qualsiasi aiuto sarebbe molto apprezzato.


buf[i]deve essere gettato su unsigned char, o buf[i] > 127buf_ptr += sprintf(buf_ptr, "%02X", (unsigned char)buf[i]);
traboccerà

Risposte:


93
printf("%02X:%02X:%02X:%02X", buf[0], buf[1], buf[2], buf[3]);

per un modo più generico:

int i;
for (i = 0; i < x; i++)
{
    if (i > 0) printf(":");
    printf("%02X", buf[i]);
}
printf("\n");

per concatenare a una stringa, ci sono alcuni modi per farlo ... probabilmente terrei un puntatore alla fine della stringa e userei sprintf. dovresti anche tenere traccia della dimensione dell'array per assicurarti che non diventi più grande dello spazio allocato:

int i;
char* buf2 = stringbuf;
char* endofbuf = stringbuf + sizeof(stringbuf);
for (i = 0; i < x; i++)
{
    /* i use 5 here since we are going to add at most 
       3 chars, need a space for the end '\n' and need
       a null terminator */
    if (buf2 + 5 < endofbuf)
    {
        if (i > 0)
        {
            buf2 += sprintf(buf2, ":");
        }
        buf2 += sprintf(buf2, "%02X", buf[i]);
    }
}
buf2 += sprintf(buf2, "\n");

Grazie Mark, il mio problema è un po 'più complicato. In realtà ho un buffer con una lunghezza di X byte. Speravo di trovare un modo generico per farlo per X byte e ottenere una stringa come risultato.
Steve Walsh

Appena aggiornato per aggiungere codice per la gestione di un dato numero di byte ... supponendo che x sia la lunghezza.
Mark Synowiec

Grazie ancora Mark, ma la cosa che ho trovato più complicato per questo problema è come stamparlo su una stringa.
Steve Walsh

5
printf("%02X", (unsigned char)buf[i]);dovrebbe essere usato poiché l'originale causerà un overflow per i caratteri non firmati
easytiger

3
Perché no printf("%02hhX", buf[i])?
Hintron

32

Per completezza, puoi anche farlo facilmente senza chiamare alcuna funzione di libreria pesante (no snprintf, no strcat, nemmeno memcpy). Può essere utile, ad esempio se stai programmando un microcontrollore o un kernel del sistema operativo in cui libc non è disponibile.

Niente di veramente strano che tu possa trovare codice simile in giro se lo cerchi su google. In realtà non è molto più complicato che chiamare snprintf e molto più veloce.

#include <stdio.h>

int main(){
    unsigned char buf[] = {0, 1, 10, 11};
    /* target buffer should be large enough */
    char str[12];

    unsigned char * pin = buf;
    const char * hex = "0123456789ABCDEF";
    char * pout = str;
    int i = 0;
    for(; i < sizeof(buf)-1; ++i){
        *pout++ = hex[(*pin>>4)&0xF];
        *pout++ = hex[(*pin++)&0xF];
        *pout++ = ':';
    }
    *pout++ = hex[(*pin>>4)&0xF];
    *pout++ = hex[(*pin)&0xF];
    *pout = 0;

    printf("%s\n", str);
}

Ecco un'altra versione leggermente più breve. Evita semplicemente la variabile di indice intermedia i e la duplicazione dell'ultimo codice case (ma il carattere di terminazione viene scritto due volte).

#include <stdio.h>
int main(){
    unsigned char buf[] = {0, 1, 10, 11};
    /* target buffer should be large enough */
    char str[12];

    unsigned char * pin = buf;
    const char * hex = "0123456789ABCDEF";
    char * pout = str;
    for(; pin < buf+sizeof(buf); pout+=3, pin++){
        pout[0] = hex[(*pin>>4) & 0xF];
        pout[1] = hex[ *pin     & 0xF];
        pout[2] = ':';
    }
    pout[-1] = 0;

    printf("%s\n", str);
}

Di seguito è riportata un'altra versione per rispondere a un commento che dice che ho usato un "trucco" per conoscere la dimensione del buffer di input. In realtà non è un trucco ma una conoscenza di input necessaria (devi conoscere la dimensione dei dati che stai convertendo). L'ho reso più chiaro estraendo il codice di conversione in una funzione separata. Ho anche aggiunto il codice di controllo dei limiti per il buffer di destinazione, che non è realmente necessario se sappiamo cosa stiamo facendo.

#include <stdio.h>

void tohex(unsigned char * in, size_t insz, char * out, size_t outsz)
{
    unsigned char * pin = in;
    const char * hex = "0123456789ABCDEF";
    char * pout = out;
    for(; pin < in+insz; pout +=3, pin++){
        pout[0] = hex[(*pin>>4) & 0xF];
        pout[1] = hex[ *pin     & 0xF];
        pout[2] = ':';
        if (pout + 3 - out > outsz){
            /* Better to truncate output string than overflow buffer */
            /* it would be still better to either return a status */
            /* or ensure the target buffer is large enough and it never happen */
            break;
        }
    }
    pout[-1] = 0;
}

int main(){
    enum {insz = 4, outsz = 3*insz};
    unsigned char buf[] = {0, 1, 10, 11};
    char str[outsz];
    tohex(buf, insz, str, outsz);
    printf("%s\n", str);
}

1
Non è un trucco, solo una costante. Nel contesto della domanda è chiaro che la lunghezza del sorgente che vogliamo convertire in esadecimale è ben nota (avrei potuto mettere un 4 hardcoded invece di sizeof). Nel caso generale la funzione dovrebbe essere chiamata su qualche ingresso di lunghezza nota e il buffer di destinazione ha 3 volte + 1 byte disponibili. Questo deve essere garantito dal chiamante, non c'è motivo per cui la funzione di conversione esegua tale attività. Chiamare strlen () può essere un modo per trovare la dimensione del sorgente in alcuni casi, ma non sempre. Cosa succede se il numero da convertire in esadecimale contiene zero?
kriss

Ispirato dalla tua funzione, ho scritto una versione che restituisce anche il numero di byte scritti nel buffer di output, simile a snprintf, ecc. Gist.github.com/cellularmitosis/0d8c0abf7f8aa6a2dff3
Jason Pepas

Penso che dovresti impostare automaticamente la dimensione corretta del buffer di output usando char str [sizeof (buf) * 3 + 1];
Cecil Ward

Inoltre, molte più const ti salvaguarderebbero. Ad esempio "const unsigned char const * p" in modo da assicurarti che i buffer di input non vengano scritti. Uno rende l'indirizzo (o "puntatore") costante, o variabile, e l'altro rende la memoria a quell'indirizzo di sola lettura o meno. Spesso ti impedisce di confondere le indicazioni. Inoltre, sarebbe utile anche avere nomi significativi che documentano quali buffer e puntatori sono per l'input e l'output.
Cecil Ward

@ Cecil War: a meno che il mio codice non sia fasullo, l'uso di const non salvaguarderà molto tranne quando dici mescolando puntatori o usando lo stesso puntatore per input e output (ok, ancora possibile). Ma aiuterà anche il compilatore a ottimizzare il codice. Ancora meglio sarebbe usare anche la parola chiave limit (peccato che C99 non C ++, ma spesso esiste come estensione del compilatore). Cosa vuoi di più significativo per chiamare il buffer di input ine il buffer di output out? Potrei anche optare per l'uso di una stringa e la restituzione di una copia invece di fornire il buffer di output, nei moderni ottimizzatori C ++ sono abbastanza buoni da non preoccuparsene molto.
kriss

15

Ecco un metodo molto più veloce:

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

unsigned char *     bin_to_strhex(const unsigned char *bin, unsigned int binsz,
                                  unsigned char **result)
{
  unsigned char     hex_str[]= "0123456789abcdef";
  unsigned int      i;

  if (!(*result = (unsigned char *)malloc(binsz * 2 + 1)))
    return (NULL);

  (*result)[binsz * 2] = 0;

  if (!binsz)
    return (NULL);

  for (i = 0; i < binsz; i++)
    {
      (*result)[i * 2 + 0] = hex_str[(bin[i] >> 4) & 0x0F];
      (*result)[i * 2 + 1] = hex_str[(bin[i]     ) & 0x0F];
    }
  return (*result);
}

int                 main()
{
  //the calling
  unsigned char     buf[] = {0,1,10,11};
  unsigned char *   result;

  printf("result : %s\n", bin_to_strhex((unsigned char *)buf, sizeof(buf), &result));
  free(result);

  return 0
}

3
Questo codice contiene un bug che si manifesta solo su strani input non stampabili (non ho avuto il tempo di scavare esattamente cosa sta succedendo matematicamente). Prova a codificare il binario di esadecimale ca9e3c972f1c5db40c0b4a66ab5bc1a20ca4457bdbe5e0f8925896d5ed37d726e uscirai ÌaÌe3cÌ72f1c5dÌ40c0b4a66Ìb5bÌ1Ì20cÌ4457bÌbÌ5Ì0Ì8Ì258Ì6Ì5Ìd37Ì726. Per risolvere questo problema, il bit all'interno hex_strdella prima riga del ciclo for deve essere modificato (input[i] >> 4) & 0x0Fcome nella risposta di @ kriss. Allora funziona bene.
niemiro

Bug: non controlla l'errore malloc ().
Cecil Ward

È sempre meglio usare caratteri non firmati assolutamente ovunque poiché nessuno vuole il rischio di caratteri firmati (una caratteristica hardware DEC PDP11 folle), e in questo modo non corri il rischio che i confronti con segno vadano male o che i cambi di segno a destra corrompano i valori. In questo caso, per essere onesti, il codice fa difensivamente un & 0x0F ovunque che ti protegge qui.
Cecil Ward

Il parametro di input bin dovrebbe essere const unsigned char const * bin, per dichiarare la memoria come di sola lettura ai fini di questa routine.
Cecil Ward

1
Ho integrato le proposte di Cecil Ward, grazie per il feedback
Yannuth

14

Risposte simili esistono già sopra, ho aggiunto questa per spiegare come funziona esattamente la seguente riga di codice:

ptr += sprintf(ptr, "%02X", buf[i])

È abbastanza complicato e non facile da capire, ho messo la spiegazione nei commenti qui sotto:

uint8 buf[] = {0, 1, 10, 11};

/* Allocate twice the number of bytes in the "buf" array because each byte would
 * be converted to two hex characters, also add an extra space for the terminating
 * null byte.
 * [size] is the size of the buf array */
char output[(size * 2) + 1];

/* pointer to the first item (0 index) of the output array */
char *ptr = &output[0];

int i;

for (i = 0; i < size; i++) {
    /* "sprintf" converts each byte in the "buf" array into a 2 hex string
     * characters appended with a null byte, for example 10 => "0A\0".
     *
     * This string would then be added to the output array starting from the
     * position pointed at by "ptr". For example if "ptr" is pointing at the 0
     * index then "0A\0" would be written as output[0] = '0', output[1] = 'A' and
     * output[2] = '\0'.
     *
     * "sprintf" returns the number of chars in its output excluding the null
     * byte, in our case this would be 2. So we move the "ptr" location two
     * steps ahead so that the next hex string would be written at the new
     * location, overriding the null byte from the previous hex string.
     *
     * We don't need to add a terminating null byte because it's been already 
     * added for us from the last hex string. */  
    ptr += sprintf(ptr, "%02X", buf[i]);
}

printf("%s\n", output);

Logica brillante. Stavo cercando per un'ora un'elegante risposta di stringa non C ++ a questa sfida!
Mark Terrill

6

Volevo solo aggiungere quanto segue, anche se è leggermente fuori tema (non standard C), ma mi ritrovo a cercarlo spesso, e mi sono imbattuto in questa domanda tra i primi risultati di ricerca. La funzione di stampa del kernel Linux printk,, ha anche specificatori di formato per l'output di contenuti di array / memoria "direttamente" tramite un singolare specificatore di formato:

https://www.kernel.org/doc/Documentation/printk-formats.txt

Raw buffer as a hex string:
    %*ph    00 01 02  ...  3f
    %*phC   00:01:02: ... :3f
    %*phD   00-01-02- ... -3f
    %*phN   000102 ... 3f

    For printing a small buffers (up to 64 bytes long) as a hex string with
    certain separator. For the larger buffers consider to use
    print_hex_dump(). 

... tuttavia, questi specificatori di formato non sembrano esistere per lo spazio utente standard (s)printf.


4

Soluzione

La funzione btoxconverte i dati arbitrari *bbin una stringa non terminata *xpdi ncifre esadecimali:

void btox(char *xp, const char *bb, int n) 
{
    const char xx[]= "0123456789ABCDEF";
    while (--n >= 0) xp[n] = xx[(bb[n>>1] >> ((1 - (n&1)) << 2)) & 0xF];
}

Esempio

#include <stdio.h>

typedef unsigned char uint8;

void main(void) 
{
    uint8 buf[] = {0, 1, 10, 11};
    int n = sizeof buf << 1;
    char hexstr[n + 1];

    btox(hexstr, buf, n);
    hexstr[n] = 0; /* Terminate! */
    printf("%s\n", hexstr);
}

Risultato: 00010A0B.

Dal vivo: Tio.run .


1

Questo è un modo per eseguire la conversione:

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

#define l_word 15
#define u_word 240

char *hex_str[]={"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"};

main(int argc,char *argv[]) {


     char *str = malloc(50);
     char *tmp;
     char *tmp2;

     int i=0;


     while( i < (argc-1)) {
          tmp = hex_str[*(argv[i]) & l_word];
          tmp2 = hex_str[*(argv[i]) & u_word];

          if(i == 0) { memcpy(str,tmp2,1); strcat(str,tmp);}
          else { strcat(str,tmp2); strcat(str,tmp);}
          i++;
    }

    printf("\n*********  %s  *************** \n", str);

}

1

Versione Yannith leggermente modificata. È solo che mi piace averlo come valore di ritorno

typedef struct {
   size_t len;
   uint8_t *bytes;
} vdata;

char* vdata_get_hex(const vdata data)
{
   char hex_str[]= "0123456789abcdef";

   char* out;
   out = (char *)malloc(data.len * 2 + 1);
   (out)[data.len * 2] = 0;
   
   if (!data.len) return NULL;
   
   for (size_t i = 0; i < data.len; i++) {
      (out)[i * 2 + 0] = hex_str[(data.bytes[i] >> 4) & 0x0F];
      (out)[i * 2 + 1] = hex_str[(data.bytes[i]     ) & 0x0F];
   }
   return out;
}


1

Questa funzione è adatta dove l'utente / chiamante desidera che una stringa esadecimale venga inserita in un array / buffer di caratteri. Con una stringa esadecimale in un buffer di caratteri, l'utente / chiamante può utilizzare la propria macro / funzione per visualizzarla o registrarla in qualsiasi posizione desideri (ad esempio in un file). Questa funzione consente inoltre al chiamante di controllare il numero di byte (esadecimali) da inserire in ciascuna riga.

/**
 * @fn 
 * get_hex
 *
 * @brief 
 * Converts a char into bunary string 
 *
 * @param[in]   
 *     buf Value to be converted to hex string
 * @param[in]   
 *     buf_len Length of the buffer
 * @param[in]   
 *     hex_ Pointer to space to put Hex string into
 * @param[in]   
 *     hex_len Length of the hex string space
 * @param[in]   
 *     num_col Number of columns in display hex string
 * @param[out]   
 *     hex_ Contains the hex string
 * @return  void
 */
static inline void
get_hex(char *buf, int buf_len, char* hex_, int hex_len, int num_col)
{
    int i;
#define ONE_BYTE_HEX_STRING_SIZE   3
  unsigned int byte_no = 0;

  if (buf_len <= 0) {
      if (hex_len > 0) {
        hex_[0] = '\0';
      }
      return;
  }

  if(hex_len < ONE_BYTE_HEX_STRING_SIZE + 1)
  {
      return;
  }

  do {
         for (i = 0; ((i < num_col) && (buf_len > 0) && (hex_len > 0)); ++i )
         {
            snprintf(hex_, hex_len, "%02X ", buf[byte_no++] & 0xff);
            hex_ += ONE_BYTE_HEX_STRING_SIZE;
            hex_len -=ONE_BYTE_HEX_STRING_SIZE;
            buf_len--;
         }
         if (buf_len > 1)
         {
             snprintf(hex_, hex_len, "\n");
             hex_ += 1;
         }
  } while ((buf_len) > 0 && (hex_len > 0));

}

Esempio: codice

#define DATA_HEX_STR_LEN 5000
    char      data_hex_str[DATA_HEX_STR_LEN];

    get_hex(pkt, pkt_len, data_hex_str, DATA_HEX_STR_LEN, 16);
    //      ^^^^^^^^^^^^                                  ^^
    //      Input byte array                              Number of (hex) byte
    //      to be converted to hex string                 columns in hex string

    printf("pkt:\n%s",data_hex_str) 

PRODUZIONE

pkt:
BB 31 32 00 00 00 00 00 FF FF FF FF FF FF DE E5 
A8 E2 8E C1 08 06 00 01 08 00 06 04 00 01 DE E5 
A8 E2 8E C1 67 1E 5A 02 00 00 00 00 00 00 67 1E 
5A 01 

0

Non c'è una primitiva per questo in C. Probabilmente malloc (o forse alloca) un buffer abbastanza lungo e loop sull'input. L'ho anche visto fatto con una libreria di stringhe dinamiche con semantica (ma non sintassi!) Simile a quella del C ++ ostringstream, che è una soluzione plausibilmente più generica ma potrebbe non valere la complessità aggiuntiva solo per un singolo caso.


0

Se vuoi memorizzare i valori esadecimali in una char *stringa, puoi usare snprintf. È necessario allocare spazio per tutti i caratteri stampati, inclusi gli zeri iniziali e i due punti.

Espandendo la risposta di Mark:

char str_buf* = malloc(3*X + 1);   // X is the number of bytes to be converted

int i;
for (i = 0; i < x; i++)
{
    if (i > 0) snprintf(str_buf, 1, ":");
    snprintf(str_buf, 2, "%02X", num_buf[i]);  // need 2 characters for a single hex value
}
snprintf(str_buf, 2, "\n\0"); // dont forget the NULL byte

Quindi ora str_bufconterrà la stringa esadecimale.


questo sovrascrive i primi 2 caratteri più e più volte .. giusto?
xordon

0

La soluzione di ZincX adattata per includere i delimitatori dei due punti:

char buf[] = {0,1,10,11};
int i, size = sizeof(buf) / sizeof(char);
char *buf_str = (char*) malloc(3 * size), *buf_ptr = buf_str;
if (buf_str) {
  for (i = 0; i < size; i++)
    buf_ptr += sprintf(buf_ptr, i < size - 1 ? "%02X:" : "%02X\0", buf[i]);
  printf("%s\n", buf_str);
  free(buf_str);
}

0

Aggiungerò qui la versione C ++ per chiunque sia interessato.

#include <iostream>
#include <iomanip>
inline void print_bytes(char const * buffer, std::size_t count, std::size_t bytes_per_line, std::ostream & out) {
    std::ios::fmtflags flags(out.flags()); // Save flags before manipulation.
    out << std::hex << std::setfill('0');
    out.setf(std::ios::uppercase);
    for (std::size_t i = 0; i != count; ++i) {
        auto current_byte_number = static_cast<unsigned int>(static_cast<unsigned char>(buffer[i]));
        out << std::setw(2) << current_byte_number;
        bool is_end_of_line = (bytes_per_line != 0) && ((i + 1 == count) || ((i + 1) % bytes_per_line == 0));
        out << (is_end_of_line ? '\n' : ' ');
    }
    out.flush();
    out.flags(flags); // Restore original flags.
}

Stamperà il dump esadecimale della bufferlunghezza countsu std::ostream out(puoi impostarlo come predefinito std::cout). Ogni riga conterrà bytes_per_linebyte, ogni byte è rappresentato utilizzando due cifre esadecimali maiuscole. Ci sarà uno spazio tra i byte. E alla fine della riga o alla fine del buffer stamperà una nuova riga. Se bytes_per_lineè impostato su 0, non stamperà new_line. Prova tu stesso.


0

Per un utilizzo semplice ho creato una funzione che codifica la stringa di input (dati binari):

/* Encodes string to hexadecimal string reprsentation
    Allocates a new memory for supplied lpszOut that needs to be deleted after use
    Fills the supplied lpszOut with hexadecimal representation of the input
    */
void StringToHex(unsigned char *szInput, size_t size_szInput, char **lpszOut)
{
    unsigned char *pin = szInput;
    const char *hex = "0123456789ABCDEF";
    size_t outSize = size_szInput * 2 + 2;
    *lpszOut = new char[outSize];
    char *pout = *lpszOut;
    for (; pin < szInput + size_szInput; pout += 2, pin++)
    {
        pout[0] = hex[(*pin >> 4) & 0xF];
        pout[1] = hex[*pin & 0xF];
    }
    pout[0] = 0;
}

Utilizzo:

unsigned char input[] = "This is a very long string that I want to encode";
char *szHexEncoded = NULL;
StringToHex(input, strlen((const char *)input), &szHexEncoded);

printf(szHexEncoded);

// The allocated memory needs to be deleted after usage
delete[] szHexEncoded;

0

Basato sulla risposta di Yannuth ma semplificato.

Qui, la lunghezza di dest[]è implicita il doppio di lene la sua allocazione è gestita dal chiamante.

void create_hex_string_implied(const unsigned char *src, size_t len, unsigned char *dest)
{
    static const unsigned char table[] = "0123456789abcdef";

    for (; len > 0; --len)
    {
        unsigned char c = *src++;
        *dest++ = table[c >> 4];
        *dest++ = table[c & 0x0f];
    }
}

0

So che questa domanda ha già una risposta, ma penso che la mia soluzione potrebbe aiutare qualcuno.

Quindi, nel mio caso, avevo un array di byte che rappresenta la chiave e avevo bisogno di convertire questo array di byte in un array di caratteri esadecimali per stamparlo in una riga. Ho estratto il mio codice in una funzione come questa:

char const * keyToStr(uint8_t const *key)
{
    uint8_t offset = 0;
    static char keyStr[2 * KEY_SIZE + 1];

    for (size_t i = 0; i < KEY_SIZE; i++)
    {
        offset += sprintf(keyStr + offset, "%02X", key[i]);
    }
    sprintf(keyStr + offset, "%c", '\0');

    return keyStr;
}

Ora posso usare la mia funzione in questo modo:

Serial.print("Public key: ");
Serial.println(keyToStr(m_publicKey));

Serialobject fa parte della libreria Arduino ed m_publicKeyè membro della mia classe con la seguente dichiarazione uint8_t m_publicKey[32].


0

Puoi risolvere con snprintf e malloc.

char c_buff[50];

u8_number_val[] = { 0xbb, 0xcc, 0xdd, 0x0f, 0xef, 0x0f, 0x0e, 0x0d, 0x0c };

char *s_temp = malloc(u8_size * 2 + 1);

for (uint8_t i = 0; i < u8_size; i++)
{
    snprintf(s_temp  + i * 2, 3, "%02x", u8_number_val[i]);
}

snprintf(c_buff, strlen(s_temp)+1, "%s", s_temp );

printf("%s\n",c_buff);

free(s);

FUORI: bbccdd0fef0f0e0d0c


-2

Che soluzioni complesse!
Malloc e sprint e lanci oh mio. (Citazione di OZ)
e non un singolo rem da nessuna parte. Accidenti, che ne

dici di qualcosa di simile?

main()
{
    // the value
    int value = 16;

    // create a string array with a '\0' ending ie. 0,0,0
    char hex[]= {0,0,'\0'}; 
    char *hex_p=hex;

    //a working variable
    int TEMP_int=0;

    // get me how many 16s are in this code
    TEMP_int=value/16;

    // load the first character up with 
    // 48+0 gives you ascii 0, 55+10 gives you ascii A
    if (TEMP_int<10) {*hex_p=48+TEMP_int;}
        else {*hex_p=55+TEMP_int;}

    // move that pointer to the next (less significant byte)<BR>
    hex_p++;

    // get me the remainder after I have divied by 16
    TEMP_int=value%16;

    // 48+0 gives you ascii 0, 55+10 gives you ascii A
    if (TEMP_int<10) {*hex_p=48+TEMP_int;}
        else {*hex_p=55+TEMP_int;}

    // print the result
    printf("%i , 0x%s",value,hex);

}

OK, ora hai due cifre esadecimali. Resta da aggiungere separatori e occuparsi degli altri byte da convertire. Forse con un ciclo? Rendilo una funzione e avrai qualcosa di simile al mio (ma piuttosto prolisso e difficile da leggere). Forse dovresti almeno finire il lavoro prima di chiamare i nomi su altri poster?
kriss

1
E una parola sui commenti nel codice sorgente (non REM, questa è la parola chiave BASIC per i commenti, per favore evitatela): i commenti che dicono in inglese quello che sta facendo il codice sono una pessima pratica! Sì, i programmatori dovrebbero sapere cosa significano gli operatori modulo (dare i resti) e quella divisione conta il numero di volte in cui un numero appare in un altro ... e che printf stampa il risultato. Oh mio!
kriss
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.