我最近刚接触编程,但这项任务已被证明是我最难的。该程序假定使用以下格式读取.txt文件
input_base number output_base
并输出结果。碱基的范围仅为2-36例如:
input: 2 10 4
output: 2
我的程序读取行的每个部分并分别存储它们。然后,我将完成将数字转换为输出基础的步骤,然后将其打印回来。我的问题是程序运行正常并打印所有存储的值和计算值,但是一旦我添加了我的" base_conversion"功能该程序不再有效,我的朋友甚至说它给了他一个分段错误。我真的不知道是什么原因造成的。任何帮助,将不胜感激。谢谢。
#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;
}
答案 0 :(得分:0)
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');
}