Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 将数字从一个基数转换为另一个基数时出现分段错误_C_Gcc_Segmentation Fault - Fatal编程技术网

C 将数字从一个基数转换为另一个基数时出现分段错误

C 将数字从一个基数转换为另一个基数时出现分段错误,c,gcc,segmentation-fault,C,Gcc,Segmentation Fault,我正在用C语言编写一个程序,将数字从任意基转换成任意基。它可以从十进制转换到任意基,但当我实现从任意基的转换时,我遇到了分段错误:我必须指定我不使用IDE,只使用gcc命令将我的程序链接到静态库。奇怪的是,我尝试在Windows上编译,结果成功了。有人能帮我吗 代码如下: #include <stdio.h> #include <stdlib.h> #include <ctype.h> //library for isdigit #include <st

我正在用C语言编写一个程序,将数字从任意基转换成任意基。它可以从十进制转换到任意基,但当我实现从任意基的转换时,我遇到了分段错误:我必须指定我不使用IDE,只使用gcc命令将我的程序链接到静态库。奇怪的是,我尝试在Windows上编译,结果成功了。有人能帮我吗

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h> //library for isdigit
#include <string.h>
#include "ylantron.h" //<-- my library

#define MAX_SYMBOLS 36

void pause();
char* convert(char* value, int startingBase, int endingBase);
char* swapArray(char *oldArray);

// MAIN

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

/* CHECK ARGUMENTS NUMBER */
if (argc != 4 ){
  printf("\n\e[91m[X]\e[39m Invalid number argument\n");
  pause();
  return 1;
}

/* CHECK ARGUMENTS */
if (   (isdigit(argv[1][0])==0)   ||   (isdigit(argv[2][0])==0)   ||   (isdigit(argv[3][0])==0)   ){
  printf("\n\e[91m[X]\e[39m One of the arguments is not a number\n");
  pause();
  return 1;
}

/* CHECKING BASES */
int check=0;
char *baseType=(char*)calloc(9,sizeof(char));
char *infSup=(char*)calloc(10,sizeof(char));
int numMinMax;

if (atoi(argv[1])<2)   { strcpy(baseType,"starting");   strcpy(infSup,"inferior");   numMinMax=2;   check=1; }
else if (atoi(argv[1])>MAX_SYMBOLS)   { strcpy(baseType,"starting");   strcpy(infSup,"superior");   numMinMax=MAX_SYMBOLS;   check=1; }
else if (atoi(argv[3])<2)   { strcpy(baseType,"ending");   strcpy(infSup,"inferior");   numMinMax=2;   check=1; }
else if (atoi(argv[3])>MAX_SYMBOLS)   { strcpy(baseType,"ending");   strcpy(infSup,"superior");   numMinMax=MAX_SYMBOLS;   check=1; }

if (check==1){
  printf("\n\e[91m[X]\e[39m The %s base can't be %s to %d\n",   baseType,   infSup,   numMinMax);

  free(baseType);
  free(infSup);

  pause();
  return 1; }

int base_from, base_to;
char* val;

base_from=atoi(argv[1]);
val=argv[2];
base_to=atoi(argv[3]);

if (base_from==base_to)   { printf("\n\e[93m[?]\e[39m Why you want me to convert a number with equal bases?"); pause(); return 1; }

printf("\nThe result is %s\n\n",converti(val,base_from,base_to));

return 0;
}

// FUNCTIONS

void pause() {

printf("\nPress any key...");
getch();
printf("\n");

}


