表格完成
This commit is contained in:
parent
eb806421af
commit
c5a4bf6456
3
3/key.h
3
3/key.h
|
@ -2,4 +2,5 @@
|
||||||
#define KEY_UP_ARROW 0x48
|
#define KEY_UP_ARROW 0x48
|
||||||
#define KEY_RIGHT_ARROW 0x4D
|
#define KEY_RIGHT_ARROW 0x4D
|
||||||
#define KEY_DOWN_ARROW 0x50
|
#define KEY_DOWN_ARROW 0x50
|
||||||
#define KEY_ENTER 0x0D
|
#define KEY_ENTER 0x0D
|
||||||
|
#define KEY_ESC 0x1B
|
847
3/main.c
847
3/main.c
|
@ -10,16 +10,18 @@
|
||||||
#define MAX_DATA_LENGTH 100
|
#define MAX_DATA_LENGTH 100
|
||||||
#define MAX_TICK 200
|
#define MAX_TICK 200
|
||||||
#define MAX_MESSAGE_LENGTH 100
|
#define MAX_MESSAGE_LENGTH 100
|
||||||
#define FUNCTION_NUM 7
|
#define FUNCTION_NUM 8
|
||||||
|
|
||||||
int tick = 0;
|
int tick = 0;
|
||||||
int current_x = 0;
|
int current_x = 0;
|
||||||
int current_y = 0;
|
int current_y = 0;
|
||||||
int alive = 1;
|
int alive = 1;
|
||||||
|
int select_mode = 0;
|
||||||
|
int select_entry = 0;
|
||||||
|
int input_mode = 0;
|
||||||
|
|
||||||
char functions[FUNCTION_NUM][100] = {
|
char functions[FUNCTION_NUM][100] = {"Save", "Load", "Sum", "Average",
|
||||||
"Save", "Load", "Sum", "Average", "Max", "Min", "Sort",
|
"Max", "Min", "Sort", "Exit"};
|
||||||
};
|
|
||||||
|
|
||||||
char *message = "Hi~";
|
char *message = "Hi~";
|
||||||
|
|
||||||
|
@ -34,6 +36,405 @@ int max(int a, int b) { return a > b ? a : b; }
|
||||||
|
|
||||||
int min(int a, int b) { return a < b ? a : b; }
|
int min(int a, int b) { return a < b ? a : b; }
|
||||||
|
|
||||||
|
int int_length(int num) {
|
||||||
|
if (num == 0)
|
||||||
|
return 1;
|
||||||
|
int length = 0;
|
||||||
|
while (num) {
|
||||||
|
num /= 10;
|
||||||
|
length++;
|
||||||
|
}
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
int is_string_all_number(char *str) {
|
||||||
|
int length = strlen(str);
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
if (str[i] < '0' || str[i] > '9') {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int is_index_all_number(TableInfo *table, int type, int index) {
|
||||||
|
if (type == 0) {
|
||||||
|
// 行
|
||||||
|
index = index - 1;
|
||||||
|
for (int i = 0; i < table->current_width; i++) {
|
||||||
|
if (strlen(table->data[index][i]) > 0) {
|
||||||
|
if (!is_string_all_number(table->data[index][i])) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 列
|
||||||
|
index = index - 'A';
|
||||||
|
for (int i = 0; i < table->current_height; i++) {
|
||||||
|
if (strlen(table->data[i][index]) > 0) {
|
||||||
|
if (!is_string_all_number(table->data[i][index])) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 交换两列
|
||||||
|
void changeTwoColumn(TableInfo *table, int column1, int column2) {
|
||||||
|
// 验证两列是否合法且不等
|
||||||
|
if (column1 == column2 || column1 < 0 || column2 < 0 ||
|
||||||
|
column1 >= table->current_width || column2 >= table->current_width) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
char tmp[MAX_DATA_LENGTH];
|
||||||
|
for (int i = 0; i < table->current_height; i++) {
|
||||||
|
strcpy(tmp, table->data[i][column1]);
|
||||||
|
strcpy(table->data[i][column1], table->data[i][column2]);
|
||||||
|
strcpy(table->data[i][column2], tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 交换两行
|
||||||
|
void changeTwoRow(TableInfo *table, int row1, int row2) {
|
||||||
|
// 验证两行是否合法且不等
|
||||||
|
if (row1 == row2 || row1 < 0 || row2 < 0 || row1 >= table->current_height ||
|
||||||
|
row2 >= table->current_height) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
char tmp[MAX_DATA_LENGTH];
|
||||||
|
for (int i = 0; i < table->current_width; i++) {
|
||||||
|
strcpy(tmp, table->data[row1][i]);
|
||||||
|
strcpy(table->data[row1][i], table->data[row2][i]);
|
||||||
|
strcpy(table->data[row2][i], tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int str_cmp(char *str1, char *str2, int case_sensitive) {
|
||||||
|
if (case_sensitive) {
|
||||||
|
return strcmp(str1, str2);
|
||||||
|
} else {
|
||||||
|
char *tmp_str1 = (char *)malloc(sizeof(char) * strlen(str1));
|
||||||
|
char *tmp_str2 = (char *)malloc(sizeof(char) * strlen(str2));
|
||||||
|
strcpy(tmp_str1, str1);
|
||||||
|
strcpy(tmp_str2, str2);
|
||||||
|
for (int i = 0; i < strlen(tmp_str1); i++) {
|
||||||
|
if (tmp_str1[i] >= 'A' && tmp_str1[i] <= 'Z') {
|
||||||
|
tmp_str1[i] += 32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0; i < strlen(tmp_str2); i++) {
|
||||||
|
if (tmp_str2[i] >= 'A' && tmp_str2[i] <= 'Z') {
|
||||||
|
tmp_str2[i] += 32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int result = strcmp(tmp_str1, tmp_str2);
|
||||||
|
free(tmp_str1);
|
||||||
|
free(tmp_str2);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int check_index_valid(TableInfo *table, char *index) {
|
||||||
|
// 合法的 index 应该是 A1,A23 这样的格式
|
||||||
|
int length = strlen(index);
|
||||||
|
if (length == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index[0] >= 'A' && index[0] <= 'A' + table->current_width - 1) {
|
||||||
|
// 列号合法
|
||||||
|
int row = 0;
|
||||||
|
for (int i = 1; i < length; i++) {
|
||||||
|
if (index[i] < '0' || index[i] > '9') {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
row = row * 10 + index[i] - '0';
|
||||||
|
}
|
||||||
|
if (row >= 1 && row <= table->current_height) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 传入实际的 index
|
||||||
|
int check_valid_formatter(TableInfo *table, int x, int y) {
|
||||||
|
// 合法的公示应该以 = 开头,并且只包含 + - 和
|
||||||
|
char *data = malloc(sizeof(char) * MAX_DATA_LENGTH);
|
||||||
|
strcpy(data, table->data[y][x]);
|
||||||
|
if (data[0] != '=') {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int length = strlen(data);
|
||||||
|
char *tmp_data = malloc(sizeof(char) * MAX_DATA_LENGTH);
|
||||||
|
for (int i = 1; i < length; i++) {
|
||||||
|
if (data[i] == ' ')
|
||||||
|
continue;
|
||||||
|
// 获取 =,-,+,\n 之间的字符串
|
||||||
|
int j = i;
|
||||||
|
while (j < length && data[j] != '=' && data[j] != '-' &&
|
||||||
|
data[j] != '+' && data[j] != '\n') {
|
||||||
|
tmp_data[j - i] = data[j];
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
tmp_data[j - i] = '\0';
|
||||||
|
// 判断是否是合法的 index
|
||||||
|
if (tmp_data[0] >= 'A' && tmp_data[0] <= 'Z') {
|
||||||
|
if (!check_index_valid(table, tmp_data))
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
for (int k = 0; k < j - i; k++) {
|
||||||
|
if (tmp_data[k] < '0' || tmp_data[k] > '9') {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取是行还是列
|
||||||
|
int get_index_type(int index) { return index >> 7; }
|
||||||
|
|
||||||
|
// 获取具体的值
|
||||||
|
int get_index_value(int index) { return index & 0b01111111; }
|
||||||
|
|
||||||
|
// 进入选择模式,选择某行或某列
|
||||||
|
int start_select_index(int entry) {
|
||||||
|
message = "Select a row or column";
|
||||||
|
current_x = 0;
|
||||||
|
current_y = 1;
|
||||||
|
select_mode = 1;
|
||||||
|
select_entry = entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 退出选择模式
|
||||||
|
void end_select_index(TableInfo *table) {
|
||||||
|
// 一个 8 位数字
|
||||||
|
// 最高位: 0 代表行 1 代表列
|
||||||
|
// 低 7 位: 代表行号或列号对应字符的 ASCII 码
|
||||||
|
int select_value = 0;
|
||||||
|
if (current_x == 0) {
|
||||||
|
// x = 0 表示选择行
|
||||||
|
select_value = 0b00000000 | current_y;
|
||||||
|
} else {
|
||||||
|
// x > 0 表示选择列
|
||||||
|
select_value = 0b10000000 | (current_x + 'A' - 1);
|
||||||
|
}
|
||||||
|
int type = get_index_type(select_value);
|
||||||
|
int value = get_index_value(select_value);
|
||||||
|
|
||||||
|
int ascii_sort = 0;
|
||||||
|
// 0 代表不区分大小写,1 代表区分大小写
|
||||||
|
int case_sensitive = 0;
|
||||||
|
|
||||||
|
// 判断是否和数字操作有关
|
||||||
|
if (select_entry == 2 || select_entry == 3 || select_entry == 4 ||
|
||||||
|
select_entry == 5 || select_entry == 6) {
|
||||||
|
int valid = is_index_all_number(table, type, value);
|
||||||
|
if (!valid) {
|
||||||
|
if (select_entry == 6) {
|
||||||
|
ascii_sort = 1;
|
||||||
|
message =
|
||||||
|
"This row or column is not all number, use ASCII to "
|
||||||
|
"sort!\n Do you want to use Case Sensitive? ([Y]/n): ";
|
||||||
|
// 等待完善:选择大小写敏感
|
||||||
|
// char tmp;
|
||||||
|
// input_mode = 1;
|
||||||
|
// scanf("%c", &tmp);
|
||||||
|
// input_mode = 0;
|
||||||
|
// if (tmp == 'n' || tmp == 'N') {
|
||||||
|
// case_sensitive = 0;
|
||||||
|
// } else {
|
||||||
|
// case_sensitive = 1;
|
||||||
|
// }
|
||||||
|
} else {
|
||||||
|
message = "This row or column is not all number!";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (select_entry == 2) {
|
||||||
|
// sum
|
||||||
|
int sum = 0;
|
||||||
|
if (type == 0) {
|
||||||
|
// 行
|
||||||
|
value = value - 1;
|
||||||
|
for (int i = 0; i < table->current_width; i++) {
|
||||||
|
if (strlen(table->data[value][i]) > 0) {
|
||||||
|
sum += atoi(table->data[value][i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 列
|
||||||
|
value = value - 'A';
|
||||||
|
for (int i = 0; i < table->current_height; i++) {
|
||||||
|
if (strlen(table->data[i][value]) > 0) {
|
||||||
|
sum += atoi(table->data[i][value]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
char *tmp_message = (char *)malloc(sizeof(char) * MAX_MESSAGE_LENGTH);
|
||||||
|
sprintf(tmp_message, "Sum: %d", sum);
|
||||||
|
message = tmp_message;
|
||||||
|
} else if (select_entry == 3) {
|
||||||
|
// average
|
||||||
|
int sum = 0;
|
||||||
|
int count = 0;
|
||||||
|
if (type == 0) {
|
||||||
|
// 行
|
||||||
|
value = value - 1;
|
||||||
|
for (int i = 0; i < table->current_width; i++) {
|
||||||
|
if (strlen(table->data[value][i]) > 0) {
|
||||||
|
sum += atoi(table->data[value][i]);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 列
|
||||||
|
value = value - 'A';
|
||||||
|
for (int i = 0; i < table->current_height; i++) {
|
||||||
|
if (strlen(table->data[i][value]) > 0) {
|
||||||
|
sum += atoi(table->data[i][value]);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
char *tmp_message = (char *)malloc(sizeof(char) * MAX_MESSAGE_LENGTH);
|
||||||
|
sprintf(tmp_message, "Average: %f", (double)sum / count);
|
||||||
|
message = tmp_message;
|
||||||
|
} else if (select_entry == 4) {
|
||||||
|
// max
|
||||||
|
int max_ = -0x7fffffff;
|
||||||
|
if (type == 0) {
|
||||||
|
// 行
|
||||||
|
value = value - 1;
|
||||||
|
for (int i = 0; i < table->current_width; i++) {
|
||||||
|
if (strlen(table->data[value][i]) > 0) {
|
||||||
|
max_ = atoi(table->data[value][i]) > max_
|
||||||
|
? atoi(table->data[value][i])
|
||||||
|
: max_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 列
|
||||||
|
value = value - 'A';
|
||||||
|
for (int i = 0; i < table->current_height; i++) {
|
||||||
|
if (strlen(table->data[i][value]) > 0) {
|
||||||
|
max_ = atoi(table->data[i][value]) > max_
|
||||||
|
? atoi(table->data[i][value])
|
||||||
|
: max_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
char *tmp_message = (char *)malloc(sizeof(char) * MAX_MESSAGE_LENGTH);
|
||||||
|
sprintf(tmp_message, "Max: %d", max_);
|
||||||
|
message = tmp_message;
|
||||||
|
} else if (select_entry == 5) {
|
||||||
|
// min
|
||||||
|
int min_ = 0x7fffffff;
|
||||||
|
if (type == 0) {
|
||||||
|
// 行
|
||||||
|
value = value - 1;
|
||||||
|
for (int i = 0; i < table->current_width; i++) {
|
||||||
|
if (strlen(table->data[value][i]) > 0) {
|
||||||
|
min_ = atoi(table->data[value][i]) < min_
|
||||||
|
? atoi(table->data[value][i])
|
||||||
|
: min_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 列
|
||||||
|
value = value - 'A';
|
||||||
|
for (int i = 0; i < table->current_height; i++) {
|
||||||
|
if (strlen(table->data[i][value]) > 0) {
|
||||||
|
min_ = atoi(table->data[i][value]) < min_
|
||||||
|
? atoi(table->data[i][value])
|
||||||
|
: min_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
char *tmp_message = (char *)malloc(sizeof(char) * MAX_MESSAGE_LENGTH);
|
||||||
|
sprintf(tmp_message, "Min: %d", min_);
|
||||||
|
message = tmp_message;
|
||||||
|
} else if (select_entry == 6) {
|
||||||
|
// sort
|
||||||
|
if (type == 0) {
|
||||||
|
// 行
|
||||||
|
value = value - 1;
|
||||||
|
for (int i = 0; i < table->current_width; i++) {
|
||||||
|
for (int j = i + 1; j < table->current_width; j++) {
|
||||||
|
if (!ascii_sort) {
|
||||||
|
if (atoi(table->data[value][i]) >
|
||||||
|
atoi(table->data[value][j])) {
|
||||||
|
changeTwoColumn(table, i, j);
|
||||||
|
}
|
||||||
|
message = "Sorted by number!";
|
||||||
|
} else {
|
||||||
|
if (str_cmp(table->data[value][i],
|
||||||
|
table->data[value][j],
|
||||||
|
case_sensitive) > 0) {
|
||||||
|
changeTwoColumn(table, i, j);
|
||||||
|
}
|
||||||
|
message = "Sorted by ASCII!";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 列
|
||||||
|
value = value - 'A';
|
||||||
|
for (int i = 0; i < table->current_height; i++) {
|
||||||
|
for (int j = i + 1; j < table->current_height; j++) {
|
||||||
|
if (!ascii_sort) {
|
||||||
|
if (atoi(table->data[i][value]) >
|
||||||
|
atoi(table->data[j][value])) {
|
||||||
|
changeTwoRow(table, i, j);
|
||||||
|
}
|
||||||
|
message = "Sorted by number!";
|
||||||
|
} else {
|
||||||
|
if (str_cmp(table->data[i][value],
|
||||||
|
table->data[j][value],
|
||||||
|
case_sensitive) > 0) {
|
||||||
|
changeTwoRow(table, i, j);
|
||||||
|
}
|
||||||
|
message = "Sorted by ASCII!";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 选择行或列
|
||||||
|
if (type == 0) {
|
||||||
|
// 行
|
||||||
|
value = value - 1;
|
||||||
|
char *tmp_message =
|
||||||
|
(char *)malloc(sizeof(char) * MAX_MESSAGE_LENGTH);
|
||||||
|
sprintf(tmp_message, "Selected row: %d", value + 1);
|
||||||
|
message = tmp_message;
|
||||||
|
} else {
|
||||||
|
// 列
|
||||||
|
value = value - 'A';
|
||||||
|
char *tmp_message =
|
||||||
|
(char *)malloc(sizeof(char) * MAX_MESSAGE_LENGTH);
|
||||||
|
sprintf(tmp_message, "Selected column: %c", value + 'A');
|
||||||
|
message = tmp_message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// char *tmp_message = (char *)malloc(sizeof(char) * MAX_MESSAGE_LENGTH);
|
||||||
|
// sprintf(tmp_message, "Selected: %d,%c", get_index_type(select_value),
|
||||||
|
// get_index_value(select_value));
|
||||||
|
// message = tmp_message;
|
||||||
|
|
||||||
|
select_mode = 0;
|
||||||
|
current_y = -1;
|
||||||
|
current_x = select_entry;
|
||||||
|
}
|
||||||
|
|
||||||
char *int_to_string(int num) {
|
char *int_to_string(int num) {
|
||||||
char *str = (char *)malloc(sizeof(char) * 100);
|
char *str = (char *)malloc(sizeof(char) * 100);
|
||||||
sprintf(str, "%d", num);
|
sprintf(str, "%d", num);
|
||||||
|
@ -53,25 +454,150 @@ void init_table(int width, int height, int column_width, TableInfo *table) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cal_formula(TableInfo *table, int x, int y) {
|
||||||
|
char *data = malloc(sizeof(char) * MAX_DATA_LENGTH);
|
||||||
|
strcpy(data, table->data[y][x]);
|
||||||
|
int length = strlen(data);
|
||||||
|
char *tmp_data = malloc(sizeof(char) * MAX_DATA_LENGTH);
|
||||||
|
int result = 0;
|
||||||
|
for (int i = 1; i < length; i++) {
|
||||||
|
if (data[i] == ' ')
|
||||||
|
continue;
|
||||||
|
// 标注 -
|
||||||
|
int minus = 0;
|
||||||
|
// 获取 =,-,+,\n 之间的字符串
|
||||||
|
int j = i;
|
||||||
|
while (j < length && data[j] != '=' && data[j] != '-' &&
|
||||||
|
data[j] != '+' && data[j] != '\n') {
|
||||||
|
tmp_data[j - i] = data[j];
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
tmp_data[j - i] = '\0';
|
||||||
|
// 判断是否是 -
|
||||||
|
if (data[i - 1] == '-') {
|
||||||
|
minus = 1;
|
||||||
|
}
|
||||||
|
// 判断是否是合法的 index
|
||||||
|
if (tmp_data[0] >= 'A' && tmp_data[0] <= 'Z') {
|
||||||
|
if (!check_index_valid(table, tmp_data))
|
||||||
|
return -1;
|
||||||
|
// 0 表示 列,剩下的是行
|
||||||
|
int col = tmp_data[0] - 'A';
|
||||||
|
int row = 0;
|
||||||
|
for (int k = 1; k < strlen(tmp_data); k++) {
|
||||||
|
row = row * 10 + tmp_data[k] - '0';
|
||||||
|
}
|
||||||
|
// 判断 table->data[row - 1][col] 是否是数字
|
||||||
|
if (strlen(table->data[row - 1][col]) == 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!is_string_all_number(table->data[row - 1][col])) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (minus) {
|
||||||
|
result -= atoi(table->data[row - 1][col]);
|
||||||
|
} else {
|
||||||
|
result += atoi(table->data[row - 1][col]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int k = 0; k < j - i; k++) {
|
||||||
|
if (tmp_data[k] < '0' || tmp_data[k] > '9') {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (minus) {
|
||||||
|
result -= atoi(tmp_data);
|
||||||
|
} else {
|
||||||
|
result += atoi(tmp_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i += j - i;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void printTable(TableInfo *table) {
|
void printTable(TableInfo *table) {
|
||||||
system("cls");
|
system("cls");
|
||||||
printf("Table v0.1 by Luthics\n");
|
printf("Table v0.2 by Luthics\n");
|
||||||
|
int max_l = int_length(table->current_height) + 1;
|
||||||
// render table
|
// render table
|
||||||
for (int i = 0; i < table->current_height; i++) {
|
for (int i = -1; i < table->current_height; i++) {
|
||||||
for (int j = 0; j < table->current_width; j++) {
|
for (int j = -1; j < table->current_width; j++) {
|
||||||
printf("+");
|
printf("+");
|
||||||
|
if (j == -1) {
|
||||||
|
for (int k = 0; k < max_l; k++) {
|
||||||
|
printf("-");
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
for (int k = 0; k < table->column_width[j]; k++) {
|
for (int k = 0; k < table->column_width[j]; k++) {
|
||||||
printf("-");
|
printf("-");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf("+\n");
|
printf("+\n");
|
||||||
for (int j = 0; j < table->current_width; j++) {
|
if (i == -1) {
|
||||||
|
// 输出 A-Z 的列名
|
||||||
|
for (int j = -1; j < table->current_width; j++) {
|
||||||
|
if (j == -1) {
|
||||||
|
printf("|");
|
||||||
|
for (int k = 0; k < max_l; k++) {
|
||||||
|
printf(" ");
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
printf("|");
|
||||||
|
for (int k = 0; k < table->column_width[j] - 1; k++) {
|
||||||
|
printf(" ");
|
||||||
|
}
|
||||||
|
if (select_mode) {
|
||||||
|
if (current_x - 1 == j && current_y == 0) {
|
||||||
|
// RED
|
||||||
|
printf("\033[31m");
|
||||||
|
// BOLD
|
||||||
|
printf("\033[1m");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("%c", 'A' + j);
|
||||||
|
if (select_mode) {
|
||||||
|
if (current_x - 1 == j && current_y == 0) {
|
||||||
|
// RESET
|
||||||
|
printf("\033[0m");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("|\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (int j = -1; j < table->current_width; j++) {
|
||||||
|
if (j == -1) {
|
||||||
|
printf("|");
|
||||||
|
int data_length = int_length(i + 1);
|
||||||
|
for (int k = 0; k < max_l - data_length; k++) {
|
||||||
|
printf(" ");
|
||||||
|
}
|
||||||
|
if (select_mode) {
|
||||||
|
if (current_x == 0 && current_y == i + 1) {
|
||||||
|
// RED
|
||||||
|
printf("\033[31m");
|
||||||
|
// BOLD
|
||||||
|
printf("\033[1m");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("%d", i + 1);
|
||||||
|
if (select_mode) {
|
||||||
|
if (current_x == 0 && current_y == i + 1) {
|
||||||
|
// RESET
|
||||||
|
printf("\033[0m");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
printf("|");
|
printf("|");
|
||||||
int data_length =
|
int data_length =
|
||||||
table->data[i][j] == NULL ? 0 : strlen(table->data[i][j]);
|
table->data[i][j] == NULL ? 0 : strlen(table->data[i][j]);
|
||||||
|
|
||||||
if (data_length == 0) {
|
if (data_length == 0) {
|
||||||
if (i == current_y && j == current_x) {
|
if (i == current_y && j == current_x && !select_mode) {
|
||||||
printf("_");
|
printf("_");
|
||||||
} else {
|
} else {
|
||||||
printf(" ");
|
printf(" ");
|
||||||
|
@ -80,33 +606,93 @@ void printTable(TableInfo *table) {
|
||||||
printf(" ");
|
printf(" ");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
int formatter = 0;
|
||||||
|
if (table->data[i][j][0] == '=') {
|
||||||
|
formatter = 1;
|
||||||
|
}
|
||||||
int add_ = 0;
|
int add_ = 0;
|
||||||
if (i == current_y && j == current_x) {
|
if (select_mode) {
|
||||||
|
if (current_x == j + 1 || current_y == i + 1) {
|
||||||
|
// RED
|
||||||
|
printf("\033[31m");
|
||||||
|
// BOLD
|
||||||
|
printf("\033[1m");
|
||||||
|
}
|
||||||
|
} else if (i == current_y && j == current_x) {
|
||||||
// RED
|
// RED
|
||||||
printf("\033[31m");
|
printf("\033[31m");
|
||||||
// BOLD
|
// BOLD
|
||||||
printf("\033[1m");
|
printf("\033[1m");
|
||||||
|
} else if (formatter) {
|
||||||
|
// BLUE
|
||||||
|
printf("\033[34m");
|
||||||
|
// BOLD
|
||||||
|
printf("\033[1m");
|
||||||
}
|
}
|
||||||
for (int k = 0; k < data_length; k++) {
|
int formatter_success = 0;
|
||||||
printf("%c", table->data[i][j][k]);
|
if (formatter && !select_mode &&
|
||||||
|
!(i == current_y && j == current_x)) {
|
||||||
|
// todo 先计算后渲染,修复列宽不合适的bug
|
||||||
|
int data = cal_formula(table, j, i);
|
||||||
|
if (data == -1) {
|
||||||
|
formatter_success = 0;
|
||||||
|
} else {
|
||||||
|
char *tmp_data =
|
||||||
|
(char *)malloc(sizeof(char) * MAX_DATA_LENGTH);
|
||||||
|
sprintf(tmp_data, "%d", data);
|
||||||
|
data_length = strlen(tmp_data);
|
||||||
|
printf("%s", tmp_data);
|
||||||
|
table->column_width[j] =
|
||||||
|
max(table->column_width[j], strlen(tmp_data));
|
||||||
|
formatter_success = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (i == current_y && j == current_x) {
|
if (!formatter_success) {
|
||||||
|
for (int k = 0; k < data_length; k++) {
|
||||||
|
printf("%c", table->data[i][j][k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (select_mode) {
|
||||||
|
if (current_x == j + 1 || current_y == i + 1) {
|
||||||
|
// RESET
|
||||||
|
printf("\033[0m");
|
||||||
|
}
|
||||||
|
} else if (i == current_y && j == current_x) {
|
||||||
// RESET
|
// RESET
|
||||||
printf("\033[0m");
|
printf("\033[0m");
|
||||||
|
// 如果还有空间,就补上下划线
|
||||||
if (table->column_width[j] - data_length > 0) {
|
if (table->column_width[j] - data_length > 0) {
|
||||||
printf("_");
|
printf("_");
|
||||||
add_ = 1;
|
add_ = 1;
|
||||||
}
|
}
|
||||||
|
} else if (formatter) {
|
||||||
|
// Reset
|
||||||
|
printf("\033[0m");
|
||||||
}
|
}
|
||||||
for (int k = 0; k < table->column_width[j] - data_length - add_;
|
if (formatter) {
|
||||||
k++) {
|
// 补上空格
|
||||||
printf(" ");
|
for (int k = 0; k < table->column_width[j] - data_length;
|
||||||
|
k++) {
|
||||||
|
printf(" ");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int k = 0;
|
||||||
|
k < table->column_width[j] - data_length - add_; k++) {
|
||||||
|
printf(" ");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf("|\n");
|
printf("|\n");
|
||||||
}
|
}
|
||||||
for (int j = 0; j < table->current_width; j++) {
|
for (int j = -1; j < table->current_width; j++) {
|
||||||
|
if (j == -1) {
|
||||||
|
printf("+");
|
||||||
|
for (int k = 0; k < max_l; k++) {
|
||||||
|
printf("-");
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
printf("+");
|
printf("+");
|
||||||
for (int k = 0; k < table->column_width[j]; k++) {
|
for (int k = 0; k < table->column_width[j]; k++) {
|
||||||
printf("-");
|
printf("-");
|
||||||
|
@ -215,49 +801,107 @@ int handleKeyPress(int key, TableInfo *table) {
|
||||||
if (key == 224) { // 特殊键
|
if (key == 224) { // 特殊键
|
||||||
key = getch(); // 获取特殊键码
|
key = getch(); // 获取特殊键码
|
||||||
if (key == KEY_LEFT_ARROW) {
|
if (key == KEY_LEFT_ARROW) {
|
||||||
if (current_x > 0) {
|
if (select_mode) {
|
||||||
current_x--;
|
// 选择模式,0,0是左上角,0,1 0,2 0,3 代表每行行号 1,0 2,0 3,0
|
||||||
} else if (current_x == 0) {
|
// 代表每列列号
|
||||||
if (current_y == -1) {
|
if (current_y == 0) {
|
||||||
current_x = FUNCTION_NUM - 1;
|
if (current_x > 1)
|
||||||
} else {
|
current_x--;
|
||||||
current_x = table->current_width - 1;
|
else
|
||||||
|
current_x = table->current_width;
|
||||||
}
|
}
|
||||||
|
if (current_x == 0) {
|
||||||
|
current_y = 0;
|
||||||
|
current_x = table->current_width;
|
||||||
|
}
|
||||||
|
status = 1;
|
||||||
|
} else {
|
||||||
|
if (current_x > 0) {
|
||||||
|
current_x--;
|
||||||
|
} else if (current_x == 0) {
|
||||||
|
if (current_y == -1) {
|
||||||
|
current_x = FUNCTION_NUM - 1;
|
||||||
|
} else {
|
||||||
|
current_x = table->current_width - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
status = 1;
|
||||||
}
|
}
|
||||||
status = 1;
|
|
||||||
}
|
}
|
||||||
if (key == KEY_RIGHT_ARROW) {
|
if (key == KEY_RIGHT_ARROW) {
|
||||||
if (current_y == -1) {
|
if (select_mode) {
|
||||||
current_x = (current_x + 1) % FUNCTION_NUM;
|
if (current_y == 0) {
|
||||||
|
if (current_x < table->current_width)
|
||||||
|
current_x++;
|
||||||
|
else
|
||||||
|
current_x = 1;
|
||||||
|
}
|
||||||
|
if (current_x == 0) {
|
||||||
|
current_y = 0;
|
||||||
|
current_x = 1;
|
||||||
|
}
|
||||||
|
status = 1;
|
||||||
} else {
|
} else {
|
||||||
current_x = (current_x + 1) % table->current_width;
|
if (current_y == -1) {
|
||||||
|
current_x = (current_x + 1) % FUNCTION_NUM;
|
||||||
|
} else {
|
||||||
|
current_x = (current_x + 1) % table->current_width;
|
||||||
|
}
|
||||||
|
status = 1;
|
||||||
}
|
}
|
||||||
status = 1;
|
|
||||||
}
|
}
|
||||||
if (key == KEY_UP_ARROW) {
|
if (key == KEY_UP_ARROW) {
|
||||||
if (current_y > 0) {
|
if (select_mode) {
|
||||||
current_y--;
|
if (current_x == 0) {
|
||||||
} else if (current_y == 0) {
|
if (current_y > 1)
|
||||||
current_y = -1;
|
current_y--;
|
||||||
current_x = min(FUNCTION_NUM - 1, current_x);
|
else
|
||||||
} else if (current_y == -1) {
|
current_y = table->current_height;
|
||||||
current_y = table->current_height - 1;
|
}
|
||||||
current_x = min(table->current_width - 1, current_x);
|
if (current_y == 0) {
|
||||||
|
current_x = 0;
|
||||||
|
current_y = table->current_height;
|
||||||
|
}
|
||||||
|
status = 1;
|
||||||
|
} else {
|
||||||
|
if (current_y > 0) {
|
||||||
|
current_y--;
|
||||||
|
} else if (current_y == 0) {
|
||||||
|
current_y = -1;
|
||||||
|
current_x = min(FUNCTION_NUM - 1, current_x);
|
||||||
|
} else if (current_y == -1) {
|
||||||
|
current_y = table->current_height - 1;
|
||||||
|
current_x = min(table->current_width - 1, current_x);
|
||||||
|
}
|
||||||
|
status = 1;
|
||||||
}
|
}
|
||||||
status = 1;
|
|
||||||
}
|
}
|
||||||
if (key == KEY_DOWN_ARROW) {
|
if (key == KEY_DOWN_ARROW) {
|
||||||
if (current_y < table->current_height - 1 && current_y >= 0) {
|
if (select_mode) {
|
||||||
current_y++;
|
if (current_x == 0) {
|
||||||
} else if (current_y == table->current_height - 1) {
|
if (current_y < table->current_height)
|
||||||
// TO FUNCTIONS AREA
|
current_y++;
|
||||||
current_y = -1;
|
else
|
||||||
current_x = min(FUNCTION_NUM - 1, current_x);
|
current_y = 1;
|
||||||
} else if (current_y == -1) {
|
}
|
||||||
current_y = 0;
|
if (current_y == 0) {
|
||||||
current_x = min(table->current_width - 1, current_x);
|
current_x = 0;
|
||||||
|
current_y = 1;
|
||||||
|
}
|
||||||
|
status = 1;
|
||||||
|
} else {
|
||||||
|
if (current_y < table->current_height - 1 && current_y >= 0) {
|
||||||
|
current_y++;
|
||||||
|
} else if (current_y == table->current_height - 1) {
|
||||||
|
// TO FUNCTIONS AREA
|
||||||
|
current_y = -1;
|
||||||
|
current_x = min(FUNCTION_NUM - 1, current_x);
|
||||||
|
} else if (current_y == -1) {
|
||||||
|
current_y = 0;
|
||||||
|
current_x = min(table->current_width - 1, current_x);
|
||||||
|
}
|
||||||
|
status = 1;
|
||||||
}
|
}
|
||||||
status = 1;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// ctrl + c
|
// ctrl + c
|
||||||
|
@ -272,49 +916,80 @@ int handleKeyPress(int key, TableInfo *table) {
|
||||||
message = "Saved!";
|
message = "Saved!";
|
||||||
status = 1;
|
status = 1;
|
||||||
}
|
}
|
||||||
// 判断 key 是可打印字符
|
if (select_mode) {
|
||||||
if (key >= 32 && key <= 126) {
|
// ENTER
|
||||||
add_char_to_cell(table, current_y, current_x, key);
|
if (key == KEY_ENTER) {
|
||||||
status = 1;
|
end_select_index(table);
|
||||||
}
|
status = 1;
|
||||||
// 退格键
|
}
|
||||||
if (key == 8) {
|
// ESC
|
||||||
del_char_from_cell(table, current_y, current_x);
|
if (key == KEY_ESC) {
|
||||||
status = 1;
|
select_mode = 0;
|
||||||
}
|
current_y = -1;
|
||||||
// ENTER
|
current_x = select_entry;
|
||||||
if (key == KEY_ENTER) {
|
message = "Canceled!";
|
||||||
if (current_y == -1) {
|
status = 1;
|
||||||
if (current_x == 0) {
|
}
|
||||||
save_table_to_file("table.dat", *table);
|
} else {
|
||||||
message = "Saved!";
|
// 判断 key 是可打印字符
|
||||||
}
|
if (key >= 32 && key <= 126) {
|
||||||
if (current_x == 1) {
|
add_char_to_cell(table, current_y, current_x, key);
|
||||||
*table = load_table_from_file("table.dat");
|
status = 1;
|
||||||
message = "Loaded!";
|
}
|
||||||
}
|
// 退格键
|
||||||
if (current_x == 2) {
|
if (key == 8) {
|
||||||
|
del_char_from_cell(table, current_y, current_x);
|
||||||
}
|
status = 1;
|
||||||
if (current_x == 3) {
|
}
|
||||||
|
// ENTER
|
||||||
}
|
if (key == KEY_ENTER) {
|
||||||
if (current_x == 4) {
|
if (current_y == -1) {
|
||||||
|
if (current_x == 0) {
|
||||||
}
|
save_table_to_file("table.dat", *table);
|
||||||
if (current_x == 5) {
|
message = "Saved!";
|
||||||
|
}
|
||||||
}
|
if (current_x == 1) {
|
||||||
if (current_x == 6) {
|
*table = load_table_from_file("table.dat");
|
||||||
|
message = "Loaded!";
|
||||||
|
}
|
||||||
|
if (current_x == 2) {
|
||||||
|
start_select_index(2);
|
||||||
|
}
|
||||||
|
if (current_x == 3) {
|
||||||
|
start_select_index(3);
|
||||||
|
}
|
||||||
|
if (current_x == 4) {
|
||||||
|
start_select_index(4);
|
||||||
|
}
|
||||||
|
if (current_x == 5) {
|
||||||
|
start_select_index(5);
|
||||||
|
}
|
||||||
|
if (current_x == 6) {
|
||||||
|
start_select_index(6);
|
||||||
|
}
|
||||||
|
if (current_x == 7) {
|
||||||
|
alive = 0;
|
||||||
|
message = "Bye!";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 如果以 = 开头
|
||||||
|
if (table->data[current_y][current_x][0] == '=') {
|
||||||
|
if (!check_valid_formatter(table, current_x,
|
||||||
|
current_y)) {
|
||||||
|
message = "Not a valid formatter!";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char *tmp_message = (char *)malloc(sizeof(char) * MAX_MESSAGE_LENGTH);
|
int debug = 0;
|
||||||
sprintf(tmp_message, "x: %d, y: %d", current_x, current_y);
|
if (debug) {
|
||||||
message = tmp_message;
|
char *tmp_message = (char *)malloc(sizeof(char) * MAX_MESSAGE_LENGTH);
|
||||||
|
sprintf(tmp_message, "x: %d, y: %d", current_x, current_y);
|
||||||
|
message = tmp_message;
|
||||||
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
BIN
3/table.dat
BIN
3/table.dat
Binary file not shown.
Loading…
Reference in New Issue