Sorting an array from a text file - c

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]);
}

Related

Sorting an array of strings loaded from a text file

I have problem to sort an array of string by length loaded from txt file.
So I read from the file line by line and put the strings into an array, after that I sort that array by the length of the string, but I get a strange output of the array stream.
The problem is that the program is sorting an array of strings, but one of the strings is pasted on top of another.
Example:
The data in the file I'm reading from:
X&Y
X|Y
!X
(X|Y)|Z
(X&Y)|Z
(X&Y)&Z
(X&Y)|Z&(A|B
((X|Y)|Z)&((A|B)|(C&D))
(X&Y)|(Z&(A|B))
(A|B)&(!C)
A|(B&(C&(D|E)))
((X|Y)|(Z&(A|B)))|((C&D)&(D|E))
(A|B)|(C&D)&(D|E)
!A&(B|C)
(A|B)|(C|D)&(D
Content of the array after sorting in ascending order:
!X
X|Y
X&Y
(X|Y)|Z
(X&Y)|Z
(X&Y)&Z
!A&(B|C)
(A|B)&(!C)
(X&Y)|Z&(A|B
(A|B)|(C|D)&(DA|(B&(C&(D|E))) //Here' is problem ! (A|B)|(C|D)&(D and A|(B&(C&(D|E))) are concatenated?
(X&Y)|(Z&(A|B))
(A|B)|(C&D)&(D|E)
((X|Y)|Z)&((A|B)|(C&D))
((X|Y)|(Z&(A|B)))|((C&D)&(D|E))
Here is the code:
//Sort function
void sort(char str[][MAXLEN], int number_of_elements) {
int d, j;
char temp[100];
for (d = 0; d < number_of_elements - 1; d++) {
for (j = 0; j < number_of_elements - d - 1; j++) {
if (strlen(str[j]) < strlen(str[j + 1])) {
strcpy(temp, str[j]);
strcpy(str[j], str[j + 1]);
strcpy(str[j + 1], temp);
}
}
}
}
int main() {
FILE *dat;
int number_of_elements;
char str[MAX][MAXLEN];
int i = 0;
dat = fopen("ulaz.txt", "r");
if (dat == NULL) {
printf("Error");
}
while (!feof(dat) && !ferror(dat)) {
if (fgets(str[i], 100, dat) != NULL)
i++;
}
number_of_elements = i;
fclose(dat);
sort(str, number_of_elements);
for (int d = 0; d < i; d++) {
printf("%s", str[d]);
}
return 0;
}
Thanks in advance !
Your observations is consistent with the last line of the source file having no trailing newline: (A|B)|(C|D)&(D
You can correct the problem by stripping the newline after fgets() and always appending one in the output phase.
Also make sure that the temporary array used for swapping the strings is long enough: instead of 100 bytes, it should have a length of MAXLEN. Also stop reading from the file when i reaches MAX.
Here is a modified version:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXLEN 200
#define MAX 100
//Sort function by decreasing string lengths
void sort(char str[][MAXLEN], int number_of_elements) {
int d, j;
for (d = 0; d < number_of_elements - 1; d++) {
for (j = 0; j < number_of_elements - d - 1; j++) {
if (strlen(str[j]) < strlen(str[j + 1])) {
char temp[MAXLEN];
strcpy(temp, str[j]);
strcpy(str[j], str[j + 1]);
strcpy(str[j + 1], temp);
}
}
}
}
int main() {
int number_of_elements;
char str[MAX][MAXLEN];
int i;
FILE *dat = fopen("ulaz.txt", "r");
if (dat == NULL) {
fprintf(stderr, "Cannot open %s: %s\n", "ulaz.txt", strerror(errno));
return 1;
}
for (i = 0; i < MAX && fgets(str[i], MAXLEN, dat) != NULL; i++) {
/* strip the trailing newline if any */
str[i][strcspn(str[i], "\n")] = '\0';
}
number_of_elements = i;
fclose(dat);
sort(str, number_of_elements);
for (int d = 0; d < number_of_elements; d++) {
printf("%s\n", str[d]);
}
return 0;
}

C program not running properly on raspberry pi

I'm currently designing a hemming code. This code works perfectly on my computer but when I port it over to my pi, it just does not work properly. I have no idea why and I am pretty new at C and the raspberry pi. Any help would be greatly appreciated.
Below is my full code:
#include <stdio.h>
#include <stdbool.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
int main(void){
int bitLen, errorLoc;
printf("\nLength of the data bits: ");
scanf("%d", &bitLen);
char binStr[ bitLen ], binStrErr[ bitLen ];
printf("Data stream without error: ");
scanf("%s", &binStr);
if(strlen(binStr) > bitLen || strlen(binStr) < bitLen)
{
printf("\nLength of data stream given does not match stated input length!");
return 0;
}
printf("Location of data bit that has error: ");
scanf("%d", &errorLoc);
if(errorLoc > bitLen)
{
printf("\nValue given is bigger than the input length!");
return 0;
}
//Number Of Check Bits Needed
int rBit = 1;
while (pow(2, rBit) < (bitLen + rBit + 1))
{
rBit = rBit + 1;
}
int checkBitsArr[rBit];
int checkBitsErrArr[rBit];
//Actual size of array
bitLen = bitLen + rBit;
int binNum[bitLen];
int binNumErr[bitLen];
int size = sizeof(binNum) / sizeof(binNum[0]);
int binNumPos = size;
printf("\nData stream: ");
//Flipping the error bit and storing into another string
printf("\nOriginal data stream: ");
for (int i = 0; i < strlen(binStr); i++){
printf("%c", binStr[i]);
if(i == (strlen(binStr)) - errorLoc){
int temp = ((binStr[i] - '0') == 0) ? 1 : 0;
binStrErr[i] = temp + '0';
}
else{
binStrErr[i] = binStr[i];
}
}
printf("\nData stream with error: ");
for (int i = 0; i < strlen(binStr); i++){
printf("%c", binStrErr[i]);
}
//Filling in the bits into two arrays: One is the correct data stream and one with error
for (int i = strlen(binStr); i >= 0; i--)
{
binNum[binNumPos] = binStr[i] - '0';
binNumErr[binNumPos] = binStrErr[i] - '0';
binNumPos--;
}
printf("\n\n");
//Moving bits to left to make space
int position = 1;
for (int i = size - 1; i >= 0; i--)
{
if ((position & (position - 1)) == 0)
{
for (int c = 0; c <= i; c++)
{
binNum[c - 1] = binNum[c];
binNumErr[c - 1] = binNumErr[c];
}
binNum[i] = 33;
binNumErr[i] = 33;
}
position++;
}
//Settings check bits into place
position = 1;
int checkBitIndex = 0;
for (int i = size - 1; i >= 0; i--)
{
//Get check bit position
if ((position & (position - 1)) == 0)
{
int temp = 0;//number of 1s in relation to the check bit
int tempErr = 0;
int maxNum = (i - position) + 1;
if (maxNum < 0)
maxNum = maxNum + (-1 * maxNum);
//first part of check
while (maxNum < i)
{
if (binNum[maxNum] == 1)
{
temp++;
}
if (binNumErr[maxNum] == 1)
{
tempErr++;
}
maxNum++;
}
int startNum = (i - position) + 1;
//If the start number is less than zero, make it zero
if (startNum < 0)
startNum = startNum + (-1 * startNum);
//Skip check method. Get the next set of check values in relation to the current check bit
for (int x = startNum - (position * 2); x >= 0; x = x - (position * 2))
{
int k = 0;
while (k < position)
{
if (binNum[x + k] == 1)
{
temp++;
}
if (binNumErr[x + k] == 1)
{
tempErr++;
}
k++;
}
}
//Set the value of check bit
binNum[i] = (temp % 2 == 0) ? 0 : 1;
binNumErr[i] = (tempErr % 2 == 0) ? 0 : 1;
//Replace the current value with the correct checkbit
checkBitsArr[checkBitIndex] = binNum[i];
checkBitsErrArr[checkBitIndex] = binNumErr[i];
temp = 0;
tempErr = 0;
checkBitIndex++;
}
position++;
}
printf("\nSEC code: ");
printf("\nOriginal data stream: ");
for (int i = 0; i < size; i++)
{
printf("%d", binNum[i]);
}
printf("\nData stream with error: ");
for (int i = 0; i < size; i++)
{
printf("%d", binNumErr[i]);
}
printf("\n\n");
int checkIndex = (int)pow(2, rBit - 1);
printf("\n\nCheckbits of data bits without error: \n");
for (int i = checkBitIndex - 1; i >= 0; i--)
{
printf("C%d: %d ", checkIndex, checkBitsArr[i]);
checkIndex = checkIndex/2;
}
checkIndex = (int)pow(2, rBit - 1);
printf("\n\nCheckbits of data bits with error: \n");
for (int i = checkBitIndex - 1; i >= 0; i--)
{
printf("C%d: %d ", checkIndex, checkBitsErrArr[i]);
checkIndex = checkIndex/2;
}
checkIndex = (int)pow(2, rBit - 1);
int posError = 0;
printf("\n\nSyndrome code: \n");
for (int i = checkBitIndex - 1; i >= 0; i--)
{
int x = checkBitsErrArr[i] ^ checkBitsArr[i];
if(x == 1){
posError += checkIndex;
}
printf("C%d: %d ", checkIndex, x);
checkIndex = checkIndex/2;
}
printf("\n\n");
printf("\nPosition of error: %d\n\n", posError);
// printf("\n\n");
return 0;
}
These are the inputs for the scanf:
Length of the data bits: 16
Data stream without error: 0011001100110011
Location of data bit that has error: 8
Below are my results on both computer and pi:
Computer result (correct):
Pi result (wrong):
Looks like you have far more than just one problem, but let's just start with the first one:
char binStr[ bitLen ], binStrErr[ bitLen ];
The string you are requesting next contains not just the 16 bytes you get as input, but also an additional sentinel character as the 17th character.
So at this point you already had 2 buffer overflows, which you can already see nicely in the output from the Pi. The same buffer overflow also occurs in the first example, except the memory layout is different enough so that it doesn't yield visible artifacts.
for (int c = 0; c <= i; c++)
{
binNum[c - 1] = binNum[c];
binNumErr[c - 1] = binNumErr[c];
}
Here comes the next buffer overflow, respectively actually an underflow this time. You are writing to binNum[-1] which is a memory location outside of the memory binNum is pointing to.
Anyway, a buffer overflow means the behavior of your program is undefined.
Get used to valgrind or similar tools for checking your code for undefined with regard to such errors.

Two-Way Insertion Sort not sorting

This is supposed to be a Two-Way insertion sort, but it's not sorting. I'm also supposed to print out the number of assignments for sorting, but right now I just want it to sort.
A separate output array of size 2n+1 is set aside. Initially x[0] is placed into the middle element of the array n.
Continue inserting elements until you need to insert between a pair of elements in the array.
As before you need to make room for the new element by shifting elements. Unlike before,
you can choose to shift all smaller elements one step to the left or all larger elements one step
to the right since there is additional room on both sides of the array. The choice of which
shift to perform depends on which would require shifting the smallest amount of elements.
I can't find much on the internet about this sort except that no one uses it.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void printArray(int arr[], int len) {
for (int j = 0; j < len; j++)
printf("%d ", arr[j]);
printf("\n");
}
int main() {
FILE *in;
int size_arr = 0;
char ch;
if ((in = fopen("data_a5.txt", "r")) == NULL) {
printf("Error!");
exit(1);
}
do {
ch = fgetc(in);
if (ch == '\n')
size_arr++;
} while (ch != EOF);
rewind(in);
int arr[size_arr];
int sort_arr[2 * size_arr + 1];
int n = 0;
while (!feof(in)) {
fscanf(in, "%d", &arr[n]);
n++;
}
fclose(in);
for (n = 0; n < 2 * size_arr; n++) {
sort_arr[n] = 0;
}
sort_arr[size_arr] = arr[0];
for (n = 1; n < size_arr; n++) {
int index = size_arr;
if (arr[n] <= sort_arr[size_arr]) {
while (!(arr[n] <= sort_arr[index]) && sort_arr[index] != 0 && index >= 0) {
index--;
}
}
if (arr[n] > sort_arr[size_arr]) {
while (!(arr[n] <= sort_arr[index]) && sort_arr[index] != 0 && index < 2 * size_arr) {
index++;
}
}
if (sort_arr[index] == 0) {
sort_arr[index] = arr[n];
} else {
int next_R, next_L = index;
while (sort_arr[next_R] != 0 && next_R <= 2 * size_arr) {
next_R++;
}
while (sort_arr[next_L] != 0 && next_L >= 0) {
next_L--;
}
int R_move = next_R - index;
int L_move = index - next_L;
if (R_move > L_move) {
while (L_move <= index) {
sort_arr[L_move] = sort_arr[L_move + 1];
L_move++;
}
sort_arr[index] = arr[n];
} else {
while (R_move >= index) {
sort_arr[R_move] = sort_arr[R_move - 1];
R_move--;
}
sort_arr[index] = arr[n];
}
}
}
printArray(arr, size_arr);
return 0;
}
I'm not sure this solves all problems but it is a problem you must fix.
This code
int next_R, next_L = index;
while(sort_arr[next_R] != 0 && next_R <= 2*size_arr)
has undefined behavior as next_R is uninitialized.
Maybe you want:
int next_R = index, next_L = index;
^^^^^
while(sort_arr[next_R] != 0 && next_R <= 2*size_arr)
In any case you have to initialize next_R before using it.
I also find this line strange:
printArray(arr, size_arr);
^^^
Seems you are printing the original array instead of the sorted array.
May be you want:
printArray(sort_arr, size_arr);
^^^^^
There are some problems in your code:
when you scan the file in the first pass, you should count the number of integers instead of the number of characters.
when inserting, your loops are off by one: the tests should read while (L_move < index) and while (R_move >= index)
while (!feof(in)) is always wrong, you should instead write while (fscanf(in, "%d", &arr[n]) == 1) {...
you should probably allocate the arrays arr and sort_arr instead of defining them as VLAs with automatic storage to prevent undefined behavior on large input files.
you should use binary search into the sorted portion, otherwise your algorithm has a basic complexity of O(N2) that dwarfs the small gain obtained from the minimisation of the insertion phase.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
void print_array(const int arr[], int len) {
for (int j = 0; j < len; j++)
printf("%d%c", arr[j], " \n"[j == len - 1]);
}
int main(void) {
FILE *in;
int size_arr, n, start;
int value;
if ((in = fopen("data_a5.txt", "r")) == NULL) {
printf("Cannot open input file %s\n", "data_a5.txt");
exit(1);
}
for (size_arr = 0; fscanf(in, "%d", &value) == 1; size_arr++)
continue;
rewind(in);
int *arr = calloc(2 * size_arr + 1, sizeof(*arr));
if (arr == NULL) {
printf("Cannot allocate memory for %d entries\n", size_arr);
exit(1);
}
start = size_arr;
for (n = 0; n < size_arr && fscanf(in, "%d", &value) == 1; n++) {
/* insert value into the sorted array */
int a, b;
for (a = start, b = start + n; a < b;) {
int mid = a + (b - a) / 2;
if (arr[mid] < value) {
a = mid + 1;
} else {
b = mid;
}
}
/* insert value at offset b */
if (b - start < start + n - b) {
/* shift left portion to the left */
for (int i = start--; i < b; i++) {
arr[i - 1] = arr[i];
}
b--;
} else {
/* shift right portion to the right */
for (int i = start + n + 1; --i > b;) {
arr[i] = arr[i - 1];
}
}
arr[b] = value;
}
fclose(in);
print_array(arr + start, n);
free(arr);
return 0;
}
like this
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void printArray(int arr[], int len){
while(len--)
printf("%d ", *arr++);
printf("\n");
}
int main(void){
int size_arr = 10;
int arr[size_arr];
int sort_arr[2 * size_arr + 1];
for(int i = 0; i < size_arr; ++i)
arr[i] = -50 + rand() % (100 + 1);
puts("before:");
printArray(arr, size_arr);
int left, right;
sort_arr[left = right = size_arr] = arr[0];
for (int n = 1; n < size_arr; ++n){
int v = arr[n];
if(v <= sort_arr[left]){
sort_arr[--left] = v;
} else if(v >= sort_arr[right]){
sort_arr[++right] = v;
} else {
int L = left, R = right, M, MV;
while(L <= R){
M = L + (R-L)/2;
MV = sort_arr[M];
if(MV < v)
L = M + 1;
else if(v < MV)
R = M - 1;
else
break;
}
//M: insert position
enum { LEFT, RIGHT } CHOICE;
if(v == MV){
int ML = M, MR = M;
while(sort_arr[ML-1] == sort_arr[ML])
--ML;
while(sort_arr[MR] == sort_arr[MR+1])
++MR;
if( ML-left >= right-MR){
M = MR+1;
CHOICE = RIGHT;
} else {
M = ML;
CHOICE = LEFT;
}
} else if(v > MV){
++M;
CHOICE = M-left+1 > right-M;// ? RIGHT : LEFT;
} else {
CHOICE = M-left-1 > right-M;// ? RIGHT : LEFT;
}
if(CHOICE == RIGHT){
memmove(sort_arr + M+1, sort_arr + M, (right-M+1)*sizeof(v));
sort_arr[M] = v;
++right;
} else {
memmove(sort_arr + left-1, sort_arr + left, (M-left)*sizeof(v));
sort_arr[M-1] = v;
--left;
}
}
}
puts("after:");
printArray(sort_arr + left, size_arr);
return 0;
}

linked lists and stacks and a segmentation fault [closed]

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);

c - skyline algorithm confusion

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;
}

Resources