为什么十进制小数中的最后一个数字不会转换为二进制?

时间:2016-09-07 16:04:10

标签: c

#include<stdio.h>
#include<string.h>
#include <math.h>
long long convertDecimalToBinary(int n);

int main() {
    int verify;
    long long  bip, dip;
    char str1[100];
    printf("Enter dotted decimal ip address :\n");
    scanf("%s",str1);
    verify = bin_verify(str1);

        seperate(str1); 

    return 0;

}
int bin_verify(char str1[]) {
    int i;
    for(i = 0; i < strlen(str1); i++) {
        if((str1[i] < 255) && (str1[i] > 0)) {
            return 1;
        }
    }
}

// function to get first decimal no sepreted

int seperate(char str1[]) {
    int s1, s2, s3, s4;
    int i, j, k = 0, m, cnt = 0, cnt1 = 0, pos = 0;
    char a[4], str2[100];
    for(i = 0; i < strlen(str1); i++) {
        pos = cnt;
        if(str1[i] == '.') {
            k = i;
            pos = cnt;
            for(j = 0; j < i; j++) {
                a[j] = str1[k-cnt];
                cnt = cnt - 1;
            }
        break;
        }
        else {
            cnt++;
            //goto one;
        }

    }
    for(m = 0; m <= pos; m++) {
        str1++;
    }
    s1 = atoi(a);
    s1 = convertDecimalToBinary(s1);
    printf("Binary Format of IP :\n");
    printf("%d.",s1);
    seperate2(str1);
    return 0;
}




 // function to get second decimal no sepreted
int seperate2(char str1[]) {
    int s1, s2, s3, s4;
    int i, j, k = 0, m, cnt = 0, cnt1 = 0, pos = 0;
    char a[4], str2[100];
    for(i = 0; i < strlen(str1); i++) {
        pos = cnt;
        if(str1[i] == '.') {
            k = i;
            pos = cnt;
            for(j = 0; j < i; j++) {
                a[j] = str1[k-cnt];
                cnt = cnt - 1;
            }
        break;
        }
        else {
            cnt++;
            //goto one;
        }

    }
    for(m = 0; m <= pos; m++) {
        str1++;
    }
    s2 = atoi(a);
    s2 = convertDecimalToBinary(s2);
    printf("%d.",s2);
    seperate3(str1);
    return 0;
}


// function to get third decimal no sepreted

int seperate3(char str1[]) {
    int s1, s2, s3, s4;
    int i, j, k = 0, m, cnt = 0, cnt1 = 0, pos = 0;
    char a[4], str2[100];
    for(i = 0; i < strlen(str1); i++) {
        pos = cnt;
        if(str1[i] == '.') {
            k = i;
            pos = cnt;
            for(j = 0; j < i; j++) {
                a[j] = str1[k-cnt];
                cnt = cnt - 1;
            }
        break;
        }
        else {
            cnt++;
            //goto one;
        }

    }
    for(m = 0; m <= pos; m++) {
        str1++;
    }
    s3 = atoi(a);
    s3 = convertDecimalToBinary(s3);
    printf("%d.",s3);
    seperate4(str1);
    return 0;
}

// function to get fourth decimal no sepreted

int seperate4(char str1[]) {
    int s1, s2, s3, s4;
    int i, j, k = 0, m, cnt = 0, cnt1 = 0, pos = 0;
    char a[4], str2[100];
    for(i = 0; i < strlen(str1); i++) {
        pos = cnt;
        if(str1[i] == '.') {
            k = i;
            pos = cnt;
            for(j = 0; j < i; j++) {
                a[j] = str1[k-cnt];
                cnt = cnt - 1;
            }
        break;
        }
        else {
            cnt++;


        }

    }

    for(m = 0; m <= pos; m++) {
        str1++;
    }
    s4 = atoi(a);
    s4 = convertDecimalToBinary(s4);
    printf("%d\n",s4);

    return 0;
}

