I'm writing some code for school that mimics a simple CPU. I know what segmentation faults are but I can't find what's wrong with my code.
There is nothing wrong with the header or main, I'm including it for referrence
Here is my header:
#define NUM_BYTES (16 * 1024)
#define BYTES_PER_WORD 2
#define WORDS_PER_INSTRUCTION 2
#define NUM_WORDS (NUM_BYTES / BYTES_PER_WORD)
#define NUM_INSTRUCTIONS (NUM_WORDS / WORDS_PER_INSTRUCTION)
#define R0 0
#define R1 1
#define R2 2
#define R3 3
#define R4 4
#define R5 5
typedef unsigned short Machine_word;
typedef enum { PLUS, MINUS, TIMES, DIV, NEG, AND, OR, NOT, LI, LW, SW,
MOVE, CMP, READ, WRITE, HALT } Opcode;
typedef enum { LT, LE, GT, GE, EQ, NE } Comparison;
typedef struct {
Opcode opcode;
Comparison comparison;
unsigned short reg1;
unsigned short reg2;
unsigned short reg3;
unsigned short addr_or_imm;
} Instruction;
void print_instruction(Instruction instr);
int disassemble(const Machine_word memory[], int starting_addr, int num_instrs,
Instruction instrs[], int *const valid_instrs);
int valid_instruction(Machine_word instr_word1, Machine_word instr_word2);
int assemble(unsigned short opcode, unsigned short comparison,
unsigned short reg1, unsigned short reg2, unsigned short reg3,
unsigned short addr_or_imm, Machine_word *const word1,
Machine_word *const word2);
My main:
#include<stdio.h>
#include "header.h"
#define PROGRAM_SIZE 10
int main() {
Machine_word words[NUM_WORDS]= {0x10a5, 0, /* 2 words of 1st instr. */
0x80c0, 0x03ff, /* 2 words of 2nd instr. */
0xa040, 0x00d8, /* etc. */
0x5008, 0,
0x7080, 0,
0xc528, 0x21f8,
0x9080, 0x2718,
0xb058, 0,
0xe100, 0,
0xf000, 0};
/* double braces because it's an array of structures */
Instruction instrs[NUM_INSTRUCTIONS]= {{0}};
int i, num_valid_instrs= 0;
disassemble(words, 0, PROGRAM_SIZE, instrs, &num_valid_instrs);
for (i= 0; i < num_valid_instrs; i++) {
print_instruction(instrs[i]);
printf("\n");
}
My functions: (the first function has no issue!)
#include<stdio.h>
#include "machine.h"
void print_instruction(Instruction instr) {
if (instr.opcode == HALT) {
printf("halt");
} else if (instr.opcode == PLUS) {
printf("plus\tR%hu\tR%hu\tR%hu", instr.reg1, instr.reg2, instr.reg3);
} else if (instr.opcode == MINUS) {
printf("minus\tR%hu\tR%hu\tR%hu", instr.reg1, instr.reg2, instr.reg3);
} else if (instr.opcode == TIMES) {
printf("times\tR%hu\tR%hu\tR%hu", instr.reg1, instr.reg2, instr.reg3);
} else if (instr.opcode == DIV) {
printf("div\tR%hu\tR%hu\tR%hu", instr.reg1, instr.reg2, instr.reg3);
} else if (instr.opcode == NEG) {
printf("neg\tR%hu\tR%hu", instr.reg1, instr.reg2);
} else if (instr.opcode == AND) {
printf("and\tR%hu\tR%hu\tR%hu", instr.reg1, instr.reg2, instr.reg3);
} else if (instr.opcode == OR) {
printf("or\tR%hu\tR%hu\tR%hu", instr.reg1, instr.reg2, instr.reg3);
} else if (instr.opcode == NOT) {
printf("not\tR%hu\tR%hu", instr.reg1, instr.reg2);
} else if(instr.opcode == LI) {
printf("li\tR%hu\t%05hu", instr.reg1, instr.addr_or_imm);
}else if (instr.opcode == LW) {
printf("lw\tR%hu\t%05hu", instr.reg1, instr.addr_or_imm);
} else if (instr.opcode == SW) {
printf("sw\tR%hu\t%05hu", instr.reg1, instr.addr_or_imm);
} else if (instr.opcode == MOVE) {
printf("move\tR%hu\tR%hu", instr.reg1, instr.reg2);
} else if (instr.opcode == CMP) {
printf("cmp %d\tR%hu\tR%hu\t%05hu", (int)instr.comparison, instr.reg1, instr.reg2, instr.addr_or_imm);
} else if (instr.opcode == READ) {
printf("read\tR%hu", instr.reg1);
} else if (instr.opcode == WRITE) {
printf("write\tR%hu", instr.reg1);
}
}
int disassemble(const Machine_word memory[], int starting_addr, int num_instrs, Instruction instrs[], int *const valid_instrs) {
int i, count= 0, index= 0;
if(starting_addr % 4 != 0)
return 0;
if(starting_addr < 0 || starting_addr > 16384)
return 0;
if(starting_addr + num_instrs*4 > 16384)
return 0;
if(memory == NULL || instrs == NULL)
return 0;
for(i = starting_addr/2; i < i + num_instrs*2; i += 2){
/*read instructions*/
Machine_word opcode = memory[i];
Machine_word comparison = memory[i];
Machine_word reg1 = memory[i];
Machine_word reg2 = memory[i];
Machine_word reg3 = memory[i];
Machine_word mem_addr = memory[i + 1];
opcode = (opcode & 0xf000) >> 12;
comparison = (comparison & 0x0e00) >> 9;
reg1 = (reg1 & 0x01c0) >> 6;
reg2 = (reg2 & 0x0038) >> 3;
reg3 = (reg3 & 0x0007);
if(opcode == 0) {
instrs[index].opcode = PLUS;
instrs[index].reg1 = reg1;
instrs[index].reg2 = reg2;
instrs[index].reg3 = reg3;
} else if(opcode == 1) {
instrs[index].opcode = MINUS;
instrs[index].reg1 = reg1;
instrs[index].reg2 = reg2;
instrs[index].reg3 = reg3;
} else if(opcode == 2) {
instrs[index].opcode = TIMES;
instrs[index].reg1 = reg1;
instrs[index].reg2 = reg2;
instrs[index].reg3 = reg3;
} else if(opcode == 3) {
instrs[index].opcode = DIV;
instrs[index].reg1 = reg1;
instrs[index].reg2 = reg2;
instrs[index].reg3 = reg3;
} else if(opcode == 4) {
instrs[index].opcode = NEG;
instrs[index].reg1 = reg1;
instrs[index].reg2 = reg2;
} else if(opcode == 5) {
instrs[index].opcode = AND;
instrs[index].reg1 = reg1;
instrs[index].reg2 = reg2;
instrs[index].reg3 = reg3;
} else if(opcode == 6) {
instrs[index].opcode = OR;
instrs[index].reg1 = reg1;
instrs[index].reg2 = reg2;
instrs[index].reg3 = reg3;
} else if(opcode == 7) {
instrs[index].opcode = NOT;
instrs[index].reg1 = reg1;
instrs[index].reg2 = reg2;
} else if(opcode == 8){
instrs[index].opcode = LI;
instrs[index].reg1 = reg1;
instrs[index].addr_or_imm = mem_addr;
} else if(opcode == 9) {
instrs[index].opcode = LW;
instrs[index].reg1 = reg1;
instrs[index].addr_or_imm = mem_addr;
} else if(opcode == 10) {
instrs[index].opcode = SW;
instrs[index].reg1 = reg1;
instrs[index].addr_or_imm = mem_addr;
} else if(opcode == 11) {
instrs[index].opcode = MOVE;
instrs[index].reg1 = reg1;
instrs[index].reg2 = reg2;
} else if(opcode == 12) {
instrs[index].opcode = CMP;
instrs[index].comparison = (Comparison)comparison;
instrs[index].reg1 = reg1;
instrs[index].reg2 = reg2;
} else if(opcode == 13) {
instrs[index].opcode = READ;
instrs[index].reg1 = reg1;
} else if(opcode == 14) {
instrs[index].opcode = WRITE;
instrs[index].reg1 = reg1;
} else if(opcode == 15) {
instrs[index].opcode = HALT;
}
index++;
count++;
}
*valid_instrs = count;
return 1;
}
Only the second function, which does bit manipulations, has issues
apologies for it being so long.
As told in comments above, the error is in i < i + num_instrs*2 condition. Note, the value of 'i' is not frizzed in i + num_instrs*2 - it is incremented on each step - i. e. condition will looks like 0 < 0 +10*2, 2 < 2 +10*2, 4 < 4 +10*2. So you need to use initial value starting_addr/2 in condition:
Please change
for(i = starting_addr/2; i < i + num_instrs*2; i += 2){
to
for(i = starting_addr/2; i < starting_addr/2 + num_instrs*2; i += 2){
Related
I have to make the labyrinth program, which works in Windows under Code Blocks; but when I want to run it in Linux it doesn't work.
When I start debugging, it works correctly until line 63 returns and crashes.
Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
Quit
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define max_col 50
#define max_row 50
#define max_numOflabyrinth 50
#define max_checkPt 50
#define MAX_LINES 10
#define MAX_LINE_LENGTH 2506
enum{UP, DOWN, LEFT, RIGHT};
typedef struct POSITION{
int x;
int y;
} POSITION;
typedef struct PFAD{
POSITION* pos;
int step;
} PFAD;
typedef struct CHECKPOINT{
int seqNum;
int total_span;
int next_span;
int stepNum;
POSITION pos;
POSITION next_steps[3];
//CHECKPOINT* previous_checkPt; //C don't support this.
} CHECKPOINT;
typedef struct LIS_CHECKPOINT{
CHECKPOINT checkPt;
CHECKPOINT* prev_checkPt;
} LIS_CHECKPOINT;
typedef struct LABYRINTH{
char name[10];
char** landkarte; //2D-array landkarte[y][x] y=row x=col
int max_x;
int max_y;
int max_step; //max. laufzeit für while()
POSITION start;
POSITION end;
} LABYRINTH;
int pos_cmp(POSITION a, POSITION b){
if(a.x == b.x && a.y == b.y){return 1;}
else{return 0;}
}
void pos_set(POSITION* des, const POSITION src){
des->x = src.x;
des->y = src.y;
}
void init_LABYRINTH(LABYRINTH* laby){
laby->landkarte=NULL;
laby->max_x=0;
laby->max_y=0;
laby->max_step=0;
laby->start.x=0;
laby->start.y=0;
laby->end.x=0;
laby->end.y=0;
}
/*
int erkunden(LABYRINTH* labyrinth){
POSITION cur_pos;
pos_set(&cur_pos, labyrinth->start);
POSITION check_steps[3]; //only three directions
PFAD footprt;
footprt.pos = calloc(labyrinth->max_x*labyrinth->max_y, sizeof(POSITION));
footprt.step = 0;
CHECKPOINT* prt_last_
}
*/
int erkunden(LABYRINTH* labyrinth){
fflush(stdin);
POSITION cur_pos;
//initialisieren
pos_set(&cur_pos, labyrinth->start);
POSITION check_steps[3]; //max. möglich 3 Richtung
PFAD footprt;
footprt.pos = calloc(labyrinth->max_x*labyrinth->max_y, sizeof(POSITION));
footprt.step = 0;
CHECKPOINT* ptr_last_checkPt;
LIS_CHECKPOINT* lis_checkPt;
lis_checkPt = calloc(max_checkPt, sizeof(LIS_CHECKPOINT));
int total_checkPt=0;
int i, j;
int if_break=1;
int numOFsteps=0;
int loopcontroll=0;
char** map= calloc(labyrinth->max_y, sizeof(char*));
for(i=0;i<labyrinth->max_y;i++){
map[i]=calloc(labyrinth->max_x, sizeof(char));
}
while(!pos_cmp(cur_pos, labyrinth->end) && if_break){
map[cur_pos.y][cur_pos.x]=1;
pos_set(&footprt.pos[footprt.step], cur_pos);
//oben
if(cur_pos.y-1>=0 && labyrinth->landkarte[cur_pos.y-1][cur_pos.x]!='w' && map[cur_pos.y-1][cur_pos.x]!=1){
check_steps[numOFsteps].x=cur_pos.x;
check_steps[numOFsteps].y=cur_pos.y-1;
numOFsteps++;
}
//unten
if(cur_pos.y+1<labyrinth->max_y && labyrinth->landkarte[cur_pos.y+1][cur_pos.x]!='w' && map[cur_pos.y+1][cur_pos.x]!=1){
check_steps[numOFsteps].x=cur_pos.x;
check_steps[numOFsteps].y=cur_pos.y+1;
numOFsteps++;
}
//links
if(cur_pos.x-1>=0 && labyrinth->landkarte[cur_pos.y][cur_pos.x-1]!='w' && map[cur_pos.y][cur_pos.x-1]!=1){
check_steps[numOFsteps].x=cur_pos.x-1;
check_steps[numOFsteps].y=cur_pos.y;
numOFsteps++;
}
//rechts
if(cur_pos.x+1<labyrinth->max_x && labyrinth->landkarte[cur_pos.y][cur_pos.x+1]!='w' && map[cur_pos.y][cur_pos.x+1]!=1){
check_steps[numOFsteps].x=cur_pos.x+1;
check_steps[numOFsteps].y=cur_pos.y;
numOFsteps++;
}
if(numOFsteps==0){
do{
ptr_last_checkPt=lis_checkPt[ptr_last_checkPt->seqNum].prev_checkPt;
j=(++ptr_last_checkPt->next_span);
}
while(ptr_last_checkPt->next_span > ptr_last_checkPt->total_span-1);
pos_set(&cur_pos, ptr_last_checkPt->next_steps[j]);
footprt.step=ptr_last_checkPt->stepNum;
}
else if(numOFsteps==1){
pos_set(&cur_pos, check_steps[0]);
}
else {
ptr_last_checkPt = &lis_checkPt[total_checkPt].checkPt;
ptr_last_checkPt->seqNum=total_checkPt;
if(total_checkPt==0){
lis_checkPt[total_checkPt].prev_checkPt=NULL;}
else{
lis_checkPt[total_checkPt].prev_checkPt=&lis_checkPt[total_checkPt-1].checkPt;
}
for(i=0;i<numOFsteps;i++){
pos_set(&ptr_last_checkPt->next_steps[i], check_steps[i]);
}
pos_set(&ptr_last_checkPt->pos, cur_pos);
ptr_last_checkPt->total_span=numOFsteps;
ptr_last_checkPt->next_span=0;
ptr_last_checkPt->stepNum=footprt.step;
pos_set(&cur_pos, ptr_last_checkPt->next_steps[0]);
total_checkPt++;
}
numOFsteps=0;
footprt.step++;
loopcontroll++;
if(loopcontroll>labyrinth->max_step) if_break=0;
}//end loop
//save the solution in the labyrith
for(i=0;i<footprt.step;i++){
labyrinth->landkarte[footprt.pos[i].y][footprt.pos[i].x]='*';
}
//free
free(footprt.pos);
free(lis_checkPt);
for(i=0;i<labyrinth->max_y;i++) free(map[i]);
free(map);
//rückgabewert
if(loopcontroll>labyrinth->max_step) return 1;
else return 0;
}
FILE* open_labyrinth_file(char* file_name){
FILE* file_landkarte = fopen(file_name, "r");
if (file_landkarte==NULL){
printf("Fehler bei Einlesen der Text-Datei\n");
return NULL;
}
printf("\"%s\" eingelesen!\n",file_name);
return file_landkarte;
}
LABYRINTH* load_labyrinth(const char* map_line, int max_x_size, int max_y_size){
LABYRINTH* labyrinth=NULL;
init_LABYRINTH(labyrinth);
int map_size = strlen(map_line)-1; //
int i=0,j=0,k=0; //variables to help
labyrinth->max_step=0;
int b=0, z=0;
//name for the Labyrinth
for(i=0;i<6;i++){
if(map_line[i] == '='){
labyrinth->name[i] = '\0';
break;
}else{
labyrinth->name[i] = map_line[i];
}
}
k = strlen(labyrinth->name)+1;
map_size -= k;
for(i=k; i<max_x_size; i++){
//if the labyrinth is not quadratic i.e. has an exact root
if(i*i == map_size){
labyrinth->max_x=i;
labyrinth->max_y=i;
break;
}
if(i*i>map_size){
printf("Dimensions incorrect: map not quaratic!: %s \n", labyrinth->name);
return NULL;
}
}
//loop to check that the maze contains one exit and one entrance
for(i=k;i<map_size;i++){
if(map_line[i]=='b'){b=1;}
if(map_line[i]=='z'){z=1;}
}
if(b!=1||z!=1){
printf("The map not contains an start and an end: %s \n", labyrinth->name);
return NULL;
}else{
printf("The map contains an start and an end: %s \n", labyrinth->name);
}
labyrinth->landkarte = calloc(labyrinth->max_y, sizeof(char*));
for(i=0;i<labyrinth->max_y;i++){
labyrinth->landkarte[i] = calloc(labyrinth->max_x, sizeof(char*));
}
for(i=0;i<labyrinth->max_y;i++){
for(j=0;j<labyrinth->max_x;j++){
labyrinth->landkarte[i][j]=map_line[i*labyrinth->max_x+j+k];
if(labyrinth->landkarte[i][j]=='b'){
labyrinth->start.x=j;
labyrinth->start.y=i;
}
if(labyrinth->landkarte[i][j]=='z'){
labyrinth->end.x=j;
labyrinth->end.y=i;
}
if(labyrinth->landkarte[i][j]=='k'){
labyrinth->max_step+=2;
}
}
}
return labyrinth;
}
/*
LABYRINTH* load_labyrinth(const char* landkarte_zeile, int max_x_size, int max_y_size){
int landkarte_size=strlen(landkarte_zeile);
int i,j,k;
LABYRINTH* labyrinth;
init_LABYRINTH(labyrinth);
labyrinth->max_step=0;
if(max_x_size!=max_y_size){
printf("Dimensionsangaben fehlerhaft: max_x und max_y muss identisch sein!/n");
return NULL;
}
for(i=0;i<5;i++){
if(landkarte_zeile[i]=='='){
labyrinth->name[i]='\0';
break;
}
labyrinth->name[i] = landkarte_zeile[i];
}
k=strlen(labyrinth->name)+1;
landkarte_size-=k;
for(i=3;i<=max_x_size;i++){
if(i*i==landkarte_size){
labyrinth->max_x=i;
labyrinth->max_y=i;
break;
}
if(i*i>landkarte_size){
printf("Dimensionen fehlerhaft: Landkarte nicht quaratisch!: %s \n",labyrinth->name);
return NULL;
}
}
labyrinth->landkarte = calloc(labyrinth->max_y, sizeof(char*));
for(i=0;i<labyrinth->max_y;i++){
labyrinth->landkarte[i] = calloc(labyrinth->max_x, sizeof(char*));
}
for(i=0;i<labyrinth->max_y;i++){
for(j=0;j<labyrinth->max_x;j++){
labyrinth->landkarte[i][j]=landkarte_zeile[i*labyrinth->max_x+j+k];
if(labyrinth->landkarte[i][j]=='b'){
labyrinth->start.x=j;
labyrinth->start.y=i;
}
if(labyrinth->landkarte[i][j]=='z'){
labyrinth->end.x=j;
labyrinth->end.y=i;
}
if(labyrinth->landkarte[i][j]=='k'){
labyrinth->max_step+=2;
}
}
}
return labyrinth;
}
*/
/*
//old
char* print_labyrinth(LABYRINTH* labyrinth){
if(labyrinth==NULL){
printf("Plot-Fehler: kein Labyrith gefunden.\n");
return;
}
char buffer[100];
char character = 'c';
int i,j;
printf("Labyrinth: %s\n", labyrinth->name);
//strcat(buffer, labyrinth->name);
for(i=0;i<labyrinth->max_y;i++){
for(j=0;j<labyrinth->max_x;j++){
if(labyrinth->landkarte[i][j]=='w'){
character = '#';
printf(character);
strncat(buffer, &character, 1);
}
else if(labyrinth->landkarte[i][j]=='k'){
printf(" ");
//strcat(buffer, ' ');
}
else{
printf("%c", labyrinth->landkarte[i][j]);
//strcat(buffer, labyrinth->landkarte[i][j]);
}
}
printf("\n");
//strcat(buffer,"\n");
}
printf("Start: (%i,%i) ", labyrinth->start.x,labyrinth->start.y);
printf("End: (%i,%i)\n", labyrinth->end.x,labyrinth->end.y);
return buffer;
} */
//new
char* print_labyrinth(LABYRINTH* labyrinth) {
if (labyrinth == NULL) {
return strdup("Plot-Fehler: kein Labyrinth gefunden.\n");
}
char* buffer = malloc(sizeof(char) * 10000);
if (buffer == NULL) {
// handle error
}
int offset = 0;
offset += sprintf(buffer + offset, "Labyrinth: %s\n", labyrinth->name);
for (int i = 0; i < labyrinth->max_y; i++) {
for (int j = 0; j < labyrinth->max_x; j++) {
if (labyrinth->landkarte[i][j] == 'w') {
offset += sprintf(buffer + offset, "#");
} else if (labyrinth->landkarte[i][j] == 'k') {
offset += sprintf(buffer + offset, " ");
} else {
offset += sprintf(buffer + offset, "%c", labyrinth->landkarte[i][j]);
}
}
offset += sprintf(buffer + offset, "\n");
}
offset += sprintf(buffer + offset, "Start: (%i,%i) End: (%i,%i)\n",
labyrinth->start.x, labyrinth->start.y, labyrinth->end.x, labyrinth->end.y);
printf("%s", buffer);
return buffer;
}
void save_to_file(char* text, char* filename) {
FILE* file = fopen(filename, "wt");
if (file == NULL) {
printf("Error opening file.\n");
return;
}
fprintf(file, "%s", text);
fclose(file);
printf("Text saved to file %s\n", filename);
}
int main()
{
/*
int i,j,k;
int *ergibnis;
int total_labyr=0;
char charbuff[2506]={'\0'};
char* solution = malloc(sizeof(char) * 10000);
int offset = 0;
LABYRINTH** labyrinth[max_numOflabyrinth];
FILE* file_landkarte = open_labyrinth_file("labyrinth_karte.txt");
if(fgets(charbuff,2506,file_landkarte)!=EOF){
labyrinth[total_labyr]=load_labyrinth(charbuff, 50, 50);
total_labyr++;
}
ergibnis = calloc(total_labyr, sizeof(int));
for(i=0;i<total_labyr;i++){
if(!erkunden(labyrinth[i])){ // ! weil erkunden liefert 0 wenn erfolgreich ist
ergibnis[i] = 1;
offset += sprintf(solution + offset, print_labyrinth(labyrinth[j]));
}
}
print_labyrinth(labyrinth);
save_to_file(solution, "solvelab.txt");
*/
LABYRINTH* labyrinth[MAX_LINES];
init_LABYRINTH(&labyrinth);
int i=0, j=0;
char charbuff[2506];
char* solution;
solution =(char*)malloc(sizeof(char) * 2506);
int offset = 0;
FILE* file_landkarte = open_labyrinth_file("labyrinth_karte.txt");
/* for(j=0; j< MAX_LINES; j++){
fflush(stdin);
init_LABYRINTH(labyrinth[j]);
}
*/
while (fgets(charbuff, MAX_LINE_LENGTH, file_landkarte) != NULL) {
labyrinth[i] = load_labyrinth(charbuff, max_row, max_col);
if(labyrinth[i]!=NULL){
print_labyrinth(labyrinth[i]);
if(!erkunden(labyrinth[i])){ // ! weil erkunden liefert 0 wenn erfolgreich ist
//solution = print_labyrinth(labyrinth[j]);
//strcpy(,print_labyrinth(labyrinth[j]));
offset += sprintf(solution + offset, print_labyrinth(labyrinth[i]));
printf("labyrinth solved!\n");
save_to_file(solution, "solvelab.txt");
}
else{
printf("labyrinth has no solution!\n");
}
}else{
printf("no posible: %i \n",j);
}
i++;
}
/*
for (j = 0; j < 6 ;j ++){
// labyrinth = load_labyrinth(lines[j],max_row, max_col);
if(labyrinth[j]!=NULL){
print_labyrinth(labyrinth[j]);
if(!erkunden(labyrinth[j])){ // ! weil erkunden liefert 0 wenn erfolgreich ist
//solution = print_labyrinth(labyrinth[j]);
//strcpy(,print_labyrinth(labyrinth[j]));
offset += sprintf(solution + offset, print_labyrinth(labyrinth[j]));
printf("labyrinth solved!\n");
//save_to_file(solution, "solvelab.txt");
}
else{
printf("labyrinth has no solution!\n");
}
}else{
printf("no posible\n: %i ",j);
}
}
*/
//save_to_file(solution, "solvelab.txt");
fclose(file_landkarte);
return 0;
}
labyrinth_karte.txt
L3=wwwwwwwskkkwwwkwswwskwwwwwkkzwwwwwww
L4=wwwwbwwskkkwwwkwswwskwwwwwkkswwwwwww
L5=wwwbwwwskkkwwwwwswwskwwwwwkkzwwwwwww
L6=wwwbwwkskkkwwwkwswwskwwwwwkkzwwwwwww
L1=wwwbwwwskkkwwwkwswwskwwwwwkkzwwwwwww
L2=wwwwwwwwwswkkkswwkwkwzwwwkkkwwswbkwwswkwwkkkkwkwwswwkkkwwwwwwwww
int I2C_Master_ReadReg(unsigned char dev_addr, unsigned char reg_addr, unsigned char count, unsigned char *pData, void (* Sub)(void)) {
uint8_t cnt;
start();
sda(dev_addr);
if (!(dev_addr == 0x10)) {
cnt = 0;
}
if (count > 0x05) {
cnt = 0;
}
if (clk() == 1) {
I2C_Ack_Error(1);
return -1;
}
sda(reg_addr + 0);
if (clk() == 1) {
I2C_Ack_Error(2);
return -2;
}
start();
sda(dev_addr + 1);
if (clk() == 1) {
I2C_Ack_Error(3);
return -3;
}
for (cnt = 0; cnt < count; ++cnt) {
*(pData + cnt) = read();
//printf("D: %x\n\r", read());
if (clk() == 0) {
I2C_Ack_Error(4);
return -4;
}
stop();
}
return 0;
}
Currently I have code for converting a char pointer that holds binary characters and converts them to hex and octal representations.
The way my code has progressed, I now have an integer binary number, it is no longer a char pointer, but I still want to convert it to either hex and octal.
So, the code I have converts: "1101" into a hex or octal equivalent, but I current have 1101 as an integer value, but still want to convert that to hex or octal.
I do not know how to rewrite the code to accept an integer binary as an argument instead of a char * binary. Or how to change the int I have into a char pointer so that it can successfully go through the conversion function.
Here's the code for the function call that current works with a char pointer to a binary representation of a number, converting it into an octal or hex representation:
output = binaryBaseChange(output, 3); //for binary to octal conversion
output = binaryBaseChange(output, 4); //for binary to hex conversion
Here's the conversion function using the char * bin argument:
char * binaryBaseChange (char * bin, int size_of_digit) {
int offset = 0;
int i = 0;
int j = 4;
int k = 0;
int number_of_hex_digits = 0;
char* substr;
char * out;
int r = 0;
while(((strlen(bin) + offset) % size_of_digit) != 0) {
offset++;
}
out = malloc((strlen(bin) + offset) / size_of_digit+1);
out[(strlen(bin)+offset)/size_of_digit] = '\0';
r = (int)strlen(bin) + offset;
bin = pad_bin(bin, r);
number_of_hex_digits = (int)strlen(bin)/size_of_digit;
while (k < number_of_hex_digits) {
substr = strndup(bin+i, j);
substr[size_of_digit] = '\0';
i = i + size_of_digit;
j = j + size_of_digit;
if (size_of_digit == 4) {
out[k] = single_digit_bin_to_hex(substr);
} else if (size_of_digit == 3) {
out[k] = single_digit_bin_to_oct(substr);
}
free(substr);
k++;
}
free(bin);
out[k] = '\0';
return out;
}
Here are the functions called within the conversion function:
char single_digit_bin_to_oct (char * bin_dig) {
if (strcmp(bin_dig, "000") == 0) {
return '0';
} else if (strcmp(bin_dig, "001") == 0) {
return '1';
} else if (strcmp(bin_dig, "010") == 0) {
return '2';
} else if (strcmp(bin_dig, "011") == 0) {
return '3';
} else if (strcmp(bin_dig, "100") == 0) {
return '4';
} else if (strcmp(bin_dig, "101") == 0) {
return '5';
} else if (strcmp(bin_dig, "110") == 0) {
return '6';
} else {
return '7';
}
}
char single_digit_bin_to_hex (char *bin_dig) {
if (strcmp(bin_dig, "0000") == 0) {
return '0';
} else if (strcmp(bin_dig, "0001") == 0) {
return '1';
} else if (strcmp(bin_dig, "0010") == 0) {
return '2';
} else if (strcmp(bin_dig, "0011") == 0) {
return '3';
} else if (strcmp(bin_dig, "0100") == 0) {
return '4';
} else if (strcmp(bin_dig, "0101") == 0) {
return '5';
} else if (strcmp(bin_dig, "0110") == 0) {
return '6';
} else if (strcmp(bin_dig, "0111") == 0) {
return '7';
} else if (strcmp(bin_dig, "1000") == 0) {
return '8';
} else if (strcmp(bin_dig, "1001") == 0) {
return '9';
} else if (strcmp(bin_dig, "1010") == 0) {
return 'A';
} else if (strcmp(bin_dig, "1011") == 0) {
return 'B';
} else if (strcmp(bin_dig, "1100") == 0) {
return 'C';
} else if (strcmp(bin_dig, "1101") == 0) {
return 'D';
} else if (strcmp(bin_dig, "1110") == 0) {
return 'E';
} else if (strcmp(bin_dig, "1111") == 0){
return 'F';
} else {
fprintf(stderr, "ERROR");
return 'X';
}
}
char * pad_bin (char * bin, int n) {
int bin_len = (int)strlen(bin);
int dif = n - bin_len;
char * new_bin = malloc(n + 1);
int i = 0;
int j = 0;
memset(new_bin,0,n+1);
if (n == 0) {
return bin;
} else for (;i <= n; i++) {
if (i < dif) {
new_bin[i] = '0';
} else {
new_bin[i] = bin[j];
j++;
}
}
return new_bin;
}
This creates a fraction and assigns negative signs accordingly. however, when i want to print out the whole numbers, numerators and denominators, the negative signs aren't passed into the the fractionPrint function. Therefore, only positive values are printed out.
struct fraction fractionCreate(int numerator, int denominator)
{
struct fraction result;
if (denominator == 0)
{
result.numerator = 0;
result.denominator = 0;
}
else
{
if (numerator*denominator <0)
{
int tempNumerator = fabs(numerator);
int tempDenominator = fabs(denominator);
int temp = 0;
while(tempDenominator != 0)
{
temp = tempDenominator;
tempDenominator = tempNumerator%tempDenominator;
tempNumerator = temp;
}
int GCD = tempNumerator;
numerator = fabs(numerator);
denominator = fabs(denominator);
//Num is larger than denom
if(numerator>=denominator)
{
//whole number
if(numerator%denominator == 0)
{
result.wholeNumber = (numerator/denominator)*-1;
result.numerator = 1;
result.denominator = 1;
}
//mixed number
else
{
result.wholeNumber = ((numerator - (numerator%denominator)) /denominator)*-1;
numerator = (numerator%denominator);
if (numerator%GCD ==0 && denominator%GCD ==0)
{
result.numerator = numerator/GCD;
result.denominator= denominator/GCD;
}
else
{
result.numerator = numerator;
result.denominator = denominator;
}
}
}
//simple fraction
else
{
if (numerator%GCD ==0 && denominator%GCD ==0)
{
result.numerator = (numerator/GCD)*-1;
result.denominator= denominator/GCD;
}
else
{
result.numerator = numerator*-1;
result.denominator = denominator;
}
}
}
if (numerator*denominator > 0)
{
int tempNumerator = fabs(numerator);
int tempDenominator = fabs(denominator);
int temp = 0;
while(tempDenominator != 0)
{
temp = tempDenominator;
tempDenominator = tempNumerator%tempDenominator;
tempNumerator = temp;
}
int GCD = tempNumerator;
numerator = fabs(numerator);
denominator = fabs(denominator);
//Num is larger than denom
if(numerator>=denominator)
{
//whole number
if(numerator%denominator == 0)
{
result.wholeNumber = numerator/denominator;
result.numerator = 1;
result.denominator = 1;
}
//mixed number
else
{
result.wholeNumber = (numerator - (numerator%denominator)) /denominator;
numerator = (numerator%denominator);
if (numerator%GCD ==0 && denominator%GCD ==0)
{
result.numerator = numerator/GCD;
result.denominator= denominator/GCD;
}
else
{
result.numerator = numerator;
result.denominator = denominator;
}
}
}
//simple fraction
else
{
if (numerator%GCD ==0 && denominator%GCD ==0)
{
result.numerator = numerator/GCD;
result.denominator= denominator/GCD;
}
else
{
result.numerator = numerator;
result.denominator = denominator;
}
}
}
}
return result;
}
void fractionPrint(struct fraction f)
{
if (f.numerator == 0 && f.denominator == 0)
{
printf("Divide by zero!\n");
}
else
{
// There IS a whole number
if (f.wholeNumber !=0)
{
int tempNumerator;
if (f.numerator <0)
{
tempNumerator = f.numerator *-1;
}
//ONLY whole number
if (tempNumerator == 1 && f.denominator ==1 )
{
printf("%d\n", f.wholeNumber);
}
//Mixed number
else
{
printf("%d %d/%d\n", f.wholeNumber, f.numerator, f.denominator);
}
}
//fraction only
else
{
printf("%d/%d\n", f.numerator, f.denominator);
}
}
}
int main (void)
{
struct fraction a, b, c, d, r, bad;
a = fractionCreate (-5, -6);
fractionPrint(a);
b = fractionCreate (-10, 2);
fractionPrint(b);
c = fractionCreate (56, -160);
fractionPrint(c);
d = fractionCreate (-35, 150);
fractionPrint(d);
bad = fractionCreate (8, 0);
fractionPrint(bad);
return 0;
}
The lost sign comes from:
result.wholeNumber = (numerator/denominator)*-1;
This is inside a block where numerator * denominator < 0, so this line always sets wholeNumber to be positive. Take out the -1.
Also, you have garbage in some other places because you don't initialize wholeNumber to 0 when it should be. And there is a potential problem due to the use of fabs and rounding that will show up when you try to store larger values; use integer negation instead of fabs.
My header file:
#ifndef __FRACTION_H__
#define __FRACTION_H__
struct fraction{
int wholeNumber;
int numerator;
int denominator;
};
struct fraction fractionCreate(int numerator, int denominator);
struct fraction fractionAdd(struct fraction a, struct fraction b);
struct fraction fractionSubtract(struct fraction a, struct fraction b);
struct fraction fractionMultiply(struct fraction a, struct fraction b);
struct fraction fractionDivide(struct fraction a, struct fraction b);
void fractionPrint(struct fraction f);
#endif
The 2 errors i keep getting in my .c file are:
Undefined symbols for architecture x86_64: "_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
my .c file
#include <math.h>
#include <stdio.h>
#include "fraction.h"
struct fraction fractionCreate(int numerator, int denominator)
{
struct fraction result;
result.wholeNumber = 0;
if (denominator == 0)
{
result.numerator = 0;
result.denominator = 0;
}
else
{
if (numerator*denominator <0)
{
int tempNumerator = fabs(numerator);
int tempDenominator = fabs(denominator);
int temp = 0;
while(tempDenominator != 0)
{
temp = tempDenominator;
tempDenominator = tempNumerator%tempDenominator;
tempNumerator = temp;
}
int GCD = tempNumerator;
numerator = fabs(numerator);
denominator = fabs(denominator);
//Num is larger than denom
if(numerator>=denominator)
{
//whole number
if(numerator%denominator == 0)
{
result.wholeNumber = (numerator/denominator)*-1;
result.numerator = 1;
result.denominator = 1;
}
//mixed number
else
{
result.wholeNumber = ((numerator - (numerator%denominator)) /denominator)*-1;
numerator = (numerator%denominator);
if (numerator%GCD ==0 && denominator%GCD ==0)
{
result.numerator = numerator/GCD;
result.denominator= denominator/GCD;
}
else
{
result.numerator = numerator;
result.denominator = denominator;
}
}
}
//simple fraction
else
{
if (numerator%GCD ==0 && denominator%GCD ==0)
{
result.numerator = (numerator/GCD)*-1;
result.denominator= denominator/GCD;
}
else
{
result.numerator = numerator*-1;
result.denominator = denominator;
}
}
}
else if (numerator*denominator > 0)
{
int tempNumerator = fabs(numerator);
int tempDenominator = fabs(denominator);
int temp = 0;
while(tempDenominator != 0)
{
temp = tempDenominator;
tempDenominator = tempNumerator%tempDenominator;
tempNumerator = temp;
}
int GCD = tempNumerator;
numerator = fabs(numerator);
denominator = fabs(denominator);
//Num is larger than denom
if(numerator>=denominator)
{
//whole number
if(numerator%denominator == 0)
{
result.wholeNumber = numerator/denominator;
result.numerator = 1;
result.denominator = 1;
}
//mixed number
else
{
result.wholeNumber = (numerator - (numerator%denominator)) /denominator;
numerator = (numerator%denominator);
if (numerator%GCD ==0 && denominator%GCD ==0)
{
result.numerator = numerator/GCD;
result.denominator= denominator/GCD;
}
else
{
result.numerator = numerator;
result.denominator = denominator;
}
}
}
//simple fraction
else
{
if (numerator%GCD ==0 && denominator%GCD ==0)
{
result.numerator = numerator/GCD;
result.denominator= denominator/GCD;
}
else
{
result.numerator = numerator;
result.denominator = denominator;
}
}
}
}
return result;
}
void fractionPrint(struct fraction f)
{
if (f.numerator == 0 && f.denominator == 0)
{
printf("Divide by zero!\n");
}
else if(f.numerator ==0 && f.denominator !=0)
{
printf("0\n");
}
else
{
// There IS a whole number
if (f.wholeNumber !=0)
{
//ONLY whole number
if (f.numerator == 1 && f.denominator ==1 )
{
printf("%d\n", f.wholeNumber);
}
//Mixed number
else
{
printf("%d %d/%d\n", f.wholeNumber, f.numerator, f.denominator);
}
}
//fraction only
else
{
printf("%d/%d\n", f.numerator, f.denominator);
}
}
}
struct fraction fractionAdd(struct fraction a, struct fraction b)
{
struct fraction result;
//If whole number exists
if(a.wholeNumber!=0)
{
if (a.numerator ==1 && a.denominator ==1)
{
a.numerator =0;
}
}
else if (b.wholeNumber!=0)
{
if (b.numerator ==1 && b.denominator ==1)
{
b.numerator =0;
}
}
//If the numerator of a is 1 and denom is 1, then make it 0
//If the numerator of b is 1 and deom is 1, then make it 0
//Open up the mixed fraction
a.numerator = (a.wholeNumber*a.denominator) + a.numerator;
b.numerator = (b.wholeNumber*b.denominator) + b.numerator;
//If the denominators equal
if (a.denominator == b.denominator)
{
result.numerator = a.numerator + b.numerator;
result.denominator = b.denominator;
result = fractionCreate(result.numerator, result.denominator);
return result;
}
else if (a.denominator == 0 && b.denominator == 0)
{
}
//If the denominator is not equal,
else if (a.denominator != b.denominator)
{
int LCM;
int temp =0;
//only use the absolute values when finding the GCD
int tempDenominatorA = fabs(a.denominator);
int tempDenominatorB = fabs(b.denominator);
while(tempDenominatorB!=0)
{
temp = tempDenominatorB;
tempDenominatorB = tempDenominatorA%tempDenominatorB;
tempDenominatorA = temp;
}
int GCD = tempDenominatorA;
LCM = fabs(a.denominator*b.denominator)/GCD;
//then multiply each denominator and numerator by a number that will make it the LCM
int multiplyA, multiplyB;
multiplyA = LCM/fabs(a.denominator);
multiplyB = LCM/fabs(b.denominator);
a.numerator = a.numerator*multiplyA;
b.numerator = b.numerator*multiplyB;
result.numerator = a.numerator + b.numerator;
result.denominator = LCM;
result = fractionCreate(result.numerator, result.denominator);
return result;
}
return result;
}
struct fraction fractionSubtract(struct fraction a, struct fraction b)
{
struct fraction result;
//If whole number exists
if(a.wholeNumber!=0)
{
if (a.numerator ==1 && a.denominator ==1)
{
a.numerator =0;
}
}
else if (b.wholeNumber!=0)
{
if (b.numerator ==1 && b.denominator ==1)
{
b.numerator =0;
}
}
//If the numerator of a is 1 and denom is 1, then make it 0
//If the numerator of b is 1 and deom is 1, then make it 0
//Open up the mixed fraction
a.numerator = (a.wholeNumber*a.denominator) + a.numerator;
b.numerator = (b.wholeNumber*b.denominator) + b.numerator;
a.wholeNumber = 0;
b.wholeNumber = 0;
//If the denominators equal
if (a.denominator == b.denominator)
{
result.numerator = a.numerator - b.numerator;
result.denominator = b.denominator;
result = fractionCreate(result.numerator, result.denominator);
return result;
}
else if (a.denominator == 0 && b.denominator == 0)
{
}
//If the denominator is not equal,
else if (a.denominator != b.denominator)
{
int LCM;
int temp =0;
//only use the absolute values when finding the GCD
int tempDenominatorA = fabs(a.denominator);
int tempDenominatorB = fabs(b.denominator);
while(tempDenominatorB!=0)
{
temp = tempDenominatorB;
tempDenominatorB = tempDenominatorA%tempDenominatorB;
tempDenominatorA = temp;
}
int GCD = tempDenominatorA;
LCM = fabs(a.denominator*b.denominator)/GCD;
//then multiply each denominator and numerator by a number that will make it the LCM
int multiplyA, multiplyB;
multiplyA = LCM/fabs(a.denominator);
multiplyB = LCM/fabs(b.denominator);
a.numerator = a.numerator*multiplyA;
b.numerator = b.numerator*multiplyB;
result.numerator = a.numerator - b.numerator;
result.denominator = LCM;
result = fractionCreate(result.numerator, result.denominator);
return result;
}
return result;
}
struct fraction fractionMultiply(struct fraction a, struct fraction b)
{
struct fraction result;
//If whole number exists
if(a.wholeNumber!=0)
{
if (a.numerator ==1 && a.denominator ==1)
{
a.numerator =0;
}
}
else if (b.wholeNumber!=0)
{
if (b.numerator ==1 && b.denominator ==1)
{
b.numerator =0;
}
}
//If the numerator of a is 1 and denom is 1, then make it 0
//If the numerator of b is 1 and deom is 1, then make it 0
//Open up the mixed fraction
a.numerator = (a.wholeNumber*a.denominator) + a.numerator;
b.numerator = (b.wholeNumber*b.denominator) + b.numerator;
a.wholeNumber = 0;
b.wholeNumber = 0;
result.numerator = a.numerator*b.numerator;
result.denominator = a.denominator*b.denominator;
result = fractionCreate(result.numerator, result.denominator);
return result;
}
struct fraction fractionDivide(struct fraction a, struct fraction b)
{
struct fraction result;
//If whole number exists
if(a.wholeNumber!=0)
{
if (a.numerator ==1 && a.denominator ==1)
{
a.numerator =0;
}
}
else if (b.wholeNumber!=0)
{
if (b.numerator ==1 && b.denominator ==1)
{
b.numerator =0;
}
}
//If the numerator of a is 1 and denom is 1, then make it 0
//If the numerator of b is 1 and deom is 1, then make it 0
//Open up the mixed fraction
a.numerator = (a.wholeNumber*a.denominator) + a.numerator;
b.numerator = (b.wholeNumber*b.denominator) + b.numerator;
a.wholeNumber = 0;
b.wholeNumber = 0;
result.numerator = a.numerator*b.denominator;
result.denominator = a.denominator*b.numerator;
result = fractionCreate(result.numerator, result.denominator);
return result;
}
you .c file is missing the main()
the gcc or any othe c compiler first looks for the main() in the program (.c file )
it seem to me that you are missing the main() in your .c file
try adding a main() in your .c file and call other functions inside the main function in the order that you wanted