【问题标题】:Word to binary numbers program in CC语言中的字转二进制程序
【发布时间】:2017-03-04 09:12:51
【问题描述】:

我正在尝试制作将单词转换为二进制数的程序。 例如:

输入:

abcd

输出(首先是a、b、c、d的ascii码):

(a、b、c、d的ASCII码)

一:97

b:98

c: 99

d: 100

将这些转换为二进制:

97: 1100001

98: 1100010

99: 1100011

100: 1100100

最后输出应该是这样的:

110000|11100010|1100011|1100100

或者它们之间没有直线。

但我收到一个错误:

输入:

一个

输出:

分段失败(核心转储)

代码如下:

#include <stdio.h>

#define MAXINPUTCHAR 100
#define MAXBINARYNUMERAL 32

int thestr[MAXINPUTCHAR];
int theastr[MAXINPUTCHAR];
int thebstr[MAXINPUTCHAR][MAXBINARYNUMERAL];
//function declerations...
void mydtob(int,int*);//Decimal to binary converter
void mystreverse(int*);//Reverse the string
void mycopy(int*,int*);//Copy array into array
void mystoa(int*,int*);//Char array to ascii codes of the chars array
void mydtobhelper(int*,int [MAXINPUTCHAR][MAXBINARYNUMERAL]);//The function that loops through and calls mydtob
void mygetline(int*);
void printArray(int [MAXINPUTCHAR][MAXBINARYNUMERAL]);//Print 2D array
void mymdcp(int target[MAXINPUTCHAR][MAXBINARYNUMERAL],int* from,int targetIndex);//Copy array to 2D array

int main(void) {
    mygetline(thestr);
    mystoa(thestr,theastr);
    mydtobhelper(theastr,thebstr);
    printArray(thebstr);
    return 0;
}

void mydtobhelper(int* decimal,int target[MAXINPUTCHAR][MAXBINARYNUMERAL]){
    int singlenumbinary[MAXBINARYNUMERAL];
    for(int i=0;decimal[i];i++){
        mydtob(decimal[i],singlenumbinary);
        mymdcp(target,singlenumbinary,0);
        target[i+1][0]='\0';
    }
}

void mydtob(int decimal,int* target){
    int base=2;
    int quotient=decimal;
    int remainder=0;
    int i=0;
    while(quotient!=0){
        remainder=quotient%base;
        quotient=quotient/base;
        target[i]=remainder+'0';
        target[i+1]='\0';
        i++;
    }
    mystreverse(target);
}

void printArray(int arraytoprint[MAXINPUTCHAR][MAXBINARYNUMERAL]){
    char convertedarr[MAXINPUTCHAR][MAXBINARYNUMERAL];
    for(int i=0;i<MAXINPUTCHAR;i++) {
        for(int k=0;i<MAXBINARYNUMERAL;k++){
            convertedarr[i][k]=arraytoprint[i][k];
        }
    }
    for(int i=0;convertedarr[i][0];i++){
        printf("%s",convertedarr[i]);   
    }   
}

void mystreverse(int* str){
    int copiedstr[MAXINPUTCHAR];
    int i=0;
    for(i=0;str[i];i++);
    i--;    
    mycopy(str,copiedstr);
    for (int k=i;k>=0;k--){
        str[k]=copiedstr[i-k];
    }
    str[i+1]='\0';
}

void mycopy(int* from,int* target){
    for(int i=0;from[i];i++){
        target[i]=from[i];
        target[i+1]='\0';
    }
}

void mystoa(int* str,int* target) {
  for (int i = 0; str[i];i++) {
    //printf("%d\n",i);
    if (str[i] >= 'a' && str[i] <= 'z' || str[i]==' ' || str[i]=='\t') {
      int n = str[i];
      target[i]=n;
      target[i+1]='\0';
    }
  }
}

void mygetline(int* target){
    int i=0;
    int c=0;
    while((c=getchar())!=EOF && c != '\n'){
        target[i]=c;
        target[i+1]='\0';
        i++;
    }
}

void mymdcp(int target[MAXINPUTCHAR][MAXBINARYNUMERAL], int* from, int targetIndex) {
    for (int j = 0; j < from[j]; j++) {
        target[targetIndex][j] = from[j];
    }
}

