在C语言中将字符串转换为二进制

6

我想在C语言中将字符串转换为二进制。该函数必须返回一个类似于“010010101”等的字符串(char *)。同时,我想打印返回的内容。但我不能确定这段代码是否正确。

函数

char* stringToBinary(char* s)
{
    if(s == NULL) return 0; /* no input string */
    char *binary = malloc(sizeof(s)*8);
    strcpy(binary,"");
    char *ptr = s;
    int i;

    for(; *ptr != 0; ++ptr)
    {

        /* perform bitwise AND for every bit of the character */
        for(i = 7; i >= 0; --i){
            (*ptr & 1 << i) ? strcat(binary,"1") : strcat(binary,"0");
        }


    }
    
    return binary;
}

3
malloc(sizeof(s)*8);的意思是分配一个可以存储8个s类型数据的内存空间。而never trust user (_caller_)的意思是永远不要相信用户(调用者)。 - Sourav Ghosh
你为什么要分配8个指针的空间? - melpomene
每个字符有8位,如果我有一个包含10个字母的字符串,那么它就意味着10*8?不是吗? - Berkin
3
s 是一个指向字符的指针。sizeof s 是一个 char* 的大小(可能是 4 或 8 字节)。 - melpomene
1
@ventsyv 什么?ASCII 是7位。 - melpomene
显示剩余11条评论
3个回答

6

你的代码看起来大部分都没问题。你只是分配了错误的内存大小。以下是已经更正过的代码:

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

char* stringToBinary(char* s) {
    if(s == NULL) return 0; /* no input string */
    size_t len = strlen(s);
    char *binary = malloc(len*8 + 1); // each char is one byte (8 bits) and + 1 at the end for null terminator
    binary[0] = '\0';
    for(size_t i = 0; i < len; ++i) {
        char ch = s[i];
        for(int j = 7; j >= 0; --j){
            if(ch & (1 << j)) {
                strcat(binary,"1");
            } else {
                strcat(binary,"0");
            }
        }
    }
    return binary;
}

样例运行:

"asdf"           => 01100001011100110110010001100110
"tester"         => 011101000110010101110011011101000110010101110010
"Happy New Year" => 0100100001100001011100000111000001111001001000000100111001100101011101110010000001011001011001010110000101110010

#include "stdlib.h" ===> #include <stdlib.h>#include "stdio.h" ===> #include <stdio.h>#include "string.h" ===> #include <string.h> - Amjad

2

不做任何假设关于输入,只打印字节中的位:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <errno.h>
char *stringToBinary(char *s)
{
  if (s == NULL) {
    // NULL might be 0 but you cannot be sure about it
    return NULL;
  }
  // get length of string without NUL
  size_t slen = strlen(s);

  // we cannot do that here, why?
  // if(slen == 0){ return s;}

  errno = 0;
  // allocate "slen" (number of characters in string without NUL)
  // times the number of bits in a "char" plus one byte for the NUL
  // at the end of the return value
  char *binary = malloc(slen * CHAR_BIT + 1);
  if(binary == NULL){
     fprintf(stderr,"malloc has failed in stringToBinary(%s): %s\n",s, strerror(errno));
     return NULL;
  }
  // finally we can put our shortcut from above here
  if (slen == 0) {
    *binary = '\0';
    return binary;
  }
  char *ptr;
  // keep an eye on the beginning
  char *start = binary;
  int i;

  // loop over the input-characters
  for (ptr = s; *ptr != '\0'; ptr++) {
    /* perform bitwise AND for every bit of the character */
    // loop over the input-character bits
    for (i = CHAR_BIT - 1; i >= 0; i--, binary++) {
      *binary = (*ptr & 1 << i) ? '1' : '0';
    }
  }
  // finalize return value
  *binary = '\0';
  // reset pointer to beginning
  binary = start;
  return binary;
}


int main(int argc, char **argv)
{
  char *output;
  if (argc != 2) {
    fprintf(stderr, "Usage: %s string\n", argv[0]);
    exit(EXIT_FAILURE);
  }
  // TODO: check argv[1]
  output = stringToBinary(argv[1]);
  printf("%s\n", output);

  free(output);
  exit(EXIT_SUCCESS);
}

-3
我不编译,但我希望这能激励你。 所以: 一个字符是8位。 xxxxxxxx 使用掩码比较每个位更容易和更快速。 xxxxxxxX & 00000001 只有当第1位为1时才是真的。 接下来是 xxxxxxXx & 00000010
char * stringToBinary( char * s )
{   
    // Variables.
    char * aux, *binary, mask;
    int size, i, y;

    if(s == NULL){
        // If arg is null, nothing to do.
        return NULL;
    }

    // Calculate the size of the str.
    size= strlen(s);
    // alloc the str that contain the answer.
    binary= malloc( (size*8)+1 );
    // If no memory, nothing to do.
    if( binary == NULL ){
        // No memory
        return NULL;
    }

    // save a copy of the arg.
    aux= s;
    // for each char in the str arg.
    for( i=0; i<size; i++ ){
        // In each char to examinate, reset the mask.
        mask= 0x0001;
        // For each bit of a char.
        for( y=0; y<8; y++ ){
            // Compare each bit with the mask.
            if( (*aux) & mask ){
                // add 0 to the answer.
                strcat(bynary,"1");
            }else{
                // add 1 to the answer.
                strcat(bynary,"0");
            }
            // shit the mask 1 pos to left.
            mask= mask<<1;
         }
         aux++
    }
    return binary;
}

一个代码转储并不是很有帮助。请添加一些注释或其他解释,说明这段代码如何解决 OP 的问题。 - skrrgwasme
最短的答案是负面的吗?我现在会添加评论。 - Agustin Lo Castro
谢谢你的建议。 - Agustin Lo Castro
strcat(bynary,"1");bynary指向未初始化的内容,并且拼写有误。 - BLUEPIXY
aux++ --> aux++;,同时你的过程是反向结果。 - BLUEPIXY
最近花了太多时间在Java上,谢谢。 - Agustin Lo Castro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接