c - 结构内的字符串被覆盖,我不知道为什么
问题描述
在过去的两个小时里我遇到了这个问题,我不明白发生了什么。我希望它打印这个
ROBCO INDUSTRIES UNIFIED OPERATING SYSTEM
COPYRIGHT 2075-2077 ROBCO INDUSTRIES
-Server 6-
但相反,它显示了这个
ROBCO INDUSTRIES UNIFIED OPERATING SYSTEM
COPYRIGHT Testing testing 123
我不知道为什么会这样,但希望你能帮助我。(如果你想知道这是一个辐射终端仿真器的用途)。问问你是否有更多的细节。谢谢!
如果您需要知道,它正在像这样编译
gcc test.c configParser.c -lconfig
测试.c
#include <stdio.h>
#include "robco.h"
int main() {
struct config_struct config;
config = getConfig("test_config.cfg");
printf("%s", config.banner);
return 0;
}
配置解析器.c
#include <stdio.h>
#include <libconfig.h>
#include <string.h>
#include "robco.h"
int cap(int num, int cap) {
return (num > cap) ? cap : num;
}
struct config_struct getConfig(const char *filename)
{
config_t cfg;
config_setting_t *root, *menu, *options, *option;
// Read the file. If there is an error, report it and exit.
config_init(&cfg);
config_read_file(&cfg, filename);
root = config_root_setting(&cfg);
// Get the banner from the config file if it exists, if not use the default set in robco.h
const char *banner;
if (! config_setting_lookup_string(root, "banner", &banner) ) {
banner = DEFAULT_BANNER;
}
// Create the config struct and fill in the banner
struct config_struct config;
strcpy(config.banner, banner);
// Get the menu
menu = config_lookup(&cfg, "menu");
// If it can't fetch the menu for any reason return -1
if(! menu) {
return;
}
// Get the options
options = config_setting_get_member(menu, "options");
if(! options) {
return;
}
// Get number of options
config.menu.num_options = cap(config_setting_length(options), MAX_OPTIONS);
// Get the title. If it doesn't exist use the default
const char *title;
if (! config_setting_lookup_string(menu, "title", &title) ) {
title = DEFAULT_TITLE;
}
strcpy(config.menu.title, title);
// Loop through and get the text for all the options
for(int i = 0; i < config.menu.num_options; ++i)
{
option = config_setting_get_elem(options, i);
const char *text;
config_setting_lookup_string(option, "text", &text);
strcpy(config.menu.options[i].text, text);
}
return config;
}
robco.h
#define MAX_STRING_LENGTH 52
#define MAX_OPTIONS 5
#define DEFAULT_BANNER "ROBCO INDUSTRIES UNIFIED OPERATING SYSTEM\nCOPYRIGHT 2075-2077 ROBCO INDUSTRIES\n-Server 6-"
#define DEFAULT_TITLE "-=- TEST TITLE -=-"
struct option_struct {
char text[MAX_STRING_LENGTH];
};
struct menu_struct {
struct option_struct options[MAX_OPTIONS];
int num_options;
int selected;
char title[MAX_STRING_LENGTH];
};
struct config_struct {
char banner[MAX_STRING_LENGTH];
struct menu_struct menu;
};
void printCenter(char msg[], int startRow);
void printMenuOption(char msg[], int startRow);
void drawMenu(struct menu_struct menu, int startRow);
void init_graphics();
struct config_struct getConfig(const char *filename);
test_config.cfg
menu: {
title: "Super Secret Valve Control Panel";
options: (
{
text: "Testing testing 123";
},
{
text: "THE SUN IS A DEADLY LASER";
}
);
};
解决方案
您的默认横幅文本比 长MAX_STRING_LENGTH
,因此当您将其复制到config.banner
数组末尾时,会导致未定义的行为。
确保所有缓冲区都足够大以存储您期望的最长字符串(考虑到终止符),或者将字符串截断到缓冲区的长度,或者使用动态内存并根据需要调整缓冲区大小。
推荐阅读
- python - Pandas:根据多列条件创建新列
- python - numpy 追加两个以上的数组
- python - 如何使用solve_ivp求解复杂的矩阵微分方程?
- apache - 使用 GET 参数将所有子文件夹重定向到 URL
- c# - MVC FileStreamResult 未下载具有自定义文件名的文件
- ruby-on-rails - 锚标记未路由到 Rails 中的预期页面
- ios - 将 IndexPath 插入 NSSet 目标-C
- ios - xam.plugin.geolocator 在 ios 中不起作用
- memory-leaks - 如何检测 C++ Builder 10.4 / Android 应用程序中的泄漏
- javascript - 用 Puppeteer 覆盖 showOpenFilePicker