2016-11-25 84 views
0

您好我試圖建立類似用printf的參數的函數返回一個指針爲char

#include <stdio.h> 

struct _data; 
typedef struct _data data; 
typedef struct _data { 
    double x; 
    double y; 
} data; 

const char* data_tostring(data* a) { 
    static char buffer[255]; 
    sprintf(buffer, "%f %f", a->x, a->y); 
    return buffer; 
} 

int main(){ 
    data a; 
    data b; 
    a.x = 0; 
    a.y = 0; 
    b.x = 1; 
    b.y = 1; 
    printf("%s %s \n", data_tostring(&a), data_tostring(&b)); 
    return 0; 
} 

我預計產量爲0 0 1 1碼,但實際上我得到0 0 0 0我做出的一個static關鍵字錯誤,返回值data_tostring()

感謝您的幫助。

回答

5

由於bufferstatic,所以兩個對data_tostring(...)的調用都寫入同一個緩衝區。此外,函數參數的評估順序未詳細說明,因此不保證data_tostring(&a)data_tostring(&b)之前得到評估。

固定這一點的一種可能的方式是通過使buffer作爲參數傳遞給data_tostring

void data_tostring(char* buffer, data* a) { 
    sprintf(buffer, "%f %f", a->x, a->y); 
} 

然後在main使用多個緩衝器:

int main() 
{ 
    data a; 
    data b; 
    char a_buf[255]; 
    char b_buf[255]; 

    a.x = 0; 
    a.y = 0; 
    b.x = 1; 
    b.y = 1; 

    // Fill buffers 
    data_tostring(a_buf, &a); 
    data_tostring(b_buf, &b); 

    printf("%s %s \n", a_buf, b_buf); 
    return 0; 
} 

wandbox example


如果你真的想要你本身在static buffer,您可以撥打printf兩次:

int main() 
{ 
    data a; 
    data b; 
    a.x = 0; 
    a.y = 0; 
    b.x = 1; 
    b.y = 1; 
    printf("%s", data_tostring(&a)); 
    printf(" %s \n", data_tostring(&b)); 
    return 0; 
} 

wandbox example

+0

不幸的是,你的解決方案正是我想避免:) – Fabio

+0

@Fabio:爲什麼?如果你想使用相同的緩衝區,你需要對'printf'進行兩次單獨的調用。 –

+0

@Fabio:使用「靜態緩衝區」替代解決方案編輯我的答案。 –

1
  • 的問題是因爲在C語言中,在函數的參數從right to left評估。
  • 因此,首先對data_tostring(&b)進行評估,指針指向緩衝區char數組。
  • 接下來,對data_tostring(&a)進行評估,並且此時,存在的char值已被sprintf(buffer, "%f %f", a->x, a->y);覆蓋。
  • 因此,在兩次參數評估之後,兩個函數評估指向具有值struct a的緩衝區char數組。這就是原因,你得到0 0 0 0

替代解決方案:

使用兩分的printf()語句和seperately打印字符串或使用兩個字符緩衝區的每個結構的(不推薦) 。

參考:Compilers and argument order of evaluation in C++

希望這有助於。