Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
First time posting a question on stack overflow so be nice.
I'm trying to write a program for school. This program is suppose to take a data set and turn it into a maze. The error I'm getting is a segmentation fault in putty but not in the IDE I'm using. Not sure what to do or how to handle it. I tried putting printf statements everywhere but none of them really show up doesnt make sense. Maybe because the functions themselves cause the fault not sure though what part.
//CODE BEGINS****************************************************************
#include <stdio.h>
#include <stdlib.h>
typedef int bool;
#define FALSE 0
#define TRUE 1
typedef struct mazeStruct
{
char **arr; /* allows for a dynamic 2-D maze of any size */
int xsize, ysize;
int xstart, ystart;
int xend, yend;
bool end;
} maze;
struct linkedStruct
{
int x;
int y;
bool Unvisited;
struct linkedStruct* next;
};
typedef struct linkedStruct linked;
typedef linked* linkedPtr;
void push(linkedPtr* hd, int Xval, int Yval)
{
linkedPtr ptr = (linkedPtr) malloc(sizeof(linked));
ptr->x = Xval;
ptr->y = Yval;
ptr->Unvisited = FALSE;
ptr->next = *hd;
*hd = ptr;
}
int isEmpty(linkedPtr hd)
{
if (hd == NULL)
return TRUE;
else
return FALSE;
}
int top(linkedPtr hd)
{
return (hd->x && hd->y);
}
void pop(linkedPtr* hd)
{
linkedPtr ptr = (linkedPtr) malloc(sizeof(linked));
ptr->x = NULL;
ptr->y = NULL;
ptr->Unvisited = TRUE;
ptr->next = *hd;
*hd = ptr;
free(ptr);
}
int main(int argc, char **argv)
{
maze m1;
linkedPtr head = NULL;
int xpos, ypos;
int i, j;
m1.end = FALSE;
FILE *src;
//FILE *src = fopen ("mazeData1.txt",'r');
/* verify the proper number of command line arguments were given */
if (argc != 2)
{
printf("Usage: %s <input file name>\n", argv[0]);
exit(-1);
}
/* Try to open the input file. */
if ((src = fopen(argv[1], "r")) == NULL)
{
printf("Can't open input file: %s", argv[1]);
printf("Standard Error.\n");
exit(-1);
}
/* read in the size, starting and ending positions in the maze */
fscanf(src, "%d %d", &m1.xsize, &m1.ysize);
if (m1.xsize < 1 || m1.ysize < 1)
{
printf("Size has to be 1 or above.\n");
fscanf(src, "%d %d", &m1.xsize, &m1.ysize);
}
fscanf(src, "%d %d", &m1.xstart, &m1.ystart);
if (m1.xstart > m1.xsize || m1.ystart > m1.ysize || m1.xstart < 1
|| m1.ystart < 1)
{
printf("The start has to be within the maze.\n");
fscanf(src, "%d %d", &m1.xstart, &m1.ystart);
}
fscanf(src, "%d %d", &m1.xend, &m1.yend);
if (m1.xend > m1.xsize || m1.yend > m1.ysize || m1.xend < 1 || m1.yend < 1)
{
printf("The end has to be within the maze.\n");
fscanf(src, "%d %d", &m1.xend, &m1.yend);
}
if (m1.xend == NULL || m1.yend == NULL)
{
printf("Error: Need at least three lines of input");
exit(-1);
}
/* print them out to verify the input */
printf("size: %d, %d\n", m1.xsize, m1.ysize);
printf("start: %d, %d\n", m1.xstart, m1.ystart);
printf("end: %d, %d\n", m1.xend, m1.yend);
/* allocate the maze */
m1.arr = (char **) malloc(sizeof(char *) * (m1.xsize + 2));
for (i = 0; i < m1.xsize + 2; i++)
m1.arr[i] = (char *) malloc(sizeof(char) * (m1.ysize + 2));
/* initialize the maze to empty */
for (i = 0; i < m1.xsize + 2; i++)
for (j = 0; j < m1.ysize + 2; j++)
m1.arr[i][j] = '.';
/* mark the borders of the maze with *'s */
for (i = 0; i < m1.xsize + 2; i++)
{
m1.arr[i][0] = '*';
m1.arr[i][m1.ysize + 1] = '*';
}
for (i = 0; i < m1.ysize + 2; i++)
{
m1.arr[0][i] = '*';
m1.arr[m1.xsize + 1][i] = '*';
}
/* mark the starting and ending positions in the maze */
m1.arr[m1.xstart][m1.ystart] = 's';
m1.arr[m1.xend][m1.yend] = 'e';
/* mark the blocked positions in the maze with *'s */
while (fscanf(src, "%d %d", &xpos, &ypos) != EOF)
{
if (xpos > m1.xsize || ypos > m1.ysize || xpos < 1 || ypos < 1
|| (xpos == m1.xstart && ypos == m1.ystart)
|| (xpos == m1.xend && ypos == m1.yend))
{
printf(
"Error: X or Y is: out of range or is on the end or is on the start\n");
continue;
}
m1.arr[xpos][ypos] = '*';
}
/* print out the initial maze */
for (i = 0; i < m1.xsize + 2; i++)
{
for (j = 0; j < m1.ysize + 2; j++)
printf("%c", m1.arr[i][j]);
printf("\n");
}
// THE START OF THE DEPTH FIRST SEARCH METHOD
for (i = 0; i < m1.xsize + 2; i++)
{
for (j = 0; j < m1.ysize + 2; j++)
{
if (m1.arr[i][j] != '*')
{
head->Unvisited = FALSE;
head->next = head->next + 1; //MAYBE
}
}
}
head->x = m1.xstart;
head->y = m1.ystart;
head->Unvisited = FALSE;
while ((isEmpty(head) == FALSE) && (m1.end == FALSE))
{
if ((m1.xend == head->x) && (m1.yend == head->y))
{
printf("The END has be found!\n");
m1.end = TRUE;
}
if ((head->x + 1 && head->y) == TRUE)
{
push(&head, head->x + 1, head->y);
}
else if ((head->x - 1 && head->y) == TRUE)
{
push(&head, head->x - 1, head->y);
}
else if ((head->x && head->y + 1) == TRUE)
{
push(&head, head->x, head->y + 1);
}
else if ((head->x && head->y) == TRUE)
{
push(&head, head->x, head->y - 1);
}
else
{
pop(head);
}
}
if (isEmpty(head) == TRUE)
{
printf("Maze has no solution");
exit(0);
}
else
{
printf("%d %d", &head);
}
printf("%d", top(head));
free(m1.arr);
m1.arr = NULL;
return 1;
}
The main problem here is that you are hiding pointer with typedef:
typedef linked* linkedPtr;
In main you are declaring
linkedPtr head = NULL;
but you never allocate/mallocate space for that variable and the first piece of code that dereference it invokes Undefined Behavior because you are dereferencing a null pointer
// THE START OF THE DEPTH FIRST SEARCH METHOD
for (i = 0; i < m1.xsize + 2; i++)
{
for (j = 0; j < m1.ysize + 2; j++)
{
if (m1.arr[i][j] != '*')
{
head->Unvisited = FALSE; <----------BOOOOOOOOOOOOOOM-------
head->next = head->next + 1;
}
}
}
Moreover you have a type mismatch calling pop function, change
pop(head);
to
pop(&head);
Related
This program is to find the epsilon closure of all states of an NFA. I have used the stack to get this done.The program gives the right output when I compiled it using gcc and ran it Windows 10(Command Prompt). But when I compiled with the same compiler and ran it in Linux it results in segmentation fault. I have used any dynamic memory allocation for that matter.
I tried to debug using gdb but not able to find the problem. Detected a segmentation fault after a printf("\n") when displaying the transitions matrix.
It would be very helpful for someone could find the fault. Thanks in advance.
The input is read from a file : nfa.txt.
//states
q0 q1 q2
//input_symbols
0 1
//start_state
q0
//final_state
q2
//transitions of the form : intial_state input final_state
q0 0 q0
q0 e q1
q1 1 q1
q1 e q2
q2 2 q2
The output is as follows:
232 is to represent null transition(Φ) and -1 for ε.
States:
q0
q1
q2
Transitions read
232 0 1 2 -1
0 0 232 232 1
1 232 1 232 2
2 232 232 2 232
e-closure(0) : 0 1 2
e-closure(1) : 1 2
e-closure(2) : 2
Please bear with me because it's a fairly long program.
#include <stdio.h>
#include <string.h> //REMEMBER ME WHILE I'M GONE
#include <errno.h>
#include <stdlib.h>
FILE *file;
int numberOfStates = 0;
int flag = 0;
int states[20];
int j = 0;
int i = 0;
int k = 0;
char a[20];
int transitions[4][5];
int visited[10];
int MAXSIZE = 8;
int stack[8];
int top = -1;
int isempty()
{
if(top == -1)
return 1;
else
return 0;
}
int isfull()
{
if(top == MAXSIZE)
return 1;
else
return 0;
}
int pop()
{
int data;
if(!isempty()) {
data = stack[top];
top = top - 1;
return data;
}
else
printf("Could not retrieve data, Stack is empty.\n");
}
int push(int data) {
if(!isfull()) {
top = top + 1;
stack[top] = data;
}
else
printf("Could not insert data, Stack is full.\n");
}
int IsVisited(int edge)
{
for(int i = 0; i < 10; i++)
if(visited[edge] == 1)
return 1;
return 0;
}
void epsilon_closure(int state)
{
int e_closure[10];
for(int i = 0; i < 10; i++ )
{ e_closure[i] = -1;
visited[i] = 0;
}
push(state);
visited[state] = 1;
while(top != -1)
{
int u = pop();
j = 1;
while(j < 5)
{
//if there is an epsilon transition from the state 'u' to 'v'
if(transitions[j][0] == u && transitions[j][4] != 232) //ASCII of Φ = 232
{
if(! IsVisited(transitions[j][4]))
{
visited[transitions[j][4]] = 1;
push(transitions[j][4]);
}
}
j++;
}
}
j = 0;
for(int edge = 0; edge < 10; edge++)
{
if(visited[edge] == 1)
e_closure[j++] = edge;
}
printf("e-closure(%d) : ",state);
for (i = 0; e_closure[i] != -1; ++i)
printf("%d ", e_closure[i]);
printf("\n");
}
int main()
{
file = fopen("nfa.txt","r");
if (file == NULL) {
perror("fopen");
return -1;
}
//Reading the states
while(!feof(file))
{
fscanf(file,"%s",a);
if(strcmp("//states",a) == 0)
flag = 1;
else if(strcmp("//input_symbols",a) == 0)
break;
if (flag == 1 && a[0] != '/')
{
states[i++] = a[1] - '0';
}
numberOfStates = i;
}
//Display the states of the e-NFA
printf("\nStates : \n");
for(i = 0; i < numberOfStates; i++ )
{
printf("q%d\n",states[i]);
}
i = 1;
flag = 0;
//Reading the transition table
for(int i = 0; i < 4; i++){
for(int j = 0; j < 5; j++)
{
transitions[i][j] = 232;
}
}
while(!feof(file))
{
fgets(a,100,file);
if(a[0] == '/')
{
flag = 1;
}
if(flag == 1 && a[0] != '/')
{
j = 0;
//found a way to store the transition table in a matrix
if(a[3] == 'e')
transitions[(a[1] - '0') + 1][4] = a[6] - '0';
else
transitions[(a[1] - '0') + 1][(a[3] - '0') + 1] = a[6] - '0';
if(a[3] != 'e')
transitions[0][a[3] - '0' + 1] = a[3] - '0'; //input
else
transitions[0][4] = -1; // epsilon input
transitions[(a[1] - '0') + 1][0] = a[1] - '0'; //initial state
}
}
printf("\nTransitions read\n");
for(int i = 0; i < 4; i++){
for(int j = 0; j < 5; j++)
{
printf("%d\t",transitions[i][j]);
}
printf("\n"); //detected segmentation fault here
}
//Calling e-closure for all the states
for(k = 0; k < numberOfStates; k++)
{
epsilon_closure(states[k]);
}
return 0;
}
There is a bug here:
int push(int data) {
if(!isfull()) {
top = top + 1;
stack[top] = data;
}
else
printf("Could not insert data, Stack is full.\n");
}
If top == MAXSIZE-1, isfull() will return false, then you increment top to MAXSIZE and assign stack[MAXSIZE] what is out of bounds and invokes UB. Not having checked the complete source code, I could imagine that incrementing top after assigning would be correct or you have to change isfull() to return true if top >= MAXSIZE-1
So this program crashes and tells me "Aborted (core dumped)" but only when my decleration of "GENERATIONS" is greater than 6... I know its a pain that I've uploaded the whole code but I really cant figure out where it is other than it's after the return from "fibonacci_quasicrystal_generator(GENERATIONS, crystal);", as the printf statement just after gets printed, then the message appears. Code below:
#define GENERATIONS 5
#define OUTFILE "frequencies.txt"
#define GNUPLOT_EXE "gnuplot"
#define GNUPLOT_SCRIPT "frequencyplot.script"
static void fibonacci_quasicrystal_generator(int generations, char * chain);
static int plot();
int main()
{
double k = 1.0, m_a = 100.0, m_b = 1.0, m = 0.0;
char * crystal = malloc(2);
//strcopy(crystal, "A"); //gsl_vector * y_vector = gsl_vector_calloc(CHAIN_LENGTH);
fibonacci_quasicrystal_generator(GENERATIONS, crystal);
if (crystal == NULL){
printf("Crystal write failed.");
exit(0);
}
int chain_length = strlen(crystal);
printf("%i member Crystal generated, after %i generations.\n", chain_length, GENERATIONS);
gsl_matrix * a_matrix = gsl_matrix_calloc(chain_length, chain_length);
gsl_matrix * b_matrix = gsl_matrix_calloc(chain_length, chain_length);
gsl_matrix_set_identity(b_matrix);
gsl_vector * eigenvalues_vector = gsl_vector_calloc(chain_length);
for (int i = 0; i < chain_length; ++i){
if (crystal[i] == 'A'){
m = m_a;
} else {
m = m_b;
}
for (int j = 0; j < chain_length; ++j){
if ((i == j) && (i != 0 && i != chain_length)){
gsl_matrix_set(a_matrix, i, j,(2*k)/m);
}
else if (i == j-1){
gsl_matrix_set(a_matrix, i, j,(-1)*(k/m));
}
else if (i == j+1){
gsl_matrix_set(a_matrix, i ,j, (-1)*(k/m));
}
}
}
gsl_eigen_gensymm_workspace * workspace = gsl_eigen_gensymm_alloc(chain_length);
gsl_eigen_gensymm(a_matrix, b_matrix, eigenvalues_vector, workspace);
gsl_eigen_gensymm_free(workspace);
free(crystal);
gsl_matrix_free(a_matrix);
gsl_matrix_free(b_matrix);
gsl_sort_vector(eigenvalues_vector);
FILE * outfile = fopen(OUTFILE, "w");
for (int i = 0; i < chain_length; ++i){
fprintf(outfile, "%e \t%i \r\n", pow(gsl_vector_get(eigenvalues_vector, i),2), i);
}
fclose(outfile);
gsl_vector_free(eigenvalues_vector);
plot();
return 0;
}
static void fibonacci_quasicrystal_generator(int generations, char * chain){
printf("generating fibonacci quasicrystal...\n");
int i;
i = 0;
char * chain_1 = malloc(2), * chain_2 = malloc(2), * tmp = malloc(2);
strcpy(chain_1, "B");
strcpy(chain_2, "A");
size_t chain_1_size = strlen(chain_1) + 1, chain_2_size = strlen(chain_2) + 1;
if (generations == 1){
chain = realloc(chain, chain_1_size);
snprintf(chain, chain_1_size, "%s", chain_1);
}
else if (generations == 2){
chain = realloc(chain, chain_2_size);
snprintf(chain, chain_2_size, "%s", chain_2);
}
else if (generations > 2){
size_t chain_3_size = strlen(chain_1) + strlen(chain_2) + 1;
char * chain_3 = malloc(chain_3_size);
printf("%i\n", generations);
for (i = 0; i < generations - 1; ++i){
printf("%i\n", i);
snprintf(chain_3, chain_3_size, "%s%s", chain_1, chain_2);
chain_1_size = chain_2_size;
chain_2_size = chain_3_size;
if ((tmp = realloc(chain_1, chain_1_size)) != NULL){
chain_1 = tmp;
}
if ((tmp = realloc(chain_2, chain_2_size)) != NULL){
chain_2 = tmp;
}
snprintf(chain_1, chain_1_size, "%s", chain_2);
snprintf(chain_2, chain_2_size, "%s", chain_3);
if (i < generations - 2){
chain_3_size = strlen(chain_1) + strlen(chain_2) + 1;
if ((tmp = realloc(chain_3, chain_3_size)) != NULL){
chain_3 = tmp;
} else {
printf("oops!\n");
exit(1);
}
}
}
chain = realloc(chain, chain_3_size);
snprintf(chain, chain_3_size, "%s", chain_3);
free(chain_3);
}
free(chain_1);
free(chain_2);
}
static int plot(){
char command[PATH_MAX];
snprintf(command, sizeof(command), "%s %s", GNUPLOT_EXE, GNUPLOT_SCRIPT);
system(command);
return 0;
}
The problem is that char *chain into fibonacci_quasicrystal_generator function has local scope: the function does not modify the crystal pointer of main, so that pointer is left with 2 bytes.
You can change the function to
static char *fibonacci_quasicrystal_generator(int generations, char * chain)
{
// YOUR STUFF
return chain;
}
And call it from main using
crystal = fibonacci_quasicrystal_generator(GENERATIONS, crystal);
You can achieve the same using a double pointer so
static void ibonacci_quasicrystal_generator(int generations, char ** chain)
I'm doing a shift-reduce algorithm for our compiler design subject. This is the code.
void shiftReduce(char str[MAX_CHAR], int prodNum, int line)
{
int limit = 5, y=0;
int substrFlag = 1; //0 true 1 false
int ctr,x, counter;
int match, next;
char stack[MAX_CHAR];
clearString(stack);
OUTER:while ((strcmp(stack, prod[0].left) != 0) && (y < limit))
{
addChar(stack, str[0]);
strcpy(str, dequeue(str));
printf("Stack = %s\nQueue = %s\n", stack, str);
for (ctr = 0; ctr < prodNum; ctr++)
{
if (strstr(stack, prod[ctr].right) != NULL)
{ //substring found
substrFlag = 0;
strcpy(stack, replace(stack, prod[ctr].right, prod[ctr].left));
goto OUTER;
}
}
if ((str[0] == '\n') || (str[0] == '\0'))
y++;
}
if (strcmp(stack, prod[0].left) == 0)
;//printf("%s - Accepted.\n", stack);
else
printf("Syntax error on line %i\n", line);
}
When I comment the printf("Stack = %s\nQueue = %s\n", stack, str); line, it works well. But when I uncomment it, it returns the code 3221225477.
BTW. This is the dequeue function:
char * dequeue (char str[MAX_CHAR])
{
int x = 0; char temp;
for (x = 0; x < length(str); x++)
{
if ((x+1) < length(str))
str[x] = str[x+1];
}
return str;
}
and the addChar function:
void addChar (char * str, char letter)
{
int a = 0;
while (str[a] != '\0')
a++;
str[a] = letter;
str[a+1] = '\0';
return;
}
and finally replace function.
char * replace (char orig[MAX_CHAR], char substr[MAX_CHAR], char rep[MAX_CHAR])
{
int match, end=0, next=0;
int flag = 0; //0 true 1 false
char temp [MAX_CHAR];
char store[MAX_CHAR];
if (strstr(orig, substr) == NULL)
return NULL;
int x,y;
for (x = 0; x < length(orig); x++)
{
if (orig[x] == substr[0]) //if current character is equal to first character of substring
{
match = x;
for (y = 0; y < length(substr); y++)
{
if (orig[match+y] != substr[y])
{
flag = 1;
break;
}
}
if (flag == 0)
{
next = match + length(substr);
for (y = 0; y < length(rep); y++)
{
temp[match+y] = rep[y];
end = (match+y);
}
for (y = next; y < length(orig); y++)
{
temp[y] = orig[next+(y-next)];
}
return temp;
}
}
else
{
addChar(temp, orig[x]);
}
}
return temp;
}
PS. The prod array:
struct RULES
{
char left[MAX_CHAR];
char right[MAX_CHAR];
} RULES;
struct RULES prod[MAX_RULES];
When I comment the printf("Stack = %s\nQueue = %s\n", stack, str); line, it works well. But when I uncomment it, it returns the code 3221225477.
Then most likely either stack or str has not been 0-terminated or points to invalid memory.
I can' seem to sort a text file I have in ascending order. For some reason it prints my shuffle array with the first and second entry swapped. I seem to have confused myself after hours of trying to get it to work and may have made a few mistakes.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
// Accepts: command line input
// Returns: 0 if no error
int main(int num_args, char *arg_strings[])
{
int x = 0, i, track_count = 0;
unsigned long Max_Length = 0;
char line[500], *temp;
FILE *file = fopen("playlist.txt", "r");
/* The next line checks if the playlist file exists and if it's not there, "Cannot Open File" is printed to the screen */
if (file == NULL)
{
printf("Cannot open file\n");
}
/* The following code identifies each line in the text and lines are shuffled accordingly */
while (fgets(line, sizeof(line), file) != NULL)
{
track_count++;
if (strlen(line) > Max_Length)
Max_Length = strlen(line);
}
rewind(file);
char *Array[track_count];
while (fgets(line, sizeof(line), file) != NULL)
{
Array[x] = malloc(strlen(line));
if (Array[x] == NULL)
{
printf("A memory error occurred.\n");
return(1);
}
strcpy(Array[x], line);
/* change \n to \0 */
Array[x][strlen(Array[x]) - 1] = '\0';
x++;
}
printf("The original playlist is:\n");
for (x = 0; x < track_count; x++)
printf("%2d %s\n", x, Array[x]);
/* The array will now be shuffled: */
srand((unsigned int)time(NULL));
for (x = track_count - 2; x > 1; x--)
{
while (1)
{
i = rand() % (track_count - 1) + 1;
if (Array[x + 1][0] == Array[i][0])
continue;
if (Array[x - 1][0] == Array[i][0])
continue;
if (Array[i + 1][0] == Array[x][0])
continue;
if (Array[i - 1][0] == Array[x][0])
continue;
temp = Array[x];
Array[x] = Array[i];
Array[i] = temp;
break;
}
}
printf("\nShuffled Array\n");
for (x = 0; x < track_count; x++)
printf("%2d %s\n", x, Array[x]);
/* Sorting */
int m = 0;
int z = 0;
int k = 0;
char j = 0;
char tempArtist[Max_Length][Max_Length];
for (m = 0; m < track_count; m++)
{
for (z = 0; z <track_count - 1 - m; z++)
{
if (strcmp(Array[j], Array[j + 1]) > 0)
{
strcpy(tempArtist, Array[j]);
strcpy(Array[j], Array[j + 1]);
strcpy(Array[j + 1], tempArtist);
}
}
}
puts("");
printf("Sorted Playlist:");
for (k = 0; k <= track_count; k++)
{
printf("\n%s", Array[k]);
}
return 0;
}
Your code definitely needs some cleaning up. But main problem was using bad variable names in loops ( you have too many vars ). Now it works.
for (m = 0; m < track_count - 1; m++)
{
for (z = 0; z <track_count - 1 - m; z++)
{
if (strcmp(Array[z], Array[z + 1]) > 0)
{
char* tmp;
tmp = Array[z];
Array[z] = Array[z + 1];
Array[z + 1] = tmp;
}
}
}
puts("");
printf("Sorted Playlist:");
for (k = 0; k < track_count; k++)
{
printf("\n%s", Array[k]);
}
I am trying to write a code which gives coordinates of corners of a skyline, it was one of my friends' homework and I am trying it as a practice for myself. So, here is my code:
#include <stdio.h>
#include <stdlib.h>
typedef struct building
{
int start, height, width;
} BUILDING;
int main()
{
FILE *buildingsptr, *outlineptr;
char karakter;
int satir = 1, i = 0, j = 0, *heights, lastpoint = 0 ;
BUILDING *ptr, *a, temp;
buildingsptr = fopen("buildings.txt", "r");
if (buildingsptr == NULL)
{
printf("An error occured while opening the file.\n");
system("PAUSE");
return 0;
}
while ((karakter = fgetc(buildingsptr)) != EOF)
{
if (karakter == '\n') satir++;
}
ptr = (BUILDING *) malloc(satir * sizeof(BUILDING));
a = ptr;
rewind(buildingsptr);
for (i = 0; i < satir; i++)
{
fscanf(buildingsptr, "%d %d %d", &ptr->start, &ptr->height, &ptr->width);
ptr++;
}
fclose(buildingsptr);
ptr = a; // a is for accessing the first part of the allocated memory,
// compiler gave some errors while I tried to access the first
// block of the array.
for (j = 0; j < satir; j++) //bubble sort to buildings
{
for (i = 0; i < satir; i++)
{
if (ptr[i].start > ptr[i + 1].start)
{
temp = ptr[i];
ptr[i] = ptr[i + 1];
ptr[i + 1] = temp;
}//end of if
}//end of second for
}//end of first for
lastpoint = ((ptr[satir - 1].start + ptr[satir - 1].width) + 1);
heights = (int *)calloc(lastpoint, sizeof(int));
for (j = 0; j < lastpoint; j++) // j travels the x axis
{
for (i = 0; i < satir; i++) // i counts buildings
{
if (j <= (ptr[i].start + ptr[i].width && ptr[i].start <= j))
{
if (ptr[i].height > heights[i])
heights[i] = ptr[i].height;
}
}
}
outlineptr = fopen("outline.txt", "w");
for (i = 0; i < lastpoint; i++) // for every point x,checking the heights
// and transforming them as the coordinates
{
if (heights[i + 1] > heights[i])
{
fprintf(outlineptr, "(%d,%d),", i + 1, heights[i]);
fprintf(outlineptr, "(%d,%d),", i + 1, heights[i + 1]);
}//end if
if (heights[(i + 1)] < heights[i])
{
fprintf(outlineptr, "(%d,%d),", i, heights[i]);
fprintf(outlineptr, "(%d,%d),", i, heights[i + 1]);
}//end if
}//end for
fprintf(outlineptr, "(%d,%d),", lastpoint, heights[lastpoint]);
fprintf(outlineptr, "(%d,%d)", lastpoint, 0);
getch();
return 0;
}
Code is working but it is writing wrong coordinates to the outline.txt. "buildings.txt" is something like:
24 7 4
5 7 11
26 9 7
9 5 5
3 12 4
33 9 6
37 5 7
12 9 10
First integer is starting point of a building, second one is height of the building and third one is width of the building. So, how can I re-write this code? I edited my code to be more proper.
This is a basic example of how the frame of your program should look.
The implementation of the algorithm itself should be up to you.
There is no need for separate line counting.
#include <stdio.h>
#include <stdlib.h>
typedef struct building
{
int start, height, width;
struct building *next;
struct building *prev;
} BUILDING;
int main()
{
FILE *inputFilePtr;
inputFilePtr = fopen("input.txt", "r");
if (inputFilePtr == NULL)
{
printf("An error occured while opening the file.\n");
return EXIT_FAILURE;
}
struct building *build = malloc(sizeof(*build));
struct building *reserve = build;
reserve->prev = NULL;
build->prev = NULL;
char lineBuf[1024];
while (fgets(lineBuf, 1024, inputFilePtr) != NULL)
{
sscanf(lineBuf, "%d %d %d", &(build->start), &(build->height), &(build->width));
build->next = malloc(sizeof(*build));
build->prev = build;
build = build->next;
}
build->next = NULL;
fclose(inputFilePtr);
/////////
// whatever logic comes here
////////
FILE *out = fopen("out.txt","w");
if (out == NULL) return EXIT_FAILURE;
// modify output function to fit your algorithm
while(reserve->next != NULL)
{
fprintf(out, "Build coordinates: (%d, %d, %d)\n", reserve->start, reserve->height, reserve->width);
reserve->prev = reserve;
reserve = reserve->next;
}
fclose(out);
// possible memory cleanup
/*
while(reserve->prev != NULL)
{
reserve = reserve->prev;
free(reserve->next);
}
*/
return 0;
}