0

私は Java for Android のバックグラウンドが強いプログラマーです。私は C の初心者で、Pebble 用のコンパニオン アプリを作成するためだけに C を学んでいます。編集:私は 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 シンボルの定義が見つかりません。

あなたのコードには、宣言も定義もされていない 2 つのシンボルがあります: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 の文字列は、1 バイトで終了する文字の連続したバイト ストリームですNUL(「NULL バイト」が表示されますが、これはあまり正確ではありません)。この行から、Java と大きく異なる動的メモリ割り当てや C の文字列に慣れていないことは明らかです。

入力元の文字列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)再入可能な関数ではないため、2 つの呼び出しで互いに上書きされます。には第 2 レベルの粒度があるためctime(3)、この例ではおそらく問題にはなりません。両方の呼び出しが同じ秒で終了し、両方とも同じ入力シード ( current_time) を使用します。これを正しく行うには、(たとえば)次のものが必要です。

time_t current_time;
char *s_time_b_h;

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

は再入可能ではなく、2 つの値が必要なため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 に答える