2016-07-29 100 views
-1

我對代碼的工作來獲得USB設備的詳細信息到一個String,並有下面的代碼,如何避免sprintf的加盟變量

struct usb_bus *bus; 
    struct usb_device *dev; 

    usb_init(); 
    usb_find_busses(); 
    usb_find_devices(); 

    for (bus = usb_busses; bus; bus = bus->next) 
     for (dev = bus->devices; dev; dev = dev->next) 
    { 

      // working outputs 
      printf("Trying device %s/%s\n", bus->dirname, dev->filename); 
      printf("Trying device2 %0x\n", dev->descriptor.idVendor); 
      printf("Trying device3 %0x\n", dev->descriptor.idProduct); 

     char deviceDetailsStr[150]; 
     sprintf(deviceDetailsStr, "%s_%s_%0x_%0x", bus->dirname, 
      dev->filename,dev->descriptor.idVendor,dev->descriptor.idProduct); 

     ... have other code here that works on "deviceDetailsStr" 
    } 

在讀thatt「的sprintf」有性能問題時,因爲它支持很多的變換。

能否請你所說的其實是使用「的sprintf」更好的選擇,讓所有4個變量的數據被讀取到變量「deviceDetailsS​​tr」

的最終目標是「deviceDetailsS​​tr」字符數組需要有所有4個entires爲單個字符串。

由於

+4

性能問題真的是你想要替換'sprintf'的原因嗎?你確定這是你的瓶頸嗎? – Evert

+0

'snprintf'可能比'sprintf'好。 – Evert

+0

您可以多次使用strcat()。 – FredK

回答

0

"0"沒有價值。如果你想要最好的表現,我會說你需要寫一些東西定製。以下是您的具體要求的示例。

uint32_t printHex(char * buffer, uint32_t value) { 
    uint32_t sz = value <= 0xF ? 1 : 
        value <= 0xFF ? 2 : 
        value <= 0xFFF ? 3 : 
        value <= 0xFFFF ? 4 : 
        value <= 0xFFFFF ? 5 : 
        value <= 0xFFFFFF ? 6 : 
        value <= 0xFFFFFFF ? 7 : 8; 
    for(uint32_t i=sz-1; i; i--) { 
     buffer[ i ] = ((value & 0xF) <= 9 ? '0' : 'a'-10) + (value & 0xF); 
     value=value>>4; 
    } 
    return sz; 
} 

char buffer[150]; 
unsigned bi=0; 
for(char * ptr = bus->dirname ; *ptr; ptr++) buffer[bi++] = *ptr; 
buffer[bi++] = '_'; 
for(char * ptr = bus->filename; *ptr; ptr++) buffer[bi++] = *ptr; 
buffer[bi++] = '_'; 
bi += printHex(buffer + bi, dev->descriptor.idVendor); 
buffer[bi++] = '_'; 
bi += printHex(buffer + bi, dev->descriptor.idProduct); 
buffer[bi] = '\0'; 

注意:沒有大小檢查(就像sprintf)。如果你想要獲得最佳表現,那麼這是一種折衷。

+0

謝謝你的例子。這正是我期待的。只是一個小小的改變。 printHex的輸出似乎與printHex函數的輸出不匹配。第一個字符似乎打印錯誤。 ** 1)首次運行:** **從sprintf:** | 004_004_45e_750 | **從新的printHex代碼:** | 004_004_'5e_q50 | 2)第二次運行: 從sprintf:| 004_004_45e_750 | 來自新增printHex碼:|004_004_'5e_ 50| 也爲第一個字符隨機打印特殊字符而不是常規ascii。你能幫我解決這個問題嗎?將此標記爲選定的答案。 – Mark

+0

嗨@Mark,我試圖重現你看到的idVendor = 1118(0x45E)和idProduct = 1872(0x750)的問題。但是,由於上面的代碼每次都工作,所以我無法使用隨機字符。我懷疑也許別的東西正在造成腐敗。 要驗證,你可以用任何uint32_t調用hexPrint(),它應該匹配printf(「%x」)。 – flu

0

步驟1:確定最大緩衝器大小需求。

假設bus->dirname, dev->filename是數組。

#define Mark_SZ ((sizeof bus->dirname - 1) + 1 + \ 
    (sizeof dev->filename - 1) + 1 + \ 
    ((sizeof dev->descriptor.idVendor * CHAR_BIT + 3) /4) + 1 + \ 
    ((sizeof dev->descriptor.idProduct * CHAR_BIT + 3) /4) + 1) 

#defined Extra (depends on: "other code here that works on "deviceDetailsStr"") 
char deviceDetailsStr[Mark_SZ + Extra]; 

第2步:複製在每個部分

// Some untested code to give you an idea. 

char *p = deviceDetailsStr; 
size_t n = strlen(bus->dirname); 
memcpy(p, bus->dirname, n); 
p += n; 

*p++ = '_'; 

n = strlen(dev->filename); 
memcpy(p, dev->filename, n); 
p += n; 

*p++ = '_'; 

p += sprintf(p, "%x", dev->descriptor.idVendor); 

*p++ = '_'; 

sprintf(p, "%x", dev->descriptor.idProduct); 

我編寫sprintf(p, "%x", dev->descriptor.idVendor)sprintf(p, "%x", dev->descriptor.idProduct)自己作爲希望即使是溫和的編譯器會認識到這一點,並具有同等itoa()像函數調用替換。否則,只需將代碼unsigned編碼爲字符串即可。

我看到"%0x"