2014-10-29 59 views
2

我可能錯過了一些明顯的東西,但是我的C很生疏,我沒有任何運氣能夠理解這一點。我有一個循環,我想遍歷來自libdvdnav的uint64_t值的數組,然後格式化值並將它們插入到字符串中。通過指向數組的指針取消引用數組值

爲libdvdnav頭定義函數我打電話正是如此:

uint32_t dvdnav_describe_title_chapters(dvdnav_t *self, int32_t title, uint64_t **times, uint64_t *duration); 

這裏是我如何定義使用的變量,並在呼叫(dvdnavargs[0]了定義並初始化其他地方):

uint64_t *times; 
uint64_t duration; 
uint32_t times_array_len; 

times_array_len = dvdnav_describe_title_chapters(dvdnav, atoi(args[0]), &times, &duration); 

下面的代碼似乎工作,並編譯&運行的w/o錯誤,但當然只是陣列中的第一個值被插入:

int i = 0; 
uint64_t a_time = times[0]; 

while(i < times_array_len){ 

    char time_json[100]; 
    sprintf(time_json, "{\"chapter\":\"%d\",\"time\":\"%u\"},", i, a_time); 
    strcat(payload, time_json); 
    i++; 
} 

如果我修改此選擇它仍然編譯乾淨的陣列中的每個值,但在運行時拋出一個段錯誤:

int i = 0; 

while(i < times_array_len){ 

    char time_json[100]; 
    sprintf(time_json, "{\"chapter\":\"%d\",\"time\":\"%u\"},", i, times[i]); 
    strcat(payload, time_json); 
    i++; 
} 

我想也許有什麼東西在,這是數組元素之一一個問題(一個太大的值,意外的,NULL等),但即使我用一個已知合理的元素(比如0)替換變量i它仍然存在段錯誤。我確信在這裏會有無數其他的改進(比如更安全的分配,溢出保護等等),但我努力破譯的部分是將這些值從數組中取出並存入我的格式化字符串中。

+0

「在運行時會引發段錯誤」 - 在哪裏?啓動一個調試器。 – 2014-10-29 15:19:59

+2

'strcat()'調用看起來很可怕... – unwind 2014-10-29 15:20:38

+1

有2個可能的問題。首先,你在計算'times_array_len'時會出現一些錯誤,'times'就會小些。其次,您的負載太短,無法保存所有這些數據。 – 2014-10-29 15:21:15

回答

1

​​如何定義?如果它太短而不能包含字符串,那麼你將會崩潰。 您可以通過多種方式解決這個:

1)既然你現在JSON條目的數量將是times_array_len您可以使用malloc堆與大小分配串100 * times_array_len - 再次,你絕不會超過(,不知道是否使用固定長度的json緩衝區是否智能),那麼strcat應該是安全的。您甚至可以直接將sprintf呼叫直接撥入​​緩衝區,因爲您現在將通過跟蹤sprintf的返回值來確定偏移量。是這樣的:

#include <stdlib.h> 
#include <stdio.h> 

int main(int argc, char** argv) 
{ 
    __int64 pTimes[] = { 1, 2, 3 ,4}; 
    size_t nTimeCount = sizeof(pTimes)/sizeof(pTimes[0]); 
    size_t nPayloadOffset = 0; 
    char* pPayload = (char*)malloc(100 * nTimeCount); 
    if (pPayload) 
    { 
     for (size_t nTimeIndex = 0; nTimeIndex < nTimeCount; ++nTimeIndex) 
     { 
      nPayloadOffset += sprintf(&pPayload[nPayloadOffset], "{\"chapter\":\"%d\",\"time\":\"%u\"},", nTimeIndex, pTimes[nTimeIndex]); 
     } 
     printf("%s\n", pPayload); 
     free(pPayload); 
    } 
    return EXIT_SUCCESS; 
} 

2)爲了避免運行在上一個單一的入口100字符長度你可能是明智的,並與初始大小分配pPlayoad,然後計算每個條目的大小和重新分配pPayload如果它變得太短

3)使用C++和std::stringstream如果C++是一個選項:

#include <sstream> 
#include <iostream> 

int main(int argc, char** argv) 
{ 
    __int64 pTimes[] = { 1, 2, 3 ,4}; 
    size_t nTimeCount = sizeof(pTimes)/sizeof(pTimes[0]); 
    size_t nPayloadOffset = 0; 
    std::stringstream JsonStream; 
    for (size_t nTimeIndex = 0; nTimeIndex < nTimeCount; ++nTimeIndex) 
    { 
     JsonStream << "{\"chapter\":\"" << nTimeIndex << "\",\"time\":\"" << pTimes[nTimeIndex] << "\"},"; 
    } 
    std::cout << JsonStream.str() << std::endl; 
    return EXIT_SUCCESS; 
}