在CLion上调试程序
使用程序的模板来调试程序
在下图中输入作为console窗口输入输入数据。
下面将程序记录一下
首先的是模板
//main.c
/*
*
* Description:
* Caution:本地调试时,只编译运行这一个文件,不要链接solution.c!因为本文件已经include了solution.c
*/
#include <stdlib.h>
#include <stdio.h>
#include "securec.h"
#include "solution.c"
// 以下为考题输入输出框架,此部分代码不建议改动;提交代码时请勿包含下面代码
static int *ExpandListInt(int *ptr, size_t oldLen, size_t newLen)
{
int *newPtr = (int *)malloc(newLen * sizeof(*ptr));
if (newPtr) {
for (size_t i = 0; i < oldLen; ++i) {
newPtr[i] = ptr[i];
}
}
if (ptr) { free(ptr); }
return newPtr;
}
static void SkipWs(void)
{
char c = (char)getchar();
while (c == ' ' || c == '\r' || c == '\n') {
c = (char)getchar();
}
(void)ungetc(c, stdin);
}
static void FreeListInt(int *value)
{
if (!value) { return; }
free(value);
}
static bool ReadListInt(int **value, size_t *size)
{
SkipWs();
char c = (char)getchar();
if (c != '[') { return false; }
SkipWs();
c = (char)getchar();
if (c == ']') {
*value = NULL;
*size = 0;
return true;
}
(void)ungetc(c, stdin);
size_t cap = 32;
for (size_t pos = 0;; ++pos) {
if (pos == 0 || pos >= cap) {
cap *= 2;
*value = ExpandListInt(*value, pos, cap);
if (*value == NULL) { break; }
}
if (scanf_s("%d", &(*value)[pos]) != 1) { break; }
SkipWs();
int in = getchar();
if (in == EOF) { break; }
if ((char)in == ']') {
*size = pos + 1;
return true;
}
if ((char)in != ',') { break; }
}
FreeListInt(*value);
*value = NULL;
return false;
}
static void PrintResultInfo(const ResultInfo *ptr)
{
printf("[");
printf("%d", ptr->time);
printf(", ");
printf("%d", ptr->timerId);
printf("]");
}
static void PrintListResultInfo(const ResultInfo *value, size_t size)
{
printf("[");
for (size_t i = 0; i < size; ++i) {
PrintResultInfo(&value[i]);
if (i + 1 < size) { printf(", "); }
}
printf("]");
}
static void FreeListResultInfo(ResultInfo *value)
{
if (!value) { return; }
free(value);
}
static bool CallCreate(TimerSystem **sys)
{
int *timers = NULL;
size_t timersSize = 0;
bool isOk = false;
do {
SkipWs();
char c = (char)getchar();
if (c != '(') { break; }
if (!ReadListInt(&timers, &timersSize)) { break; }
SkipWs();
c = (char)getchar();
if (c != ')') { break; }
isOk = true;
*sys = TimerSystemCreate(timers, timersSize);
} while (false);
FreeListInt(timers);
timers = NULL;
printf("null\n");
return isOk;
}
static bool CallTimerStart(TimerSystem *sys)
{
int timerId = 0;
bool returnValue = false;
bool isOk = false;
do {
SkipWs();
char c = (char)getchar();
if (c != '(') { break; }
if (scanf_s("%d", &timerId) != 1) { break; }
SkipWs();
c = (char)getchar();
if (c != ')') { break; }
isOk = true;
returnValue = TimerSystemTimerStart(sys, timerId);
printf("%s", returnValue ? "true" : "false");
} while (false);
printf("\n");
return isOk;
}
static bool CallTimerStop(TimerSystem *sys)
{
int timerId = 0;
bool returnValue = false;
bool isOk = false;
do {
SkipWs();
char c = (char)getchar();
if (c != '(') { break; }
if (scanf_s("%d", &timerId) != 1) { break; }
SkipWs();
c = (char)getchar();
if (c != ')') { break; }
isOk = true;
returnValue = TimerSystemTimerStop(sys, timerId);
printf("%s", returnValue ? "true" : "false");
} while (false);
printf("\n");
return isOk;
}
static bool CallRunTimerSystem(TimerSystem *sys)
{
int nowTime = 0;
ResultInfo *returnValue = NULL;
size_t returnSize = 0;
bool isOk = false;
do {
SkipWs();
char c = (char)getchar();
if (c != '(') { break; }
if (scanf_s("%d", &nowTime) != 1) { break; }
SkipWs();
c = (char)getchar();
if (c != ')') { break; }
isOk = true;
returnValue = TimerSystemRunTimerSystem(sys, nowTime, &returnSize);
PrintListResultInfo(returnValue, returnSize);
} while (false);
FreeListResultInfo(returnValue);
returnValue = NULL;
printf("\n");
return isOk;
}
static bool GetCmdName(char* buffer, size_t size)
{
SkipWs();
size_t pos = 0;
char c = (char)getchar();
while (c != '\r' && c != '\n' && c != ' ' && c != '(' && feof(stdin) == 0 && pos < size) {
buffer[pos++] = c;
c = (char)getchar();
}
if (pos >= size) { return false; }
buffer[pos] = '\0';
if (pos == 0) { return feof(stdin) != 0; }
if (feof(stdin) == 0) { (void)ungetc(c, stdin); }
return true;
}
int main(void)
{
char cmd[64] = {0};
bool isOk = GetCmdName(cmd, sizeof(cmd));
TimerSystem *sys = NULL;
if (strcmp(cmd, "TimerSystem") != 0) { isOk = false; }
if (isOk) { isOk = CallCreate(&sys); }
while (isOk) {
const char *cmds[] = {"timerStart", "timerStop", "runTimerSystem"};
bool (*funcs[])(TimerSystem *sys) = {CallTimerStart, CallTimerStop, CallRunTimerSystem};
if (!GetCmdName(cmd, sizeof(cmd))) {
isOk = false;
break;
}
if (cmd[0] == '\0') {
TimerSystemFree(sys);
return 0;
}
isOk = false;
for (size_t i = 0; i < sizeof(cmds) / sizeof(cmds[0]); ++i) {
if (strcmp(cmd, cmds[i]) == 0) {
isOk = (*funcs[i])(sys);
break;
}
}
}
printf("Error: Input format incorrect!");
if (sys) { TimerSystemFree(sys); }
return 0;
}
//solution.c
/*
*
* Description:
* Caution:本地调试时,只编译运行timer.c文件,不要链接这个文件!因为本文件已经被timer.c文件include了
*/
#include <stdbool.h>
typedef struct {
} TimerSystem;
typedef struct {
int time;
int timerId;
} ResultInfo;
// 注意:该函数为类构造函数,返回的对象指针将作为其他待实现函数的入参;框架代码在调用该函数后,会输出 null(而非指针)
static TimerSystem *TimerSystemCreate(const int *timers, size_t timersSize)
{
return NULL;
}
static bool TimerSystemTimerStart(TimerSystem *sys, int timerId)
{
return false;
}
static bool TimerSystemTimerStop(TimerSystem *sys, int timerId)
{
return false;
}
// 注意:返回的数组必须在函数内调用malloc进行内存分配,由框架代码调用free进行内存释放。
// 返回的数组长度需要保存在 *returnSize 中。
static ResultInfo *TimerSystemRunTimerSystem(TimerSystem *sys, int nowTime, size_t *returnSize)
{
*returnSize = 0;
return NULL;
}
static void TimerSystemFree(TimerSystem *sys)
{
}
实现逻辑代码
/*
*
*
* Caution:本地调试时,只编译运行timer.c文件,不要链接这个文件!因为本文件已经被timer.c文件include了
*/
#include <stdbool.h>
#include <malloc.h>
#include <stdlib.h>
typedef struct {
int time;
int timerId;
} ResultInfo;
typedef struct {
ResultInfo resultInfo;
int count;
int terminalTime;
int sysTime;
bool status;
} TimerSystem;
// 注意:该函数为类构造函数,返回的对象指针将作为其他待实现函数的入参;框架代码在调用该函数后,会输出 null(而非指针)
static TimerSystem* TimerSystemCreate(const int* timers, size_t timersSize)
{
TimerSystem* timerSystem = (TimerSystem*) malloc(sizeof(TimerSystem) * timersSize); //创建堆空间指针
for (int i = 0; i < timersSize; i++) {
timerSystem[i].resultInfo.timerId = i;
timerSystem[i].resultInfo.time = timers[i];
timerSystem[i].count = timersSize;
timerSystem[i].sysTime = 0;
timerSystem[i].terminalTime = 0;
timerSystem[i].status = false;
}
return timerSystem;
}
static bool TimerSystemTimerStart(TimerSystem* sys, int timerId)
{
int count = sys[0].count;
for (int i = 0; i < count; i++) {
if (timerId == sys[i].resultInfo.timerId) {
sys[i].status = true;
sys[i].terminalTime = sys[i].sysTime; //start时更新成系统最终时间,否则terminalTime保持不变,最为下次计数起始时间
return true;
}
}
return false;
}
static bool TimerSystemTimerStop(TimerSystem* sys, int timerId)
{
int count = sys[0].count;
for (int i = 0; i < count; i++) {
if (timerId == sys[i].resultInfo.timerId) {
sys[i].status = false;
return true;
}
}
return false;
}
static int compare(const void* a, const void* b)
{
int diff = ((ResultInfo*) a)->time - ((ResultInfo*) b)->time;
if (diff == 0) {
diff = ((ResultInfo*) a)->timerId - ((ResultInfo*) b)->timerId;
}
return diff;
}
// 注意:返回的数组必须在函数内调用malloc进行内存分配,由框架代码调用free进行内存释放。
// 返回的数组长度需要保存在 *returnSize 中。
static ResultInfo* TimerSystemRunTimerSystem(TimerSystem* sys, int nowTime, size_t* returnSize)
{
int count = sys[0].count;
ResultInfo* array = (ResultInfo*) malloc(sizeof(ResultInfo) * count * 1000);
int arrayIndex = 0;
for (int i = 0; i < count; i++) {
sys[i].sysTime = nowTime; //记录系统最终时间,遇到start时更新成系统最终时间
if (sys[i].status == false) { continue; } //关闭的计时器不再计数
int time = sys[i].resultInfo.time;
int terminalTime = sys[i].terminalTime;
int tempTime = time + terminalTime;
while (tempTime <= nowTime) {
array[arrayIndex].timerId = i;
array[arrayIndex].time = tempTime;
tempTime += time;
arrayIndex++;
}
sys[i].terminalTime = tempTime - time;
}
qsort(array, arrayIndex, sizeof(ResultInfo), compare);
*returnSize = arrayIndex;
return array;
}
static void TimerSystemFree(TimerSystem* sys)
{
free(sys);
}
/*
* 遗留问题,结构体数组是否可以使用{0}初始化
* qsort对结构体数据排序
* start时全部更新到最新时间,下次计数时间为最新时间。如果不是start,下次计数时间为上一次最后的时间
*/
CMakelist.txt
cmake_minimum_required(VERSION 3.16.5)
message("this is cmakelist log")
message(${CMAKE_CURRENT_SOURCE_DIR})
get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME)
message(${ProjectId})
message(${ProjectId})
message(NAME)
string(REPLACE " " "_" ProjectId ${ProjectId})
message(${ProjectId})
project(${ProjectId} C)
#添加宏定义Debug为CMAKE_BUILD_TYPE
SET(CMAKE_BUILD_TYPE "Debug")
set(CMAKE_CXX_STANDARD 17)
if (CMAKE_BUILD_TYPE STREQUAL Debug)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -D_DEBUG")
else ()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -D_DEBUG")
endif ()
#添加头文件
#例如:include_directories(/usr/include/abc /usr/include/xxx)
#是将“/usr/include/abc”和“/usr/include/xxx”这两个目录添加至编译器的头文件搜索目录(两个目录用空格分隔)。
include_directories(../3rd/huawei_secure_c-master/include)
aux_source_directory(../3rd/huawei_secure_c-master/src secureCSrc)
#通过编译源文件来创建一个可执行文件,其中,name是生成的可执行文件的名称,source是创建可执行文件所需要的源文件。
#源文件可以使用aux_source_directory指令返回的变量(将源文件保存在这个变量中),也可以是指定的.cpp文件(注意路径)。
add_executable(${ProjectId}
${secureCSrc}
solution.c
main.c)
针对上面的逻辑代码,有两个测试用例
----------------------------------
TimerSystem([3, 5])
timerStart(0)
timerStart(1)
runTimerSystem(17)
timerStop(1)
runTimerSystem(20)
timerStop(1)
timerStop(2)
----------------------------------
TimerSystem([8, 4, 11])
runTimerSystem(2)
timerStart(1)
timerStart(4)
runTimerSystem(8)
timerStart(0)
timerStart(2)
timerStart(1)
runTimerSystem(20)
timerStop(1)
runTimerSystem(30)
测试输出
null
[]
true
false
[[4, 1], [8, 1]]
true
true
true
[[4, 1], [8, 0], [8, 1], [11, 2], [12, 1], [16, 0], [16, 1], [20, 1]]
true
[[22, 2], [24, 0]]
预期输出null
[]
true
false
[[6, 1]]
true
true
true
[[12, 1], [16, 0], [16, 1], [19, 2], [20, 1]]
true
[[24, 0], [30, 2]]