-
Notifications
You must be signed in to change notification settings - Fork 0
/
file.c
150 lines (131 loc) · 4.25 KB
/
file.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/**
* @file file.h
* @brief Provides utility functions to read a Latin square from a file and manage memory for 2D integer arrays.
*
* This file includes functions to dynamically allocate, read, and deallocate memory for a 2D array representing
* a Latin square. The main functionalities are:
* - Reading a Latin square from a file.
* - Safely freeing the memory allocated for a 2D array.
*
* The functions in this file ensure robust error handling for file operations and memory allocation.
*
* @authors
* - Panagiotis Tsembekis
* - Rafael Tsekouronas
*
* @bug No known bugs.
*/
#include "file.h"
// Frees a dynamically allocated 2D integer array
void free2DArray(int **array, int size)
{
if (array != NULL)
{
for (int i = 0; i < size; i++)
{
free(array[i]); // free each column
}
free(array); // free every row
}
}
// Reads the latin square values from the specified file and stores them in a 2D array which is returned
int **readLatinSquare(const char *filename, int *size)
{
// Open file for reading
FILE *fp = fopen(filename, "r");
// Check file pointer after attempting to open file
if (fp == NULL)
{
perror("Error occurred while attempting to read from file.\n");
return NULL;
}
// Check n (size of latin square)
if (fscanf(fp, "%d", size) != 1 || *size <= 0 || *size > N) // check fscanf return code and size's value
{
perror("Invalid size of Latin Square!\n");
fclose(fp);
return NULL; // close file and exit
}
// Allocate memory for 2D array
int **array = (int **)malloc(*size * sizeof(int *));
if (array == NULL) // check for incorrect memory allocation for rows
{
perror("Memory allocation for rows of 2D array failed.\n");
fclose(fp);
return NULL;
}
for (int i = 0; i < *size; i++) // allocate memory for columns
{
array[i] = (int *)malloc(*size * sizeof(int));
if (array[i] == NULL) // check for incorrect memory allocation for columns
{
perror("Memory allocation failed for columns.\n");
free2DArray(array, i); // free previously allocated rows
fclose(fp);
return NULL;
}
}
// Read initial latin square values from file
for (int i = 0; i < *size; i++)
{
for (int j = 0; j < *size; j++)
{
if (fscanf(fp, "%d", &array[i][j]) != 1) // if read more than 1 argument => incorrect
{
perror("Error reading data from file.\n");
free2DArray(array, *size); // free allocated space for array
fclose(fp);
return NULL;
}
else if (array[i][j] > *size || array[i][j] < -(*size)) // check if values inside the file are in appropriate range
{
perror("File contains invalid values!\n");
free2DArray(array, *size); // free allocated space for array
fclose(fp);
return NULL;
}
}
}
// Check for extra data in file
int extraValue;
if (fscanf(fp, "%d", &extraValue) == 1)
{ // check if there are extra rows or columns in the file
perror("File contains more data than expected!\n");
free2DArray(array, *size); // free allocated space for array
fclose(fp);
return NULL;
}
fclose(fp);
return array;
}
#ifdef DEBUG_FILE
int main()
{
int size = 0;
// Provide a test file name [!][!][!]
const char *testFile = "testLatinSquare.txt";
// Call readLatinSquare function
int **latinSquare = readLatinSquare(testFile, &size);
// Check for correct initialization
if (latinSquare == NULL)
{
printf("Failed to read the Latin square from file '%s'.\n", testFile);
}
else
{
printf("Successfully read a %d x %d Latin square from file '%s':\n", size, size, testFile);
// Print the Latin square
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
printf("%d ", latinSquare[i][j]);
}
printf("\n");
}
// Free the allocated memory
free2DArray(latinSquare, size);
}
return 0;
}
#endif