//to convert decimal to binary

long long convertDecimalToBinary(int n)
{

//printf("%d", n);
    long long binaryNumber = 0;
    int remainder, i = 1,step=0;

    while (n!=0)
    {
        remainder = n%2;
      // printf("Step %d: %d/2, Remainder = %d, Quotient = %d\n", step++, n, remainder, n/2);

        n /= 2;

        binaryNumber += remainder*i;
        i *= 10;
    }
    return binaryNumber;
}

输出:

Enter dotted decimal ip address :

192.15.7.4
Binary Format of IP :
11000000.1111.111.0

我想将ip地址转换为二进制,但是, 它总是返回0作为最后一个十进制数的二进制。 为什么它没有执行seperate4()功能?

1 个答案:

答案 0 :(得分:1)

你所做的错误已经在评论中列出,但你做得过于复杂,几乎就像Rube-Goldberg一样。它非常简单,无需任何复杂的技巧即可完成。

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

// ALL CHECKS OMMITTED!

char *int8_to_bin(int n, char *buf)
{
  int i = 8;
  // we need an unsigned integer for the bit-juggling
  // because of two's complement numbers.
  // Not really needed here because the input is positive
  unsigned int N;
  // check for proper size
  if (n < 0 || n > 255) {
    return NULL;
  }
  // is safe now
  N = (unsigned int) n;
  // we work backwards here, least significant bit first
  // but we want it least significant bit last.
  while (i--) {
    // make a (character) digit out of an integer
    buf[i] = (char) (N & 0x1) + '0';
    // shift one bit to the right and
    // drop the least significant bit by doing it
    N >>= 1;
  }
  // return the pointer to the buffer we got (for easier use)
  return buf;
}

int main(int argc, char **argv)
{
  // keeps the intermediate integer
  int addr;
  // command-line argument, helper for strtol() and int8_to_bin()
  char *s, *endptr, *cp;
  // buffer for int8_to_bin() to work with
  // initialize to all '\0';
  char buf[9] = { '\0' };
  // array holding the end-result
  // four 8-character groups with three periods and one NUL
  char binaddr[4 * 8 + 3 + 1];
  // iterator
  int i;

  if (argc < 2) {
    fprintf(stderr, "Usage: %s dotted_ipv4\n", argv[0]);
    exit(EXIT_FAILURE);
  }
  // set a pointer pointing to the first argument as a shortcut
  s = argv[1];

  // the following can be done in a single loop, of course

  // strtol() skips leading spaces and parses up to the first non-digit.
  // endptr points to that point in the input where strtol() decided
  // it to be the first non-digit
  addr = (int) strtol(s, &endptr, 0);

  // work on copy to check for NULL while keeping the content of buf
  // (checking not done here)
  cp = int8_to_bin(addr, buf);
  // if(cp == NULL)...

  // copy the result to the result-array
  // cp has a NUL, is a proper C-string
  strcpy(binaddr, cp);

  // rinse and repeat three times
  for (i = 1; i < 4; i++) {
    // skip anything between number and period,
    // (or use strchr() to do so)
    while (*endptr != '.'){
      endptr++;
    }
    // skip the period itself
    endptr++;
    // add a period to the output
    strcat(binaddr, ".");
    // get next number
    addr = (int) strtol(endptr, &endptr, 0);
    cp = int8_to_bin(addr, buf);
    // if(cp == NULL)...
    strcat(binaddr, cp);
  }
  printf("INPUT:  %s\n", s);
  printf("OUTPUT: %s\n", binaddr);

  exit(EXIT_SUCCESS);
}

我们不需要复杂的解析算法,strtol()为我们做了,我们只需要自己找到下一个时期。所有输入和输出的大小是已知的和/或如果它们在其限制范围内,则可以很容易地检查 - 例如:不需要繁琐且容易出错的内存分配,我们可以使用固定大小的缓冲区和strcat()

有一个原则,不仅适用于海军,也适用于编程:KISS