我想通過 UART 發送字串來除錯我的微控制器程式。現在我面臨將除錯字串連接在一起的問題,因為我必須使用 c 字串。我需要debugMessageOnStack
在堆疊上。
考慮下面的例子:我需要一個像“我最喜歡的顏色是蒙巴頓粉紅色”這樣的字串
const char debugMessageStart[] = "My favorite color is ";
const char* colors[MAX_COLORS] = {[GREEN] = "green", [ORANGE] = "orange", [PINK] = "mountbatten pink"};
char debugMessageOnStack[DEBUG_MESSAGE_LENGTH];
我知道DEBUG_MESSAGE_LENGTH
手工計算很容易,但我希望它是動態計算的,所以每次我添加一個比所有現有顏色字串都長的新顏色字串時,我不必手動重新計算它。
理論上應該是可能的,因為colors
在編譯之前知道每個字串的長度,但我不知道我該怎么做。
謝謝!
uj5u.com熱心網友回復:
首先,“但我希望它是動態計算的”沒有多大意義,因為您的陣列必須足夠大以處理最壞的情況。在最壞的情況下,您的代碼不會因堆疊溢位而陷入困境,因此您可以簡單地為該陣列分配足夠大的陣列。
在最壞的情況下,“節省一些堆疊空間”是沒有意義的,因為無論如何這只是一個區域變數,無論大小如何都會在使用后被釋放。
使用結構陣列代替字串陣列:
typedef struct
{
size_t length;
const char* str;
} color_t;
const color_t colors[] =
{
[GREEN] = { sizeof("green")-1, "green" },
...
};
這樣一切都存盤在閃存中并在編譯時計算。如果您對減少代碼重復很迂腐,那么您可以添加一個神秘的宏(通常不推薦):
#define COLOR_INIT(str) { sizeof(str)-1, str }
...
[GREEN] = COLOR_INIT("green"),
uj5u.com熱心網友回復:
通常應該避免在堆疊上使用可變大小的物件。首先,存在字串的大小可能增長太多而無法保存在堆疊中的風險。第二,使用自動VLA 或alloca()
通常比固定大小物件的堆疊分配效率低(盡管仍然比 快malloc()
)。
無論如何,要處理堆疊上未知大小的字串,您可以使用snprintf
函式。該函式的作業原理類似,printf()
但它將字符存盤到字串中。但是,如果一個NULL
作為緩沖區傳遞,0 作為大小傳遞,它會回傳一些將存盤到緩沖區的字符。
該字串將分兩次生成:
size_t n = snprintf(NULL, 0, "My favorite color is %s", colors[ORANGE]);
char msg[n 1]; // 1 for the terminator
snprintf(msg, n 1, "My favorite color is %s", colors[ORANGE]);
將訊息生成包裝到 helper 中以避免重復可能是一個好主意:
size_t mk_msg(char *msg, size_t n, int color) {
return snprintf(msg, n, "My favorite color is %s", colors[color]);
}
這種方法的優點是非常通用且可重用。
uj5u.com熱心網友回復:
如果您的編譯器支持 VLA,您可以使用它:
#include <stdio.h>
#include <string.h>
#define MAX_COLORS 3
#define GREEN 0
#define ORANGE 1
#define PINK 2
const char debugMessageStart[] = "My favorite color is ";
const char* colors[] = { [GREEN] = "green",[ORANGE] = "orange", [PINK] = "mountbatten pink" };
int main(void)
{
const char* color = colors[ORANGE];
int length = strlen(debugMessageStart) strlen(color) 1;
char debugMessageOnStack[length];
strcpy(debugMessageOnStack, debugMessageStart);
strcat(debugMessageOnStack, color);
printf("%s\n", debugMessageOnStack);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/317711.html
上一篇:AttributeError:'int'物件沒有屬性'get'我該如何修復它
下一篇:選擇值包含新列的特定字串