0

我是一名具有强大的 Java for Android 背景的程序员。我对 C 语言非常陌生,我只是学习它来为 Pebble 编写配套应用程序。编辑:我正在使用 cloudpebble,所以我无法控制库。

这是我认为问题所在的代码部分的摘要:

#include <pebble.h>

static int s_time_a_min;
static int s_time_a_h;
static int s_time_b_min = 0;
static int s_time_b_h = 0;
static int s_time_b_total;
char* c_time_string_min;
char* c_time_string_h;

int str_cut(char *str, int begin, int len){ //I got this method from the internet
    int l = strlen(str);

    if (len < 0) len = l - begin;
    if (begin + len > l) len = l - begin;
    memmove(str + begin, str + begin + len, l - len + 1);

    return len;
}

static void update_text(){
    time_t current_time;

    c_time_string_min = ctime(&current_time); //set these two strings the same: current time
    c_time_string_h = ctime(&current_time); //they are only strings so that they can be substringed

    c_time_string_min = str_cut(c_time_string_min, 14, 16); //substring so that the each string has either min or h
    c_time_string_h = str_cut(c_time_string_h, 11, 13); 

    s_si_h = atoi(c_time_string_h); //make the strings integers so that I can do math with them
    s_si_min = atoi(c_time_string_min);

    s_time_b_total = (((s_si_h) * 3600) + ((s_si_min) * 60)) * (123/99); //do some math. Don't ask what it's for.

    do{
        s_time_b_total = s_time_b_total - 10000; //do some more math. Also don't ask what it's for.
        s_time_b_h = s_time_b_h + 1;
    }while(s_ra_all > 10000);

    do{
        s_time_b_total = s_time_b_total - 100;
        s_time_b_min = s_time_b_min + 1;
    }while(s_ra_all > 100);

    //Here is where I think the problem lies.
    const char* buf = (char)(((int)0)+s_time_b_h) + ":" + (char)(((int)0)+s_time_b_min); //create a string that merges the two integers together and puts a colon in the middle                        

    text_layer_set_text(s_time_layer, buf); //Set text
}

然后是通常的 Window_load、main、init 等。

请告诉我我做错了什么。谢谢。

4

2 回答 2

1

在 C 中,简单的数字相加不会形成字符串。

相反,创建一个缓冲区并打印到它。

// const char* buf = (char)(((int)0)+s_time_b_h) + ":" + 
//    (char)(((int)0)+s_time_b_min);

//create a string that merges 2 integers together and puts a colon in the middle
char   buf[100];
sprintf(buf, "%d:%d", s_time_b_h, s_time_b_min);
于 2015-01-01T00:00:31.240 回答
0

如果没有看到链接器错误,就不可能知道问题所在。发生链接器错误的一个常见原因是无法解析符号。当您有函数原型或变量声明但没有定义时,就会发生这种情况。考虑:

#include <stdio.h>
extern char *foo;
int main(void) { printf("%s\n", foo); return 0; }

编译时,你会看到这样的输出:

[dho@zendev ~]$ cc test.c -o test
/tmp/cc2ec2wu.o: In function `main':
test.c:(.text+0x7): undefined reference to `foo'
collect2: error: ld returned 1 exit status

此错误出现在链接阶段,因为编译器对类型的大小有足够的了解以生成所有相关代码。链接最终二进制文件时,变量的存储位置是未知的。同样,考虑:

#include <stdio.h>    
int foo(void);
int main(void) { foo(); return 0; }

[dho@zendev ~]$ cc test.c -o test
/tmp/cc8tgEsT.o: In function `main':
test.c:(.text+0x5): undefined reference to `foo'
collect2: error: ld returned 1 exit status

在这里,我们再次看到编译器有足够的信息来工作,但是在链接时,我们找不到 foo 符号的定义。

在您的代码中,有两个符号既没有声明也没有定义:text_layer_set_texts_time_layer. 有可能pebble.h声明了这些符号,但您没有正确链接来解析它们。如果您做了类似的事情,我希望看到这一点

cc test.c -o test

代替

cc test.c -o test -lpebble

您突出显示的行不可能导致链接器错误,但这是有问题的。在 C 中,+运算符不连接字符串。因此,这条线不会做你认为它正在做的事情:

const char* buf = (char)(((int)0)+s_time_b_h) + ":" + (char)(((int)0)+s_time_b_min);

此外,将整数转换为字符不会使该整数可表示为具有相同逻辑值的字符串。(即int i = 42; char c = (char)i;->c'*',不是"42")。s_time_b_h并且s_time_b_min也不是整数,它们是指向字符的指针。C 中的字符串是由一个NUL字节终止的连续字符字节流(您会看到“NULL 字节”被抛出,但这并不是非常正确)。从这一行可以清楚地看出,您不熟悉动态内存分配或 C 字符串,它们与 Java 有很大不同。

您填充的字符串ctime(3)具有以下形式:

"Wed Jun 30 21:49:08 1993\n"

因此,它们包含换行符。即使您的代码按预期工作,输出buf也会如下所示:

|Wed Jun 30 21:49:08 1993
:Wed Jun 30 21:49:08 1993
|

在此示例中,我使用管道字符来显示字符串的开始和结束位置。

你的电话ctime(3)是有缺陷的。您的值current_time未初始化,因此 的输出ctime(3)未定义。此外,ctime(3)它不是可重入函数,因此您对它的两次调用会相互覆盖。因为ctime(3)具有二级粒度,所以对于您的示例,这可能不是问题——两个调用都将在同一秒内完成,并且它们都使用相同的输入种子 ( current_time)。要正确执行此操作,您需要(例如):

time_t current_time;
char *s_time_b_h;

current_time = time(NULL);
s_time_b_h = ctime(&current_time);

因为ctime(3)不是可重入的,并且您需要两个值,所以您需要在某处为它们分配内存。您可以简单地做到这一点,而不必担心动态内存分配:

/* 
 * ctime(3) says "The reentrant version ctime_r() does the same, 
 * but stores the string in a user-supplied buffer which should have 
 * room for at least 26 bytes."
 *
 * 26 is length of string plus newline plus NUL byte.
 */
#define CTIME_MAX_LEN 26
char h_buf[CTIME_MAX_LEN], min_buf[CTIME_MAX_LEN];
time_t current_time;
char *s_time_b_h, *s_time_b_min;

current_time = time(NULL);
s_time_b_h = ctime_r(&current_time, h_buf);
if (s_time_b_h == NULL) {
    return -1;
}
s_time_b_min = ctime_r(&current_time, h_buf);
if (s_time_b_min == NULL) {
    return -1;
}

/* Get rid of newlines that you probably don't want */
h_buf[CTIME_MAX_LEN - 2] = '\0';
min_buf[CTIME_MAX_LEN - 2] = '\0';

/* 
 * CTIME_MAX_LEN * 2 is enough space for both times, the
 * additional 2 bytes is enough for the colon and NUL-byte.
 */
char o_buf[CTIME_MAX_LEN * 2 + 2];
snprintf(o_buf, sizeof (o_buf), "%s:%s", h_buf, min_buf);
text_layer_set_text(s_time_layer, o_buf);

当然,除非您对 的调用使用不同的值,ctime_r(3)否则双方将是相同的。在您修复链接器错误之前,您仍然无法测试此代码。

于 2015-01-01T00:08:58.497 回答