Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
圆石C中的数组中断_C_Arrays_Pebble Watch_Cloudpebble - Fatal编程技术网

圆石C中的数组中断

圆石C中的数组中断,c,arrays,pebble-watch,cloudpebble,C,Arrays,Pebble Watch,Cloudpebble,我正在尝试使用CloudPebble上的C在Pebble中创建一个简单的掷骰子应用程序。我有一个不同大小的模具阵列,你可以使用上/下滚动,你可以使用中间的按钮滚动(目前只生成一个随机数,以后会更有趣)。顶部还有一个标签,显示当前模具 它大部分都在工作,但有一个bug我一辈子都想不出来: 滚动骰子时,至少有一个骰子不会显示骰子编号 坏掉的骰子仍然会滚动,但是rand()函数似乎没有上限(或者上限可能是1000;我在坏掉的骰子上滚动的最高上限是880) 第一次启动时,D6坏了。我修补、调整并添加

我正在尝试使用CloudPebble上的C在Pebble中创建一个简单的掷骰子应用程序。我有一个不同大小的模具阵列,你可以使用上/下滚动,你可以使用中间的按钮滚动(目前只生成一个随机数,以后会更有趣)。顶部还有一个标签,显示当前模具

它大部分都在工作,但有一个bug我一辈子都想不出来:

  • 滚动骰子时,至少有一个骰子不会显示骰子编号
  • 坏掉的骰子仍然会滚动,但是rand()函数似乎没有上限(或者上限可能是1000;我在坏掉的骰子上滚动的最高上限是880)
第一次启动时,D6坏了。我修补、调整并添加了一些代码来查看背景中发生了什么,但突然间D6开始工作(不知道为什么),D20坏了。我试着将数组中的“20”项改为“35”,只是想看看它能做什么,现在D35起作用了,但D2和D4坏了。我把它换回来,不同的骰子破了

附件是我当前的代码,目前显示D20和D4已损坏。我已经去除了所有的垃圾、返工和用于故障排除的辅助代码,因为这些都没有帮助

有人能解释一下为什么骰子看起来是随机的,以及如何修复它吗?谢谢大家!

#include <pebble.h>

static Window *s_main_window;
static TextLayer *s_label_layer;
static TextLayer *s_output_layer;

static int dice_select = 6;
static char *die_label = "D";
static char *dice_array[] = {"2", "4", "6", "8", "10", "12", "20", "100", NULL};

// === Separate Processes ===

    static void update_label(char *die) {
      die_label[1] = '\0';
      strcat(die_label, die);
      text_layer_set_text(s_label_layer, die_label);
    }

// === Main Window Processes ===

static void main_window_load(Window *window) {
  Layer *window_layer = window_get_root_layer(window);
  GRect window_bounds = layer_get_bounds(window_layer);

  // Create label TextLayer
  s_label_layer = text_layer_create(GRect(5, 0, window_bounds.size.w - 10, 24));
  text_layer_set_font(s_label_layer, fonts_get_system_font(FONT_KEY_GOTHIC_18_BOLD));
  text_layer_set_text_alignment(s_label_layer, GTextAlignmentCenter);
  text_layer_set_text(s_label_layer, "D20");
  text_layer_set_overflow_mode(s_label_layer, GTextOverflowModeWordWrap);
  layer_add_child(window_layer, text_layer_get_layer(s_label_layer));

  // Create output TextLayer
  s_output_layer = text_layer_create(GRect(5, 24, window_bounds.size.w - 10, window_bounds.size.h - 24));
  text_layer_set_font(s_output_layer, fonts_get_system_font(FONT_KEY_GOTHIC_28));
  text_layer_set_text(s_output_layer, "No button pressed yet.");
  text_layer_set_overflow_mode(s_output_layer, GTextOverflowModeWordWrap);
  layer_add_child(window_layer, text_layer_get_layer(s_output_layer));
}

static void main_window_unload(Window *window) {
  // Destroy output TextLayer
  text_layer_destroy(s_label_layer);
  text_layer_destroy(s_output_layer);
}


// === Button Handlers ===

static void up_click_handler(ClickRecognizerRef recognizer, void *context) {
  // Increment dice selection
  if(dice_select < 7) {
    dice_select += 1;
  } 
  update_label(dice_array[dice_select]);
}

static void select_click_handler(ClickRecognizerRef recognizer, void *context) {
  // Establish die selection
  char *die = dice_array[dice_select];     
  int die_sides = atoi(die);

  // Roll die
  int result = rand() % die_sides + 1;
  char *result_str = "";
  snprintf(result_str, sizeof(result_str), "%d", result);

  // Print result
  text_layer_set_text(s_output_layer, result_str);
}

static void down_click_handler(ClickRecognizerRef recognizer, void *context) {
  // Increment dice selection
  if(dice_select > 0) {
    dice_select -= 1;
  }
  update_label(dice_array[dice_select]);
}