【问题讨论】:

  • 你在哪里得到错误?有人认为我认为你可以用更少的代码来实现这一点,通过使用位操作来获取二进制数和 ASCII,你可以使用枚举或字符转换为 int
  • mystoa() 是一个问题,如果 str 类似于 "ABC" 作为目标将缺少 target[0] 的值...target[2] 并且它不会以空字符终止。不清楚功能的目标。
  • @Muhamed-- 请学习如何使用调试器。我使用 gdb 在 30 秒内找到了导致您的段错误的错误。您可以在比发布问题更短的时间内找到它!您会注意到这里的每个人都在不断地恳求人们使用调试器。那是因为我们一直在使用它们,并且知道它们可以节省多少时间。花一个下午的时间学习 gdb 或您选择的其他调试器的基本原理是非常值得的!积极的一点是,感谢您发布完整的编译文件。
  • @DavidBowling 对不起。我是 C 新手。我不知道我可以使用哪个调试器。我会试试 gdb。谢谢

标签: c binary segmentation-fault bit coredump


【解决方案1】:

分段错误是由函数printArray()中的错误循环引起的:

for(int k=0;i<MAXBINARYNUMERAL;k++){
   convertedarr[i][k]=arraytoprint[i][k];

循环条件中的i 应该是k。解决此问题后,程序可以运行:

λ> ./a.out 
z
1111010
λ> ./a.out 
a
1100001
λ> ./a.out 
f
1100110

编辑

我认为代码可读性可能是这里的一个问题。考虑原始格式的代码:

void printArray(int arraytoprint[MAXINPUTCHAR][MAXBINARYNUMERAL]){
    char convertedarr[MAXINPUTCHAR][MAXBINARYNUMERAL];
    for(int i=0;i<MAXINPUTCHAR;i++) {
        for(int k=0;i<MAXBINARYNUMERAL;k++){
            convertedarr[i][k]=arraytoprint[i][k];
        }
    }
    for(int i=0;convertedarr[i][0];i++){
        printf("%s",convertedarr[i]);   
    }
    putchar('\n');
}

与此相比:

void printArray(int arraytoprint[MAXINPUTCHAR][MAXBINARYNUMERAL])
{
    char convertedarr[MAXINPUTCHAR][MAXBINARYNUMERAL];

    for (int i = 0;i < MAXINPUTCHAR; i++) {
        for (int k = 0;i < MAXBINARYNUMERAL; k++){
            convertedarr[i][k] = arraytoprint[i][k];
        }
    }
    for (int i = 0;convertedarr[i][0]; i++){
        printf("%s", convertedarr[i]);   
    }
    putchar('\n');
}

这两个 sn-ps 都包含原始错误,但第二个更容易发现,因为符号并没有那么挤在一起。

【讨论】:

  • 我只是想知道,你是怎么这么快找到错误的。我的意思是即使它是调试器。找到它不是那么容易?
  • @MuhamedCicak-- Hereherehere 是使用 gdb 的教程。这不是一个教程的地方,但简单地说,我用调试符号编译了你的代码并在 gdb 中运行它。当它出现段错误时,gdb 告诉我发生了什么函数。我没有立即看到问题,所以我输入了一个printf() 来显示ik 的值,然后看到k 只是不断增长。啊哈!
  • @MuhamedCicak--作为旁注,阅读您的代码有点困难,因为您不使用很多空格或空行。这会导致您难以发现的错误(因此我使用了printf() 语句)。如果您尝试格式化代码以提高可读性,则不太可能需要调试器来查找如此简单的错字。不过,学习如何使用一个。时间会得到回报。
  • @MuhamedCicak--在我的答案中添加了关于代码可读性的编辑。
  • 我想我应该购买像 CLion 这样的 IDE。我在 CLion 中进行免费试用编程,而且我对代码可读性没有任何问题,因为您可以选择自动格式化代码。但是因为它已过期(免费试用)我现在用 Sublime Text 编程。你知道任何免费的 IDE,它有自动格式化代码吗?因为我找了一段时间没找到。
猜你喜欢
  • 1970-01-01
  • 2018-04-28
  • 2013-09-20
  • 2017-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多