char* convert(char* value, int startingBase, int endingBase){

char symbols[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
char *valueArray=NULL;
int val=0;


if (startingBase != 10 ){
  for (int i=0;i<(strlen(value)/sizeof(char));i++){
     for (int j=0;j<MAX_SYMBOLS;j++){
        if (value[i]==symbols[j]){
           val+=j;
           break;
        }
     }
  }
}

printf("val: %d",val);

for (int i=1;val!=0;){
  valueArray=(char *)realloc(valueArray,(++i)*sizeof(char));
  valueArray[i-2]=symbols[(val%endingBase)];
  valueArray[i-1]='\0';
  val/=endingBase;
}

swapArray(valueArray);

return valueArray;

}

char* swapArray(char *oldArray){

char old;
int i,j;

for (i=0,j=strlen(oldArray)-1;i<(strlen(oldArray)/2);i++,j--){
  old=oldArray[i];
  oldArray[i]=oldArray[j];
  oldArray[j]=old;
}

return oldArray;
}
#包括
#包括
#包含//isdigit的库
#包括

#包括“ylantron.h”/您有一些真正的bug。有些人会造成崩溃。其他人会产生错误的结果。首先,我将解释错误

此外,在下面,我制作了两个版本的程序。一个带有注释的程序,注释中显示了bug[以及修复程序]。还有,第二个清理版本


对于碰撞,向后操作:

  • swapArray
    正在分段故障,因为它被赋予了
    NULL
    指针
  • convert
    将执行
    swapArray(valueArray)
    valueArray
    可以/将执行
    NULL
  • convert
    中,
    valueArray
    将为
    NULL
    如果
    val
    为零(即,
    realloc
    的循环将有零次迭代
  • 如果
    startingBase
    为10,则
    val
    可以/将为零(即前两个循环不会执行)
  • 如果(startingBase!=10)
  • 测试是多余的/错误的,则应始终执行这两个循环(即
  • 此外,即使固定了#5,
    val
    仍然可以[合法地]为零(即原始值为零)。因此,必须重新构造
    realloc
    循环以至少执行一次,以确保
    valueArray
    不是
    NULL

    好的,这可以处理崩溃,但是程序仍然会产生错误的结果,因为在这一行上面:

    val += j;
    
    我们需要乘以起始基数,如下所示:

    val *= startingBase;
    val += j;
    

    这是带注释的版本

    样式为:
    #if 0/*原始代码*/#else/*固定代码*/#endif
    ,并且有注释解释事情[请原谅免费的样式清理]:

    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>                      // library for isdigit
    #include <string.h>
    #include <curses.h>
    //#include "ylantron.h"                 // <-- my library
    
    #define MAX_SYMBOLS 36
    
    void pause();
    char *convert(char *value, int startingBase, int endingBase);
    char *swapArray(char *oldArray);
    
    // MAIN
    
    int
    main(int argc, char *argv[])
    {
    
        /* CHECK ARGUMENTS NUMBER */
        if (argc != 4) {
            printf("\n\e[91m[X]\e[39m Invalid number argument\n");
            pause();
            return 1;
        }
    
        /* CHECK ARGUMENTS */
        if ((isdigit(argv[1][0]) == 0) || (isdigit(argv[2][0]) == 0) || (isdigit(argv[3][0]) == 0)) {
            printf("\n\e[91m[X]\e[39m One of the arguments is not a number\n");
            pause();
            return 1;
        }
    
        /* CHECKING BASES */
        int check = 0;
        char *baseType = (char *) calloc(9, sizeof(char));
        char *infSup = (char *) calloc(10, sizeof(char));
        int numMinMax;
    
        int base_from;
        int base_to;
        char *val;
    
        base_from = atoi(argv[1]);
        val = argv[2];
        base_to = atoi(argv[3]);
    
        if (base_from < 2) {
            strcpy(baseType, "starting");
            strcpy(infSup, "inferior");
            numMinMax = 2;
            check = 1;
        }
        else if (base_from > MAX_SYMBOLS) {
            strcpy(baseType, "starting");
            strcpy(infSup, "superior");
            numMinMax = MAX_SYMBOLS;
            check = 1;
        }
        else if (base_to < 2) {
            strcpy(baseType, "ending");
            strcpy(infSup, "inferior");
            numMinMax = 2;
            check = 1;
        }
        else if (base_to > MAX_SYMBOLS) {
            strcpy(baseType, "ending");
            strcpy(infSup, "superior");
            numMinMax = MAX_SYMBOLS;
            check = 1;
        }
    
        if (check == 1) {
            printf("\n\e[91m[X]\e[39m The %s base can't be %s to %d\n",
                baseType, infSup, numMinMax);
    
            free(baseType);
            free(infSup);
    
            pause();
            return 1;
        }
    
        if (base_from == base_to) {
            printf("\n\e[93m[?]\e[39m Why you want me to convert a number with equal bases?");
            pause();
            return 1;
        }
    
        printf("\nThe result is %s\n\n", convert(val, base_from, base_to));
    
        return 0;
    }
    
    // FUNCTIONS
    
    void
    pause()
    {
    
        printf("\nPress any key...");
        getch();
        printf("\n");
    }
    
    char *
    convert(char *value, int startingBase, int endingBase)
    {
    
        char symbols[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };
        char *valueArray = NULL;
        int val = 0;
    
        // NOTE/BUG: this should _always_ be executed regardless of base
    #if 0
        if (startingBase != 10) {
    #endif
            for (int i = 0; i < (strlen(value) / sizeof(char)); i++) {
                for (int j = 0; j < MAX_SYMBOLS; j++) {
                    if (value[i] == symbols[j]) {
                        // NOTE/BUG: when assembling the number we must multiply by
                        // the base
    #if 1
                        val *= startingBase;
    #endif
                        val += j;
                        break;
                    }
                }
            }
    #if 0
        }
    #endif
    
        // NOTE: for debug?
        printf("val: %d", val);
    
        // NOTE/BUGS:
        // (1) if val is zero, this loop will never be executed and
        //     valueArray will remain NULL
        // (2) if startingBase _is_ 10, then val could _never_ be non-zero
    #if 0
        for (int i = 1; val != 0;) {
            valueArray = (char *) realloc(valueArray, (++i) * sizeof(char));
            valueArray[i - 2] = symbols[(val % endingBase)];
            valueArray[i - 1] = '\0';
            val /= endingBase;
        }
    #else
        int i = 1;
        while (1) {
            valueArray = (char *) realloc(valueArray, (++i) * sizeof(char));
            valueArray[i - 2] = symbols[(val % endingBase)];
            valueArray[i - 1] = '\0';
            val /= endingBase;
            if (val == 0)
                break;
        }
    #endif
    
        // NOTE/BUG: this produces a segfault if valueArray is NULL
        swapArray(valueArray);
    
        return valueArray;
    }
    
    char *
    swapArray(char *oldArray)
    {
    
        char old;
        int i;
        int j;
    
        // NOTE/BUG: strlen gives segfault if oldArray is NULL
        for (i = 0, j = strlen(oldArray) - 1; i < (strlen(oldArray) / 2); i++, j--) {
            old = oldArray[i];
            oldArray[i] = oldArray[j];
            oldArray[j] = old;
        }
    
        return oldArray;
    }
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>                      // library for isdigit
    #include <string.h>
    #include <curses.h>
    //#include "ylantron.h"                 // <-- my library
    
    #define MAX_SYMBOLS 36
    
    void pause();
    char *convert(char *value, int startingBase, int endingBase);
    char *swapArray(char *oldArray);
    
    // MAIN
    
    int
    main(int argc, char *argv[])
    {
    
        /* CHECK ARGUMENTS NUMBER */
        if (argc != 4) {
            printf("\n\e[91m[X]\e[39m Invalid number argument\n");
            pause();
            return 1;
        }
    
        /* CHECK ARGUMENTS */
        if ((isdigit(argv[1][0]) == 0) || (isdigit(argv[2][0]) == 0) || (isdigit(argv[3][0]) == 0)) {
            printf("\n\e[91m[X]\e[39m One of the arguments is not a number\n");
            pause();
            return 1;
        }
    
        /* CHECKING BASES */
        int check = 0;
        char *baseType = (char *) calloc(9, sizeof(char));
        char *infSup = (char *) calloc(10, sizeof(char));
        int numMinMax;
    
        int base_from;
        int base_to;
        char *val;
    
        base_from = atoi(argv[1]);
        val = argv[2];
        base_to = atoi(argv[3]);
    
        if (base_from < 2) {
            strcpy(baseType, "starting");
            strcpy(infSup, "inferior");
            numMinMax = 2;
            check = 1;
        }
        else if (base_from > MAX_SYMBOLS) {
            strcpy(baseType, "starting");
            strcpy(infSup, "superior");
            numMinMax = MAX_SYMBOLS;
            check = 1;
        }
        else if (base_to < 2) {
            strcpy(baseType, "ending");
            strcpy(infSup, "inferior");
            numMinMax = 2;
            check = 1;
        }
        else if (base_to > MAX_SYMBOLS) {
            strcpy(baseType, "ending");
            strcpy(infSup, "superior");
            numMinMax = MAX_SYMBOLS;
            check = 1;
        }
    
        if (check == 1) {
            printf("\n\e[91m[X]\e[39m The %s base can't be %s to %d\n",
                baseType, infSup, numMinMax);
    
            free(baseType);
            free(infSup);
    
            pause();
            return 1;
        }
    
        if (base_from == base_to) {
            printf("\n\e[93m[?]\e[39m Why you want me to convert a number with equal bases?");
            pause();
            return 1;
        }
    
        printf("\nThe result is %s\n\n", convert(val, base_from, base_to));
    
        return 0;
    }
    
    // FUNCTIONS
    
    void
    pause()
    {
    
        printf("\nPress any key...");
        getch();
        printf("\n");
    }
    
    char *
    convert(char *value, int startingBase, int endingBase)
    {
        char symbols[] = { "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" };
        char *valueArray = NULL;
        int val = 0;
    
        for (int chr = *value++;  chr != 0;  chr = *value++) {
            for (int j = 0; j < MAX_SYMBOLS; j++) {
                if (chr == symbols[j]) {
                    val *= startingBase;
                    val += j;
                    break;
                }
            }
        }
    
        int i = 1;
        while (1) {
            valueArray = (char *) realloc(valueArray, (++i) * sizeof(char));
            valueArray[i - 2] = symbols[(val % endingBase)];
            valueArray[i - 1] = '\0';
            val /= endingBase;
            if (val == 0)
                break;
        }
    
        swapArray(valueArray);
    
        return valueArray;
    }
    
    char *
    swapArray(char *oldArray)
    {
        char old;
        int i;
        int j;
    
        for (i = 0, j = strlen(oldArray) - 1; i < (strlen(oldArray) / 2); i++, j--) {
            old = oldArray[i];
            oldArray[i] = oldArray[j];
            oldArray[j] = old;
        }
    
        return oldArray;
    }
    
    char *
    swapArray_2(char *oldArray)
    {
        char old;
        int len;
        int i;
        int j;
    
        len = strlen(oldArray);
        for (i = 0, j = len - 1; i < (len / 2); i++, j--) {
            old = oldArray[i];
            oldArray[i] = oldArray[j];
            oldArray[j] = old;
        }
    
        return oldArray;
    }
    
    char *
    swapArray_3(char *oldArray)
    {
        char *lhs;
        char *rhs;
        char old;
    
        lhs = oldArray;
        rhs = &lhs[strlen(lhs) - 1];
    
        for (;  lhs < rhs;  ++lhs, --rhs) {
            old = *lhs;
            *lhs = *rhs;
            *rhs = old;
        }
    
        return oldArray;
    }