static void click_config_provider(void *context) {
  // Register the ClickHandlers
  window_single_click_subscribe(BUTTON_ID_UP, up_click_handler);
  window_single_click_subscribe(BUTTON_ID_SELECT, select_click_handler);
  window_single_click_subscribe(BUTTON_ID_DOWN, down_click_handler);
}



// === Initialize/Deinitialize App ===

static void init() {
  // Create main Window
  s_main_window = window_create();
  window_set_window_handlers(s_main_window, (WindowHandlers) {
    .load = main_window_load,
    .unload = main_window_unload,
  });
  window_set_click_config_provider(s_main_window, click_config_provider);
  window_stack_push(s_main_window, true);
}

static void deinit() {
  // Destroy main Window
  window_destroy(s_main_window);
}

int main(void) {
  init();
  app_event_loop();
  deinit();
}
但此部件将不再打印卷结果:

  // Roll die
  int result = rand() % die_sides + 1;
  char result_str[32];
  snprintf(result_str, sizeof(result_str), "%d", result);

  // Print result
  text_layer_set_text(s_output_layer, result_str);

问题是这条线

static char *die_label = "D";
die\u标签
指向一个a不应写入的内存区域,并且b只有两个字符的空间,即
D
\0
终止符。因此,
strcat
正在向内存中写入不应该写入的内容

解决方案是将
模具标签
声明为

static char die_label[32] = "D";   // reserve space for 32 characters
然后我建议将更新函数改为

static void update_label(char *die) 
{
  sprintf(die_label, "D%s", die);
  text_layer_set_text(s_label_layer, die_label);
}

这两条线也有同样的问题

char *result_str = "";
snprintf(result_str, sizeof(result_str), "%d", result);
在本例中,您只有一个字符的空间,但传递给
snprintf
的长度是指针的大小,即4或8字节。我会把那些台词改成

char result_str[32];
sprintf( result_str, "%d", result );

针对更新后的问题:


是的,我想知道。显然,
text\u layer\u set\u text
不会复制字符串,它只保留一个指向它的指针。这意味着
结果\u str
不能是局部变量,因为一旦函数返回,局部变量就会超出范围。解决方案是在文件顶部声明
result\u str
,就像声明
die\u label
,或者在函数本身中将其声明为
static

问题在于这一行

static char *die_label = "D";
die\u标签
指向一个a不应写入的内存区域,并且b只有两个字符的空间,即
D
\0
终止符。因此,
strcat
正在向内存中写入不应该写入的内容

解决方案是将
模具标签
声明为

static char die_label[32] = "D";   // reserve space for 32 characters
然后我建议将更新函数改为

static void update_label(char *die) 
{
  sprintf(die_label, "D%s", die);
  text_layer_set_text(s_label_layer, die_label);
}

这两条线也有同样的问题

char *result_str = "";
snprintf(result_str, sizeof(result_str), "%d", result);
在本例中,您只有一个字符的空间,但传递给
snprintf
的长度是指针的大小,即4或8字节。我会把那些台词改成

char result_str[32];
sprintf( result_str, "%d", result );

针对更新后的问题:


是的,我想知道。显然,
text\u layer\u set\u text
不会复制字符串,它只保留一个指向它的指针。这意味着
结果\u str
不能是局部变量,因为一旦函数返回,局部变量就会超出范围。解决方案是在文件顶部声明
result\u str
,就像声明
die\u label
,或者在函数本身中将其声明为
static

Aha,我正在学习!非常感谢。您的修复有一个小问题:Pebble C中不支持sprintf()。我用snprintf替换了它们,现在骰子滚动功能被破坏。@LARPkitten如果您编辑问题并为
更新标签
选择\u单击\u处理程序
,我会看一看。已更新。在这两个函数中,我对
snprintf()
使用了相同的语法,但它的行为并不相同
update\u label
prints,但是
select\u click\u handler
没有。不过,我发现:将
result\u str
更改为静态字符,并修复了它。谢谢你的帮助@Larpketten你赢了我,我只是更新了答案:)很高兴我能帮忙,祝你好运的代码!啊哈,我在学习!非常感谢。您的修复有一个小问题:Pebble C中不支持sprintf()。我用snprintf替换了它们,现在骰子滚动功能被破坏。@LARPkitten如果您编辑问题并为
更新标签
选择\u单击\u处理程序
,我会看一看。已更新。在这两个函数中,我对
snprintf()
使用了相同的语法,但它的行为并不相同
update\u label
prints,但是
select\u click\u handler
没有。不过,我发现:将
result\u str
更改为静态字符,并修复了它。谢谢你的帮助@Larpketten你赢了我,我只是更新了答案:)很高兴我能帮忙,祝你好运的代码!