kexin2024年5月22日

在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]]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值