c - C 语言的基本更改程序符合要求,但不显示任何输出

标签 c file-io segmentation-fault

我最近刚接触编程,但事实证明这项任务是我最困难的。该程序应该读取具有以下格式的 .txt 文件

input_base number output_base

并输出结果。碱基的范围只能是 2-36 例如:

input: 2 10 4
output: 2

我的程序读取该行的每个部分并分别存储它们。然后,我按照步骤将数字转换为输出基数,然后向后打印。我的问题是程序运行良好并打印所有存储的值和计算的值,但是一旦我添加“base_conversion”函数,程序就不再工作,我的 friend 甚至说这给了他一个段错误。我真的不知道是什么原因造成的。任何帮助,将不胜感激。谢谢。

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

void read_file_to_buffer(FILE *file);
char *buffer = NULL;
void string_check(char *buffer);
int char_to_int(char c);
int int_conversion(int x, int y);
void base_conversion(int end_number, int out_base);

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

FILE *file = NULL;


if ( argc != 2 ){
    fprintf(stderr, "Error: To many/few arguments\n");
    exit(EXIT_FAILURE);
}

else {
    file = fopen(argv[1], "rb");

    if (file == NULL) {
        fprintf(stderr, "Error: could not open file '%s'\n", argv[1]);
        exit(EXIT_FAILURE);
    }
    else{
        printf("File %s opened!\n", argv[1]);
    }
}

read_file_to_buffer(file);
string_check(buffer);

fclose(file);
free(buffer);
buffer = NULL;

exit(EXIT_SUCCESS);
}



void read_file_to_buffer(FILE *file) {
long file_size = 0;

if(buffer != NULL){
    fprintf(stderr, "buffer in use\n");
    exit(EXIT_FAILURE);
}
rewind(file);
if (fseek(file, 0, SEEK_END) != 0){
    perror("Could not seek to end of file");
    exit(EXIT_FAILURE);
}

file_size = ftell(file);
if (file_size < 0){
    perror("could not tell size of file");
    exit(EXIT_FAILURE);
}
rewind(file);

buffer = (char *)malloc(sizeof(char) * (file_size + 1));
if (buffer == NULL){
    fprintf(stderr, "Could not allocate memory");
    exit(EXIT_FAILURE);
}

if(fread(buffer, sizeof(char), (size_t)file_size, file) != file_size){
    fprintf(stderr, "Could not read file\n");
    exit(EXIT_FAILURE);
}
buffer[file_size] = '\0';

return;
}


void string_check(char *buffer){

int i = 0;
int j = 0;
char base_in[2];
char number[50];
char base_out[2];
int actual_number[100];
int end_number = 0;
int x = 0;
int y = 0;
int in_base;
int out_base;

while( buffer[i] != '\0'){
    if (buffer[i] != '#' && buffer[i] != ' ' && buffer[i] != '\n' &&     buffer[i] != '\r'){
        while (buffer[i] != ' '){
            base_in[j] = buffer[i];
            i++;
            j++;
        }
        j = 0;
        i++;
        if (base_in[1] != '\0'){
            x = char_to_int(base_in[0]);
            y = char_to_int(base_in[1]);
            in_base = int_conversion(x, y);
            x = 0;
            y = 0;
        }
        else{

            in_base = char_to_int(base_in[0]);
        }
        while (buffer[i] != ' '){
            number[j] = buffer[i];
            i++;
            j++;

        }
        int  q;
        q=j;
        j=0;
        while (number[j] != '\0'){
            actual_number[j] = char_to_int(number[j]);
            end_number = end_number + pow(in_base, q-1) * actual_number[j];
            j++;
            q--;
        }
        j = 0;
        i++;

        while (buffer[i] != '\n' && buffer[i] != '\0'){
            base_out[j] = buffer[i];
            i++;
            j++;
        }
        if (base_out[1] != '\0'){
            x = char_to_int(base_out[0]);
            y = char_to_int(base_out[1]);
            out_base = int_conversion(x, y);
            x = 0;
            y = 0;
        }
        else{
            out_base = char_to_int(base_out[0]);
        }
        j = 0;
        i++;

        base_conversion(end_number, out_base);
    }
    else{
        while (buffer[i] != '\n' && buffer[i] != '\0'){
            i++;
        }
    }
    i++;
}

return;
}

int char_to_int(char c){

char map[] = "0123456789abcdefghijklmnopqrstuvwxyz";
int result = -1;
char *next = map;

while(*next != '\0'){
    if(*next == c){
        result = next - map;
        break;
    }
    next++;
}
return result;
}

int int_conversion(int x, int y){
int value;

value = (x * 10) + y;

return value;
}

void base_conversion(int end_number, int out_base){
int remainder[100];
char map[] = "0123456789abcdefghijklmnopqrstuvwxyz";
int index = 0;
int i;

while (end_number != 0){
    remainder[index] = end_number % out_base;
    end_number = end_number / out_base;
    index++;
}
for (i=0; i<index; i++){
    printf("%c", map[remainder[index-1]]);
}
printf("\n");
return;
}

最佳答案

OP 的 base_conversion() 很困惑。

循环重复打印相同的字符。

for (i=0; i<index; i++){
    printf("%c", map[remainder[index-1]]);  // Why same character?
}

代码使用带符号的数学和%,并且可以创建可用作数组索引的negative remainders

remainder[index] = end_number % out_base;  // result may be negative.
...
printf("%c", map[remainder[index-1]]);     // accessing out of bounds with negative
<小时/>

建议的简化。

void base_conversion_helper(unsigned end_number, int out_base){
  if (end_number >= out_base) base_conversion_helper(end_number/out_base, out_base);
  putchar("0123456789abcdefghijklmnopqrstuvwxyz"[end_number % outbase]);
}

void base_conversion(unsigned end_number, int out_base){
  assert(out_base >= 2 && out_base <= 36);
  base_conversion_helper(end_number, out_base);
  putchar('\n');
}

关于c - C 语言的基本更改程序符合要求,但不显示任何输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42238239/

相关文章:

C 编程 : Error in program. 不会显示用户输入的文件的最大/最小/平均值

rjava依赖包安装段错误(core dumped)

c - 为什么要用这个宏?

c - 如何获取execlp的退出代码

c - 如何从文件类型中读取特定的字节选择?

c - 我的 C 程序生成段错误,我不明白为什么

C++ new() 在调用 ctor 之前崩溃

c - 读取链表节点内的字符数组?

c - C 中的伪泛型

python - 行结束以及对文本文件的读取和写入