int to 32-bitstring program

This is a discussion on int to 32-bitstring program within the C Programming forums, part of the General Programming Boards category; Ok, so I am trying to make a program that takes two ints, converts them to 32-length bitstrings, (one <mask> ...

  1. #1
    Registered User
    Join Date
    May 2010
    Location
    San Jose, California, United States
    Posts
    22

    Smile int to 32-bitstring program

    Ok, so I am trying to make a program that takes two ints, converts them to 32-length bitstrings, (one <mask> filters the other <num>), and return a filtered bitstring of same length.
    Example:
    0000000000000000000010110001010 (num)

    ^^ ^^ ^
    | | | | |
    | | | | |

    0000000000000000000000110001101 (mask)

    Each of the mask bits points at a bit position in "num". Isolating those bits,

    11 10 0 (bits from num that were masked)
    Then these are squeezed,

    11100
    And padded with leading zeros,

    0000000000000000000000000011100


    Code:
    /* three header files */
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    /* declare two global variables */
    int num;
    int mask;
    
    /* a helper function to print out a number in binary */
    char print32bits(int x)
    {
    
       unsigned int mask;       /* declare as a local variable */
       char *foo;                /* bitstring to be returned*/
    
       mask = 0x80000000;       /* initializes the local, not global mask */
       while (mask != 0)
       {
          if ((mask & x) == 0)
             strcat(foo,"0");
          else
             strcat(foo,"1");          //segmentation fault, program ends
          mask = mask >> 1;
       }
       strcat("\n",foo);
       return foo;
    }
    
    
    int get_bits_squeeze(int num, int mask)
    {
        num = print32bits(num);         /*translate into bitstring*/
        mask = print32bits(mask);       /*translate into bitstring*/
        char *bitString;
        for(int i = 0;i<=32;i++)        /*create filtered bitstring*/
        {
            if(mask[i]=="1")
                strcat(bitString,num[i]);
        }
        /*fill in here*/
    
    
        return 0;
    }
    
    /*
       the main function. argc, argv are the command-line arguments,
       like args in Java
    */
    int main(int argc, char* argv[])
    {
       int result;                  /* declare a local variable */
    
       //num = atoi(argv[1]);	/* store first command line argument into num */
       //mask = atoi(argv[2]);	/* store second into mask */
       num = 13;
       mask = 12;
       printf("%s",print32bits(num));		/* produce first line of output */
       printf("%s",print32bits(mask));		/* produce second line of output */
       result = get_bits_squeeze(num, mask);
       printf("%s",print32bits(result));		/* produce third line of output */
       exit(0);                     /* success */
    }
    I know there may be several issues with the program, but I can't seem to get past that segmentation fault error to check them..
    I have a few questions bothering me: 1) should the char *foo be a pointer (and *bitString)? How do I know when I should make chars pointers? 2) also, is there a way to filter the initial bitstrings without making them strings (in other words if print32bits() returned in int instead of char)??

    Can someone read this over and help me out?
    Any help is appreciated!!

  2. #2
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,047
    char *foo can only hold a single character so either make it a static array, char foo[], or malloc storage dynamically.

  3. #3
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    You are creating pointers foo and bitstring and you are neither allocating nor freeing memory for them. That's what's causing your seg-fault... accessing unallocated memory.

    C Strings - C++ Tutorial - Cprogramming.com

  4. #4
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by itCbitC View Post
    char *foo can only hold a single character so either make it a static array, char foo[], or malloc storage dynamically.
    Actually char *foo can't hold anything except an address. It has exactly 0 memory allocated to it until you use malloc().

  5. #5
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,566
    Crank up those compiler warnings and heed them. If you write code the compiler says is bad, and force it to compile it, the resultant executable probably wont work like you want.

    Code:
    char print32bits(int x)
    {
    ...
        char *foo;                /* bitstring to be returned*/
    ...
                strcat(foo,"0");
    ...
        return foo;
    }
    You're returning a char * from a function that wants you to return a char.
    You can't strcat into a pointer unless it point to valid memory.

    Code:
    int get_bits_squeeze(int num, int mask)
    {
        num = print32bits(num);         /*translate into bitstring*/
        mask = print32bits(mask);       /*translate into bitstring*/
       char *bitString;
        for(int i = 0;i<=32;i++)        /*create filtered bitstring*/
            if(mask[i]=="1")
                strcat(bitString,num[i]);
    Those two calls that assign the value of print32bits to num and mask don't do what you think. Declare two variables, say (e.g. char *num_str, *mask_str)as appropriate to receive the value of print32bits.
    Your for loop should be < 32. An array of 32 items only has valid indexes of 0..31.
    mask and num are single ints, so you can't index it like it's an array. This should be the num_str and mask_str I referred to.
    Once you fix that, you can't compare num_str[i] (a char) to "1" (a string). You need single quotes, '1' (for string comparison, you can't use ==, you need strcmp).

    Code:
        printf("%s",print32bits(num));       /* produce first line of output */
        printf("%s",print32bits(mask));      /* produce second line of output */
        result = get_bits_squeeze(num, mask);
        printf("%s",print32bits(result));        /* produce third line of output */
        exit(0);
    %s expects a char *, not a char. Also, it should be return 0, not exit(0).

    Whew! Good effort, but maybe you ought to go back in your book a bit, or find some more basic tutorials that cover functions, arrays, strings, etc and work some very basic examples in those first, tackling one concept at a time until you are very competent in it, then come back to this program that incorporates several of them at once.

  6. #6
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Hey there

    Why don't you just pass a 32byte array into the function?

  7. #7
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,047
    @OP: Still not sure what bitwise manipulations you're trying to do.
    It's masking off only two bits: bit 1 and bit 10. How'd you get three?
    Quote Originally Posted by CommonTater View Post
    Actually char *foo can't hold anything except an address.
    foo holds an address but *foo is a byte bucket.
    Quote Originally Posted by CommonTater View Post
    It has exactly 0 memory allocated to it until you use malloc().
    Unless it points to a char.
    Last edited by itCbitC; 02-17-2011 at 02:10 PM.

  8. #8
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Quote Originally Posted by itCbitC View Post
    foo holds an address but *foo is a byte bucket.
    I'm not exactly sure what you mean by "a byte bucket", but the fact remains that uninitialized pointers are simply not (safely) dereferenceable. Period. And even if one was to point the thing to a single char, well, that would be just as disastrous; consider: strcpy( &ch, "uh-oh"). I don't know, maybe I misunderstood you?
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  9. #9
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,047
    Quote Originally Posted by Sebastiani View Post
    I'm not exactly sure what you mean by "a byte bucket"
    A bucket that holds a byte of data
    Quote Originally Posted by Sebastiani View Post
    but the fact remains that uninitialized pointers are simply not (safely) dereferenceable. Period.
    I implied that in my previous post; guess I should have been crystal clear.
    Quote Originally Posted by Sebastiani View Post
    And even if one was to point the thing to a single char, well, that would be just as disastrous; consider: strcpy( &ch, "uh-oh"). I don't know, maybe I misunderstood you?
    We're on the same page here if you read my first post.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Producer/Consumer - problems creating threads
    By hansel13 in forum C Programming
    Replies: 47
    Last Post: 08-20-2010, 02:02 PM
  2. Replies: 3
    Last Post: 05-13-2007, 08:55 AM
  3. Moving Average Question
    By GCNDoug in forum C Programming
    Replies: 4
    Last Post: 04-23-2007, 11:05 PM
  4. Replies: 1
    Last Post: 10-27-2006, 01:21 PM
  5. About aes
    By gumit in forum C Programming
    Replies: 13
    Last Post: 10-24-2006, 03:42 PM

Tags for this Thread


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21