Konversi hex ke biner dari argumen baris perintah C

Ini adalah pekerjaan rumah di mana saya harus mengubah hex ke biner ketika sebuah perintah dipanggil di terminal. "Guru" saya tidak benar-benar "mengajar" C jadi saya bingung. Saya harus menyertakan prosedur, void printBits (unsigned long i), yang mencetak bit di i. Ini akan dipanggil dari baris perintah menggunakan saklar '-p' diikuti dengan bilangan bulat panjang 32-bit yang tidak ditandatangani dalam bentuk hex. Contoh: $lab3 -p 0x5

Keluaran: 0000 0000 0000 0000 0000 0000 0000 0101

Tolong jangan hanya memberi saya kodenya. Saya perlu memahami ini.

void printBits(unsigned long number) {
    // Declare Array to hold our binary number
    char binaryNumber[32];
    // For Loop Index
    int i;
    for (i = 31; i >= 0; --i)
    {
    binaryNumber[i] = (number & 1);
    number >>= 1;
    }

person DNH    schedule 19.02.2016    source sumber
comment
Tolong jangan hanya memberi saya kodenya. Saya perlu memahami ini. OKE.   -  person 4pie0    schedule 19.02.2016
comment
Apa yang kamu punya sejauh ini?   -  person    schedule 19.02.2016
comment
Diedit untuk menunjukkan apa yang saya miliki. Tidak tahu ke mana harus pergi setelah itu   -  person DNH    schedule 19.02.2016
comment
Yang terbaik adalah memberikan keseluruhan program (sebaiknya yang dikompilasi) agar kami dapat membantu Anda dengan sebaik-baiknya. Tunjukkan semuanya kepada kami, bukan hanya fungsi printBits() karena Anda memiliki beberapa masalah yang harus diselesaikan, bukan hanya manipulasi biner. Anda juga harus mengambil argumen baris perintah, menguraikannya untuk memastikan kebenarannya, dan kemudian mengubahnya menjadi bilangan bulat. Guru Anda sering bertanya kepada Anda apakah dia tidak bersedia membantu Anda.   -  person    schedule 19.02.2016
comment
Berikut petunjuknya, lihat fungsi berikut di perpustakaan C: putchar(), strcmp(), sscanf(). Ini akan memungkinkan Anda menyelesaikan semua masalah yang telah ditetapkan guru untuk Anda. Terakhir, untuk menangani argumen baris perintah, Anda harus menggunakan parameter argc dan argv di fungsi main() Anda, parameter ini banyak digunakan dan dapat dicari di Google dengan mudah.   -  person    schedule 19.02.2016
comment
Maaf aku bahkan belum memulai hal lain. Saya baru saja mencoba memahami cara melakukan fungsi printBits dan Google belum terlalu banyak membantu. Saya mungkin mencari di tempat yang salah   -  person DNH    schedule 19.02.2016
comment

Agak tidak jelas apa masalah Anda. Mungkin saja Anda memiliki beberapa paket yang tidak kompatibel. Untuk menghindari masalah seperti ini, saya merekomendasikan penggunaan Anaconda: https://anaconda.org

Itu akan datang dengan python dan sebagian besar perpustakaan dasar, termasuk matplotlib. Saya juga dapat merekomendasikan seaborn untuk plot yang terlihat profesional dan tidak memerlukan banyak kode.

  -  person DNH    schedule 19.02.2016
comment
Masalah ini tidak terlalu sulit. Apa yang perlu Anda pahami adalah ketika Anda menggeser angka, mengulang 0-size Anda mendapatkan bit dalam urutan host-byte sehingga bit pertama yang Anda geser adalah bit paling tidak signifikan pada perangkat keras little-endian. Anda dapat mengatasinya dengan beberapa cara, mengindeks posisi karakter dalam array Anda dari tinggi ke rendah untuk memperbaiki masalah, atau Anda dapat melakukan pergeseran yang lebih besar terlebih dahulu (misalnya n >> size - 1) dan menulis bit dalam urutan normal. Setelah Anda memahami kekhasan itu, pengkodeannya menjadi mudah.   -  person David C. Rankin    schedule 19.02.2016
comment
@DNH, Anda berhak mengeluh jika guru Anda tidak melakukan tugasnya. Saya berharap saya memiliki internet ketika saya masih di sekolah. Stack overflow adalah tempat yang bagus untuk belajar dengan cepat dan sangat bagus jika Anda benar-benar ingin belajar pemrograman. Saya belajar C secara otodidak dan sudah lama menjadi programmer profesional, jadi itu benar-benar bisa dicapai.   -  person    schedule 19.02.2016
comment
@DavidC.Rankin, urutan byte host tidak relevan jika Anda menggunakan tipe data int unsigned untuk menyimpan nilai. Yang terpenting hanyalah menggeser ke arah yang benar dan menguji bit yang benar.   -  person    schedule 19.02.2016
comment
Anda benar, saya berpikir lebih cepat bahwa saya seharusnya melakukannya. Tujuannya adalah untuk menjelaskan mengapa menarik bit dengan pergeseran yang lebih rendah menghasilkan posisi bit yang lebih tinggi dalam representasi biner.   -  person David C. Rankin    schedule 19.02.2016


Jawaban (4)


Ada sejumlah cara untuk mendekati pencetakan representasi biner untuk bilangan apa pun. Pertama, Anda cukup menampilkan hasil operasi shift dan indeks secara langsung (ke stdout, file, dll...) Tampaknya ini adalah pendekatan yang Anda mulai, tetapi kemudian Anda mendeklarasikan buffer 32 bit. Meskipun Anda pasti bisa melakukan itu, tidak perlu melakukan buffering pada hasilnya jika Anda tidak ingin mengembalikan pointer ke buffer yang telah selesai. (yang membawa saya ke poin ketiga saya, di bawah)

Mengeluarkan bit secara sederhana tanpa menyimpan/mengembalikan pointer ke bit dalam string nul-terminated, ada tempatnya tetapi umumnya penggunaannya terbatas. Namun demikian, ini adalah masalah umum yang mencakup dasar-dasar semua pendekatan. Membuat representasi biner tanpa bantalan dapat dilakukan sebagai berikut:

/** unpadded binary representation of 'v'. */
void binprn (const unsigned long v)
{
    if (!v)  { putchar ('0'); return; };  /* if v = 0 output '0' */

    size_t sz = sizeof v * CHAR_BIT;  /* get the number of bits in v */
    unsigned long rem = 0;        /* variable to hold shifted result */

    while (sz--)               /* for each bit (in decreasing order) */
        if ((rem = v >> sz))   /* if bits exist in the shifted value */
            putchar ((rem & 1) ? '1' : '0');    /* output '1' or '0' */
}

Komentarnya cukup menjelaskan. Skemanya adalah dengan menggeser setiap bit yang dimulai dengan bit paling signifikan (misalnya bit 31 (31-0) untuk nomor 32-bit. Anda memeriksa apakah ada 1-bit setelah pergeseran tersebut (jika tidak, pergeserannya melebihi yang paling banyak). posisi bit yang signifikan dalam angka dan tidak ada yang perlu dicetak). Begitu ada bit yang ditemukan di rem, akan selalu ada bit-bit yang harus dicetak sepanjang sisa iterasi perulangan karena Anda menggeser dengan jumlah yang semakin berkurang. Dengan memulai dari bit paling signifikan (yang dicetak pertama kali), bit Anda akan dicetak dalam urutan yang benar dan hanya mencetak jumlah bit yang membentuk nomor tersebut.

Umumnya ketika Anda hanya mengeluarkan representasi biner langsung ke layar, Anda hanya ingin mengeluarkan bit hingga bit paling signifikan. (yang mencegah keluaran 1 dengan 63 0 di depannya sehingga membuat segalanya berantakan.)

Selanjutnya, mengeluarkan representasi biner berlapis ke sejumlah bit. Ini berguna jika Anda hanya ingin melihat 8, 16, 32, ... bit terbawah dalam angka berapa pun, namun menginginkan representasi dengan jumlah bit tetap setiap saat. Di sini Anda cukup memasukkan jumlah bit yang ingin Anda lihat. Fungsi Anda kemudian akan mengulang jumlah posisi bit dalam nomor Anda dan menampilkan hasilnya:

/** binary representation of 'v' padded to 'sz' bits.
 *  the padding amount is limited to the number of
 *  bits in 'v'. valid range: 0 - sizeof v * CHAR_BIT.
 */
void binprnpad (const unsigned long v, size_t sz)
{
    if (!sz) putchar ((v & 1) ? '1' : '0');  /* if no sz, '0' is fine */

    if (sz > sizeof v * CHAR_BIT)  /* if sz exceed # of bits, limit   */
        sz = sizeof v * CHAR_BIT;

    while (sz--)  /* for sz positions in decreasing order, '1' or '0' */
        putchar ((v >> sz & 1) ? '1' : '0');
}

Anda akan melihat perbedaan utama di sini adalah Anda tidak perlu repot memeriksa apakah masih ada bit untuk mencegah pencetakan angka nol di depan yang tidak diinginkan, karena Anda mengontrol jumlah bit dengan parameter sz. (terserah Anda apa yang Anda lakukan jika ukuran 0 dilewati, saya hanya memilih untuk menampilkan '0')

Sekarang untuk poin ketiga yang disebutkan di atas. Mengeluarkan bit saja sudah rumit dari sudut pandang pemformatan di bagian utama kode Anda. Saya merasa jauh lebih berguna untuk menyimpan bit dalam array karakter (nul-terminated sehingga dapat diperlakukan sebagai string) dan mengembalikan pointer ke array sehingga dapat diteruskan ke printf, dll Sekarang Anda harus memasukkan array berukuran cukup sebagai parameter, mendeklarasikan array static sehingga array tidak dimusnahkan saat fungsi dikembalikan, atau secara dinamis mengalokasikan penyimpanan untuk array di dalam fungsi. Semuanya memiliki kelebihan dan kekurangan yang harus Anda pertimbangkan tergantung pada kebutuhan kode Anda. misalnya.:

/** returns pointer to binary representation of 'v' zero padded to 'sz'.
 *  returns pointer to string contianing binary representation of
 *  unsigned 64-bit (or less ) value zero padded to 'sz' digits.
 */
char *binpad (const unsigned long v, const size_t sz)
{
    static char s[BITS_PER_LONG + 1] = {0};
    char *p = s + BITS_PER_LONG;
    register size_t i;

    for (i = 0; i < sz; i++)
        *--p = (v>>i & 1) ? '1' : '0';

    return p;
}

Kode berfungsi sama dengan kode empuk non-buffer di atas. Perhatikan bagaimana p mengembalikan posisi awal dalam buffer di mana sz jumlah bit dimulai. Perhatikan juga bahwa Anda memerlukan konstanta untuk BITS_PER_LONG yang menunjukkan jumlah bit dalam long pada perangkat keras Anda. (yang biasanya ditangani dengan cara yang mirip dengan BUILD_64)

catatan: perlu diketahui bahwa salah satu batasan pada deklarasi static adalah fungsi konversi hanya dapat digunakan sekali dalam satu panggilan printf (atau dalam satu baris kode) karena hanya ada satu larik penyimpanan untuk konversi biner. (Anda selalu dapat melakukan sejumlah panggilan dan menyimpan hasilnya di lokasi berbeda sebelum melakukan panggilan printf)

Salah satu variasi terakhir pada cetakan biner adalah cetakan representasi dengan pemisah yang disertakan untuk membuatnya lebih mudah untuk mengidentifikasi dan membandingkan antara string biner (terutama ketika berhadapan dengan urutan 0 dan 1 yang lebih panjang. Misalnya:

hexval : 0xdeadbeef  =>  11011110-10101101-10111110-11101111

Fungsinya pada dasarnya bekerja sama seperti binpad di atas, tetapi dengan tambahan bahwa buffer statis lebih besar untuk mengakomodasi pemisah dan pemeriksaan tambahan pada posisi bit untuk menentukan kapan pemisah harus ditambahkan ke buffer:

/** returns pointer to formatted binary representation of 'v' zero padded to 'sz'.
 *  returns pointer to string contianing formatted binary representation of
 *  unsigned 64-bit (or less ) value zero padded to 'sz' digits with char
 *  'sep' placed every 'szs' digits. (e.g. 10001010 -> 1000-1010).
 */
char *binfmt (const unsigned long v, const unsigned char sz, 
            const unsigned char szs, const char sep)
{
    static char s[BITS_PER_LONG * 2 + 1] = {0};
    char *p = s + 2 * BITS_PER_LONG;
    register size_t i;

    *p = 0;
    for (i = 0; i < sz; i++) {
        p--;
        if (i > 0 && szs > 0 && i % szs == 0)
            *p-- = sep;
        *p = (v >> i & 1) ? '1' : '0';
    }

    return p;
}

Masalah Anda yang tersisa hanyalah memproses argumen baris perintah, dan melakukan konversi dari string input ke nilai yang tidak ditandatangani bersama dengan pemeriksaan validasi bahwa jumlahnya tidak melebihi 32-bit, dll. Anda dapat memproses argumen dengan getops atau untuk sejumlah kecil opsi sederhana Anda cukup menggunakan loop. Di Linux, satu-satunya argumen wajib yang harus ditanggapi oleh kode Anda adalah -h untuk bantuan dan -v untuk versi. Meskipun tidak ada yang melakukan ini untuk contoh singkat, dll., setidaknya menyenangkan untuk memiliki informasi tersebut. Lihat contoh berikut yang menggabungkan semua bagian dan beri tahu saya jika Anda memiliki pertanyaan:

#include <stdio.h>
#include <stdlib.h> /* for strtoul */
#include <errno.h>  /* for errno   */
#include <limits.h> /* for UINT_MAX, ULONG_MAX, CHAR_BIT */

#define PACKAGE "hex2bin"
#define VERSION "0.01"

/* BUILD_64 - Check x86/x86_64 */
#if defined(__LP64__) || defined(_LP64)
# define BUILD_64   1
#endif

/* BITS_PER_LONG */
#ifdef BUILD_64
# define BITS_PER_LONG 64
#else
# define BITS_PER_LONG 32
#endif

unsigned long processopts (int argc, char **argv);
unsigned long xstrtoul (char *s);
void binprn (const unsigned long v);
void binprnpad (const unsigned long v, size_t sz);
char *binpad (const unsigned long v, const size_t sz);
char *binfmt (const unsigned long v, const unsigned char sz, 
            const unsigned char szs, const char sep);
void help (int xcode);

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

    unsigned long hexval = processopts (argc, argv);

    /* print unpadded binary */
    printf ("\n hexval : 0x%lx (%lu)  =>  ", hexval, hexval);
    binprn (hexval);
    printf ("\n");

    /* print padded to 32-bits */
    printf ("\n hexval : 0x%lx (%lu)  =>  ", hexval, hexval);
    binprnpad (hexval, sizeof (int) * CHAR_BIT);
    printf ("\n");

    /* padded binary returned as formatted string
     * with '-' separators every 8 bits
     */
    printf ("\n hexval : 0x%lx (%lu)  =>  %s\n\n", hexval, hexval,
            binfmt (hexval, sizeof (int) * CHAR_BIT, CHAR_BIT, '-'));

    return 0;
}

/* quick custom argument handler */
unsigned long processopts (int argc, char **argv)
{
    size_t i = 1;
    unsigned long val = 0;

    if (argc < 2) help (0);         /* insufficient arguments       */

    for (; argv[i]; i++) {          /* for each argument            */
        if (*argv[i] == '-') {      /* for each beginning with '-'  */
            switch (argv[i][1]) {
                case 'h':           /* respond to '-h' help         */
                    help (0);
                case 'p':           /* handle '-p' convert value    */
                    if (!argv[i+1]) {   /* if '-p' w/o next arg     */
                        fprintf (stderr, "error: insufficient input.\n");
                        help (1);
                    }
                    if (*argv[i+1] != '0' || /* validate hex input  */
                        (argv[i+1][1] != 'x' && argv[i+1][1] != 'X')) {
                        fprintf (stderr, "error: invalid 'hex_value' input.\n");
                        help (1);                    
                    }
                    val = xstrtoul (argv[i+1]); /* convert to ulong */
                    if (val > UINT_MAX) {       /* validate 32-bits */
                        fprintf (stderr, "error: input value exceeds 32-bits.\n");
                        help (1);
                    }
                    break;
                case 'v':           /* respond to '-v' version      */
                    printf ("%s, version %s\n", PACKAGE, VERSION);
                    exit (0);
                default :
                    fprintf (stderr, "error: invalid/unrecognized option '%s'.\n",
                            argv[i]);
                    help (1);
            }
        }
    }
    return val; /* return val */
}

unsigned long xstrtoul (char *s)
{
    unsigned long v = 0;
    errno = 0;

    /* test for hex or decimal conversion */
    if (*s == '0' && (s[1] == 'x' || s[1] == 'X'))
        v = strtoul (s, NULL, 16);
    else
        v = strtoul (s, NULL, 10);

    /* check for various possible errors */
    if ((errno == ERANGE && v == ULONG_MAX) || (errno != 0 && v == 0)) {
        perror ("strtoul");
        exit (EXIT_FAILURE);
    }
    return v;
}

/** unpadded binary representation of 'v'. */
void binprn (const unsigned long v)
{
    if (!v)  { putchar ('0'); return; };

    size_t sz = sizeof v * CHAR_BIT;
    unsigned long rem = 0;

    while (sz--)
        if ((rem = v >> sz))
            putchar ((rem & 1) ? '1' : '0');
}

/** binary representation of 'v' padded to 'sz' bits.
 *  the padding amount is limited to the number of
 *  bits in 'v'. valid range: 0 - sizeof v * CHAR_BIT.
 */
void binprnpad (const unsigned long v, size_t sz)
{
    if (!sz) putchar ((v & 1) ? '1' : '0');

    if (sz > sizeof v * CHAR_BIT)
        sz = sizeof v * CHAR_BIT;

    while (sz--)
        putchar ((v >> sz & 1) ? '1' : '0');
}

/** returns pointer to binary representation of 'v' zero padded to 'sz'.
 *  returns pointer to string contianing binary representation of
 *  unsigned 64-bit (or less ) value zero padded to 'sz' digits.
 */
char *binpad (const unsigned long v, const size_t sz)
{
    static char s[BITS_PER_LONG + 1] = {0};
    char *p = s + BITS_PER_LONG;
    register size_t i;

    for (i = 0; i < sz; i++)
        *--p = (v>>i & 1) ? '1' : '0';

    return p;
}

/** returns pointer to formatted binary representation of 'v' zero padded to 'sz'.
 *  returns pointer to string contianing formatted binary representation of
 *  unsigned 64-bit (or less ) value zero padded to 'sz' digits with char
 *  'sep' placed every 'szs' digits. (e.g. 10001010 -> 1000-1010).
 */
char *binfmt (const unsigned long v, const unsigned char sz, 
            const unsigned char szs, const char sep)
{
    static char s[BITS_PER_LONG * 2 + 1] = {0};
    char *p = s + 2 * BITS_PER_LONG;
    register size_t i;

    *p = 0;
    for (i = 0; i < sz; i++) {
        p--;
        if (i > 0 && szs > 0 && i % szs == 0)
            *p-- = sep;
        *p = (v >> i & 1) ? '1' : '0';
    }

    return p;
}

void help (int xcode)
{
    xcode = xcode ? xcode : 0;  /* set default exit code */

    printf ("\n %s, version %s\n\n"
            "  usage:  %s -p hex_value (32-bit)\n\n"
            "  converts 'hex_value' to its binary representation.\n\n"
            "    Options:\n\n"
            "      -h            this help.\n"
            "      -p hex_value  display binary representation of 'hex_value'.\n"
            "      -v            display version information.\n\n",
            PACKAGE, VERSION, PACKAGE);

    exit (xcode);
}

Penggunaan/Keluaran

$ ./bin/hex2bin -p 0xe7

 hexval : 0xe7 (231)  =>  11100111

 hexval : 0xe7 (231)  =>  00000000000000000000000011100111

 hexval : 0xe7 (231)  =>  00000000-00000000-00000000-11100111


$ ./bin/hex2bin -p 0xdeadbeef

 hexval : 0xdeadbeef (3735928559)  =>  11011110101011011011111011101111

 hexval : 0xdeadbeef (3735928559)  =>  11011110101011011011111011101111

 hexval : 0xdeadbeef (3735928559)  =>  11011110-10101101-10111110-11101111


$ ./bin/hex2bin -h

 hex2bin, version 0.01

  usage:  hex2bin -p hex_value (32-bit)

  converts 'hex_value' to its binary representation.

    Options:

      -h            this help.
      -p hex_value  display binary representation of 'hex_value'.
      -v            display version information.


$ ./bin/hex2bin -v
hex2bin, version 0.01
person David C. Rankin    schedule 19.02.2016

Setiap jumlah disimpan dalam mesin sebagai serangkaian bit. Untuk mencetaknya ke konsol, Anda perlu meneruskan string yang setiap karakternya adalah 1 (0x31) atau 0 (0x30) tergantung pada apakah bit yang sesuai dalam angka diatur. Dan karakter terakhir HARUS '\0' untuk menandakan akhir string.

Setelah Anda menyiapkan buffer karakter, mencetaknya ke konsol dapat dilakukan menggunakan mis. fprintf:

fprintf(stdout, "%s\n", binaryNumber); // (maybe use stderr)

dengan sedikit koreksi pada kode Anda untuk memastikan string dihentikan NULL (memiliki '\0' sebagai karakter terakhir dalam buffer) dan Anda memasukkan karakter ke dalam buffer (jika tidak, 1 dan 0 yang bukan karakter yang dapat dicetak dimasukkan ke dalam buffer dan Anda akan melihat tidak ada keluaran sama sekali):

void
hex_to_bin_print(unsigned long number)
{
    char binaryNumber[33];
    int i;
    for (i = 31; i >= 0; --i)
    {
        binaryNumber[i] = (number & 1) ? '1' : '0';
        number >>= 1;
    }
    binaryNumber[32] = '\0';
    fprintf(stdout, "Number %s\n", binaryNumber);
}

int main(void) {
    hex_to_bin_print(1);
    hex_to_bin_print(2);
    hex_to_bin_print(15);
    hex_to_bin_print(127);
    hex_to_bin_print(256);
    hex_to_bin_print(12345);
    return 0;
}

cetakan:

Nomor 00000000000000000000000000000001

Nomor 000000000000000000000000000000010

Nomor 00000000000000000000000000001111

Nomor 00000000000000000000000001111111

Nomor 00000000000000000000000100000000

Nomor 00000000000000000011000000111001

person 4pie0    schedule 19.02.2016
comment
apa tujuan dari ? '1' : '0'; apa yang sedang dilakukannya? - person DNH; 19.02.2016
comment
@DNH jika tidak, 1 dan 0 yang bukan karakter yang dapat dicetak dimasukkan ke dalam buffer dan Anda tidak akan melihat keluaran sama sekali - apakah Anda mencobanya? - person 4pie0; 19.02.2016
comment
?: adalah cara singkat untuk melakukan pernyataan if. kondisi? jika_benar : jika_salah. Jika mau, Anda bisa menggunakan pernyataan if/else biasa. Banyak orang lebih memilih ?: tapi itu tidak terlalu penting. - person ; 19.02.2016

Pertama Anda mengonversi string yang Anda dapatkan dari baris perintah menjadi integer, paling sederhana adalah menggunakan sscanf

e.g.

if ( sscanf( argv[1], "%X", &n ) == 1)
{
  ...

sekarang Anda memiliki nilai desimal n.

Untuk mengonversi ke biner, Anda harus melewati setiap bit dalam bilangan bulat yang tidak ditandatangani.

Dengan melakukan bitwise-dan dengan nilai desimal Anda dapat memeriksa setiap bit apakah sudah disetel dan mencetak '1' atau '0' tergantung pada bitnya

for (int i = 0; i < 32; ++i)
{
   unsigned int mask = 0x8000 >> i; // this bit we check
   char ch = (n & mask) ? '1' : '0'; // see if it is set or not
   ...
}
person AndersK    schedule 19.02.2016

Inilah salah satu tampilan program Anda. Saya telah mengomentari bagian-bagian penting, tetapi Anda harus melihat dokumentasi fungsi-fungsi yang digunakan. Jika Anda menggunakan linux (sepertinya Anda menilai dari pertanyaan awal) maka Anda dapat menggunakan "halaman manual" linux seperti man sscanf untuk memberikan info lengkap tentang sscanf atau fungsi lainnya di perpustakaan C.

Kompilasi dengan: gcc main.c -o lab3

/* main.c */
#include <stdio.h> //provides putchar()
#include <strings.h> //provides sscanf() and strcmp()
#include <stdlib.h> //provides EXIT_x values

void printBits(unsigned long i)
{
  int j; //define a loop counter

  for(j = 0 ; j < 32 ; j++)
  {
    //test the highest bit and write a 1 or a 0
    //(we always test the highest bit but we shift the number along each time)
    putchar(i & 0x80000000 ? '1' : '0');

    //shift the bits along by one ready for the next loop iteration
    i <<= 1;

    //print a space after every 4th bit to break it up into nybbles
    if((j % 4) == 3)
      putchar(' ');
  }

  //finish the output in a tidy manner by writin a newline
  putchar('\n');
}


//a helpful function to assist the user
void usage(const char* progname)
{
  //show the user the proper way to run the program
  printf("%s -p 0x1234abcd\n", progname);
}

//this version of the main() signature gives access to commandline arguments
int main(int argc, char** argv)
{
  //flag to show the commandline arguments are in the wrong format
  int badargs = 0;

  //variable to store the 32 bit number given by the user
  unsigned long value;

  if(argc == 3) //do we have the right number of commandline arguments?
    if(strcmp(argv[1], "-p") == 0) //is argv[1] equal to "-p" ?
      if(sscanf(argv[2], "0x%x", &value) == 1) //is the number formatted like hex?
        printBits(value); //success, user input was good, print the bits!
      else
        badargs = 1; //the integer was not properly formatted as hexadecimal like 0x1234
    else
      badargs = 1; //argv[1] was not "-p"
  else
    badargs = 1; //wrong number of args given by user

  if(badargs) //we detected bad argument syntax earlier so we'd better remind the user what to do
  {
    printf("Incorrect argument syntax\n\n\t");
    usage(argv[0]); //argv[0] is the name of your executable program file ("lab3" in your case)
    putchar('\n');
    return EXIT_FAILURE;
  }

  return EXIT_SUCCESS;
}

Saya sendiri yang menulis ini, tetapi ada banyak contoh "latihan pengajaran" semacam ini di web, jadi menurut saya tidak terlalu spoiler jika hanya menyertakan kode kata demi kata di sini.

person Community    schedule 19.02.2016