fix lab9 error
This commit is contained in:
3 files changed
+209
-129
No files matched your search
+2
-2
@@ -3,9 +3,9 @@ CC = gcc
|
||||
CFLAGS = -Wall -std=c11
|
||||
|
||||
#Input file
|
||||
INPUT = input1.txt
|
||||
INPUT = input5.txt
|
||||
OUTPUT = output.txt
|
||||
REF = ref1.txt
|
||||
REF = ref5.txt
|
||||
# Source file
|
||||
SRCS = lab9.c
|
||||
# Output
|
||||
|
||||
+206
-126
@@ -12,16 +12,22 @@
|
||||
#define ERROR_CODE 1
|
||||
#define OK_CODE 0
|
||||
#define MAX_STRING_LEN 256
|
||||
#define SCAN_MAX_LEN 255
|
||||
#define SCAN_FORMAT_LEN 16
|
||||
#define IS_EQUAL 0
|
||||
#define INDEX_OFFSET 1
|
||||
#define BASE_TEN 10
|
||||
#define DOUBLE 2
|
||||
|
||||
#define SHORT 1
|
||||
#define INTEGER 2
|
||||
#define FLOAT 3
|
||||
#define CHAR 4
|
||||
#define STRING 5
|
||||
#define TYPE_SHORT 1
|
||||
#define TYPE_INTEGER 2
|
||||
#define TYPE_FLOAT 3
|
||||
#define TYPE_CHAR 4
|
||||
#define TYPE_STRING 5
|
||||
|
||||
#define NEWLINE '\n'
|
||||
#define VALUE_SEPARATOR ','
|
||||
#define NULL_TERMINATOR '\0'
|
||||
#define SENTINEL_STRING "E"
|
||||
|
||||
char A_NUMBER[] = "A01385066";
|
||||
|
||||
@@ -36,10 +42,8 @@ void insertNode(NODE **head, void *data)
|
||||
NODE *node;
|
||||
|
||||
node = malloc(sizeof(NODE));
|
||||
|
||||
node->data = data;
|
||||
node->next = *head;
|
||||
|
||||
*head = node;
|
||||
}
|
||||
|
||||
@@ -51,96 +55,25 @@ void freeList(NODE *head)
|
||||
{
|
||||
temp = head;
|
||||
head = head->next;
|
||||
|
||||
free(temp->data);
|
||||
free(temp);
|
||||
}
|
||||
}
|
||||
|
||||
NODE* readFile(char *filepath, int *type, int *count)
|
||||
{
|
||||
FILE *file;
|
||||
file = fopen(filepath, "r");
|
||||
|
||||
if (file == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fscanf(file, "%d", type) != EXPECTED_INPUT)
|
||||
{
|
||||
fclose(file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int ch; // skip newlines characters and EOF
|
||||
while ((ch = fgetc(file)) != '\n' && ch != EOF) {}
|
||||
|
||||
char *format;
|
||||
NODE *head;
|
||||
size_t size;
|
||||
|
||||
head = NULL;
|
||||
*count = 0;
|
||||
|
||||
format = *type == SHORT ? "%hd" :
|
||||
*type == INTEGER ? "%d" :
|
||||
*type == FLOAT ? "%f" :
|
||||
" %c";
|
||||
|
||||
size = *type == SHORT ? sizeof(short) :
|
||||
*type == INTEGER ? sizeof(int) :
|
||||
*type == FLOAT ? sizeof(float) :
|
||||
*type == CHAR ? sizeof(char) :
|
||||
MAX_STRING_LEN;
|
||||
|
||||
while (READING)
|
||||
{
|
||||
void *data;
|
||||
|
||||
data = malloc(size);
|
||||
|
||||
if (*type == STRING)
|
||||
{
|
||||
if (fscanf(file, "%255[^,\n]", (char *)data) != EXPECTED_INPUT ||
|
||||
strcmp((char *)data, "E") == IS_EQUAL)
|
||||
{
|
||||
free(data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fscanf(file, format, data) != EXPECTED_INPUT ||
|
||||
(*type == CHAR &&
|
||||
*(char *)data == 'E'))
|
||||
{
|
||||
free(data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
insertNode(&head, data);
|
||||
(*count)++;
|
||||
|
||||
ch = fgetc(file);
|
||||
if (ch == EOF)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (ch == '\n')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
return head;
|
||||
}
|
||||
|
||||
int compare(void *a, void *b, int type)
|
||||
{
|
||||
if (type == SHORT || type == INTEGER)
|
||||
if (type == TYPE_SHORT)
|
||||
{
|
||||
short va;
|
||||
short vb;
|
||||
|
||||
va = *(short *)a;
|
||||
vb = *(short *)b;
|
||||
|
||||
return (va > vb) - (va < vb);
|
||||
}
|
||||
|
||||
if (type == TYPE_INTEGER)
|
||||
{
|
||||
int va;
|
||||
int vb;
|
||||
@@ -151,7 +84,7 @@ int compare(void *a, void *b, int type)
|
||||
return (va > vb) - (va < vb);
|
||||
}
|
||||
|
||||
if (type == FLOAT)
|
||||
if (type == TYPE_FLOAT)
|
||||
{
|
||||
float va;
|
||||
float vb;
|
||||
@@ -162,7 +95,7 @@ int compare(void *a, void *b, int type)
|
||||
return (va > vb) - (va < vb);
|
||||
}
|
||||
|
||||
if (type == CHAR)
|
||||
if (type == TYPE_CHAR)
|
||||
{
|
||||
char va;
|
||||
char vb;
|
||||
@@ -182,8 +115,8 @@ NODE* split(NODE *head)
|
||||
NODE *slow;
|
||||
NODE *second;
|
||||
|
||||
slow = head;
|
||||
fast = head;
|
||||
slow = head;
|
||||
|
||||
while (fast != NULL && fast->next != NULL)
|
||||
{
|
||||
@@ -206,6 +139,7 @@ NODE* merge(NODE *first, NODE *second, int type)
|
||||
{
|
||||
return second;
|
||||
}
|
||||
|
||||
if (second == NULL)
|
||||
{
|
||||
return first;
|
||||
@@ -216,22 +150,20 @@ NODE* merge(NODE *first, NODE *second, int type)
|
||||
first->next = merge(first->next, second, type);
|
||||
return first;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
second->next = merge(first, second->next, type);
|
||||
return second;
|
||||
}
|
||||
}
|
||||
|
||||
NODE* mergeSort(NODE *head, int type)
|
||||
{
|
||||
NODE *second;
|
||||
|
||||
if (head == NULL || head->next == NULL)
|
||||
{
|
||||
return head;
|
||||
}
|
||||
|
||||
NODE *second;
|
||||
|
||||
second = split(head);
|
||||
head = mergeSort(head, type);
|
||||
second = mergeSort(second, type);
|
||||
@@ -239,37 +171,185 @@ NODE* mergeSort(NODE *head, int type)
|
||||
return merge(head, second, type);
|
||||
}
|
||||
|
||||
NODE* readFile(char *filepath, int *type, int *count)
|
||||
{
|
||||
FILE *file;
|
||||
NODE *head;
|
||||
int ch;
|
||||
size_t size;
|
||||
|
||||
file = fopen(filepath, "r");
|
||||
if (file == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fscanf(file, "%d", type) != EXPECTED_INPUT)
|
||||
{
|
||||
fclose(file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ch = fgetc(file);
|
||||
while (ch != NEWLINE && ch != EOF)
|
||||
{
|
||||
ch = fgetc(file);
|
||||
}
|
||||
|
||||
head = NULL;
|
||||
*count = 0;
|
||||
|
||||
size = MAX_STRING_LEN;
|
||||
if (*type == TYPE_SHORT)
|
||||
{
|
||||
size = sizeof(short);
|
||||
}
|
||||
else if (*type == TYPE_INTEGER)
|
||||
{
|
||||
size = sizeof(int);
|
||||
}
|
||||
else if (*type == TYPE_FLOAT)
|
||||
{
|
||||
size = sizeof(float);
|
||||
}
|
||||
else if (*type == TYPE_CHAR)
|
||||
{
|
||||
size = sizeof(char);
|
||||
}
|
||||
|
||||
while (READING)
|
||||
{
|
||||
char buffer[MAX_STRING_LEN];
|
||||
char scanFormat[SCAN_FORMAT_LEN];
|
||||
void *data;
|
||||
char *end;
|
||||
long longValue;
|
||||
float floatValue;
|
||||
int scanResult;
|
||||
|
||||
data = malloc(size);
|
||||
if (data == NULL)
|
||||
{
|
||||
fclose(file);
|
||||
freeList(head);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
scanResult = snprintf(scanFormat, SCAN_FORMAT_LEN, "%%%d[^,\n]", SCAN_MAX_LEN);
|
||||
if (scanResult < 0)
|
||||
{
|
||||
free(data);
|
||||
fclose(file);
|
||||
freeList(head);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fscanf(file, scanFormat, buffer) != EXPECTED_INPUT)
|
||||
{
|
||||
free(data);
|
||||
break;
|
||||
}
|
||||
|
||||
if (strcmp(buffer, SENTINEL_STRING) == IS_EQUAL)
|
||||
{
|
||||
free(data);
|
||||
break;
|
||||
}
|
||||
|
||||
if (*type == TYPE_SHORT)
|
||||
{
|
||||
longValue = strtol(buffer, &end, BASE_TEN);
|
||||
if (*end != NULL_TERMINATOR || longValue < SHRT_MIN || longValue > SHRT_MAX)
|
||||
{
|
||||
free(data);
|
||||
fclose(file);
|
||||
freeList(head);
|
||||
return NULL;
|
||||
}
|
||||
*(short *)data = (short)longValue;
|
||||
}
|
||||
else if (*type == TYPE_INTEGER)
|
||||
{
|
||||
longValue = strtol(buffer, &end, BASE_TEN);
|
||||
if (*end != NULL_TERMINATOR || longValue < INT_MIN || longValue > INT_MAX)
|
||||
{
|
||||
free(data);
|
||||
fclose(file);
|
||||
freeList(head);
|
||||
return NULL;
|
||||
}
|
||||
*(int *)data = (int)longValue;
|
||||
}
|
||||
else if (*type == TYPE_FLOAT)
|
||||
{
|
||||
floatValue = strtof(buffer, &end);
|
||||
if (*end != NULL_TERMINATOR)
|
||||
{
|
||||
free(data);
|
||||
fclose(file);
|
||||
freeList(head);
|
||||
return NULL;
|
||||
}
|
||||
*(float *)data = floatValue;
|
||||
}
|
||||
else if (*type == TYPE_CHAR)
|
||||
{
|
||||
if (strlen(buffer) != INDEX_OFFSET)
|
||||
{
|
||||
free(data);
|
||||
fclose(file);
|
||||
freeList(head);
|
||||
return NULL;
|
||||
}
|
||||
*(char *)data = buffer[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
strncpy((char *)data, buffer, MAX_STRING_LEN);
|
||||
((char *)data)[MAX_STRING_LEN - INDEX_OFFSET] = NULL_TERMINATOR;
|
||||
}
|
||||
|
||||
insertNode(&head, data);
|
||||
(*count)++;
|
||||
|
||||
ch = fgetc(file);
|
||||
if (ch == EOF)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (ch == NEWLINE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
return head;
|
||||
}
|
||||
|
||||
void printValue(FILE *file, void *data, int type)
|
||||
{
|
||||
if (type == SHORT)
|
||||
if (type == TYPE_SHORT)
|
||||
{
|
||||
short v;
|
||||
v = *(short *)data;
|
||||
fprintf(file, "%hd", v);
|
||||
fprintf(file, "%hd", *(short *)data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == INTEGER)
|
||||
if (type == TYPE_INTEGER)
|
||||
{
|
||||
int v;
|
||||
v = *(int *)data;
|
||||
fprintf(file, "%d", v);
|
||||
fprintf(file, "%d", *(int *)data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == FLOAT)
|
||||
if (type == TYPE_FLOAT)
|
||||
{
|
||||
float v;
|
||||
v = *(float *)data;
|
||||
fprintf(file, "%.1f", v);
|
||||
fprintf(file, "%.1f", *(float *)data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == CHAR)
|
||||
if (type == TYPE_CHAR)
|
||||
{
|
||||
char v;
|
||||
v = *(char *)data;
|
||||
fprintf(file, "%c", v);
|
||||
fprintf(file, "%c", *(char *)data);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -281,8 +361,12 @@ void writeOutput(char *filepath, NODE *head, int type, int isError)
|
||||
FILE *file;
|
||||
|
||||
file = fopen(filepath, "w");
|
||||
if (file == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (isError == 1)
|
||||
if (isError == ERROR_CODE)
|
||||
{
|
||||
fputs("Error\n", file);
|
||||
fclose(file);
|
||||
@@ -292,31 +376,29 @@ void writeOutput(char *filepath, NODE *head, int type, int isError)
|
||||
while (head != NULL)
|
||||
{
|
||||
printValue(file, head->data, type);
|
||||
|
||||
if (head->next != NULL)
|
||||
{
|
||||
fputc(',', file);
|
||||
fputc(VALUE_SEPARATOR, file);
|
||||
}
|
||||
|
||||
head = head->next;
|
||||
}
|
||||
|
||||
fputc('\n', file);
|
||||
fputc(NEWLINE, file);
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
NODE *head;
|
||||
int type;
|
||||
int count;
|
||||
|
||||
if (argc < EXPECTED_ARGUMENTS)
|
||||
{
|
||||
printf("Usage: %s <input_file> <output_file>\n", argv[PROGRAM_FILE]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
NODE *head;
|
||||
int type;
|
||||
int count;
|
||||
|
||||
head = readFile(argv[INPUT_FILE], &type, &count);
|
||||
|
||||
if (head == NULL)
|
||||
@@ -326,9 +408,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
head = mergeSort(head, type);
|
||||
|
||||
writeOutput(argv[OUTPUT_FILE], head, type, OK_CODE);
|
||||
|
||||
freeList(head);
|
||||
|
||||
return 0;
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
101,158,205,219,317,347,412,501,516,604,629,732,739,813,826,945,32767
|
||||
apple,banana,blackberry,blueberry,cherry,grape,kiwi,lemon,mango,orange,peach,pear,pineapple,raspberry,strawberry,watermelon
|
||||
Reference in new issue
Block a user