首页 > 解决方案 > 结构内的字符串被覆盖,我不知道为什么

问题描述

在过去的两个小时里我遇到了这个问题,我不明白发生了什么。我希望它打印这个

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";
    }
  );
};

标签: c

解决方案


您的默认横幅文本比 长MAX_STRING_LENGTH,因此当您将其复制到config.banner数组末尾时,会导致未定义的行为。

确保所有缓冲区都足够大以存储您期望的最长字符串(考虑到终止符),或者将字符串截断到缓冲区的长度,或者使用动态内存并根据需要调整缓冲区大小。


推荐阅读