2013-05-06 111 views
-1

這個問題是答案。與格式化程序無關,而是涉及到複製到新緩衝區時的白癡。在C++中將0複製爲000?


我希望這是一個一行的答案。我有一個snprintf()語句是類似如下:

snprintf(buffer, sizeof(buffer), "%03d", 0U); 

我期待buffer持有000但由於某種原因它僅持有00。假設緩衝區足夠大,足以容納我想要的東西。我是愚蠢的嗎?

編輯:

請參閱下面的完整代碼與上下文。我之前試圖簡化它,因爲我不認爲所有這些背景都是必要的。這一點仍然存在,使用%04u在第一個CSV行中給我000%03u只給我00

uint16_t CSVGenerator::write_csv_data(TestRecord* record) 
{ 
    // Define the templates. 
    const char *row_template = "%04u,%6.3E,%6.3E,%6.3E,%6.3E,%6.3E\n"; 
    char csv_row_buffer[CSV_ROW_BUFFER_SIZE]; 

    // Add the data. 
    uint16_t row_count = 0U; 
    for (uint16_t reading = 0U; reading < MEASURE_READING_COUNT; ++reading) 
    { 
     // Parse the row. 
     snprintf(csv_row_buffer, sizeof(csv_row_buffer), row_template, 
       // Test ID 
       MEASURE_PERIOD_SECS * reading, 
       // Impedances Z1-Z5. 
       record->measurements[reading][0U], 
       record->measurements[reading][1U], 
       record->measurements[reading][2U], 
       record->measurements[reading][3U], 
       record->measurements[reading][4U]); 

     // Add it to the main buffer, excluding the terminator. 
     strncpy((m_csv_data_buffer + (reading * CSV_ROW_BUFFER_SIZE) - 1U), 
       csv_row_buffer, (sizeof(csv_row_buffer) - 1U)); 

     // Increment the row count. 
     ++row_count; 
    } // for : each reading. 

    return row_count; 
} 
+2

緩衝區有多大,它是什麼,它是如何定義的? – Mat 2013-05-06 10:43:46

+0

@Mat:說'char buffer [8U]'。 – 2013-05-06 10:45:21

+5

緩衝區被定義爲'char * buffer = malloc(blah)';在任何情況下?另外如果你的號碼沒有簽名,你應該使用'%03u'(不是d) – Dave 2013-05-06 10:45:41

回答

2

方式更重要的你如何檢查,這只是「000」中含有?如果您正在從(m_csv_data_buffer + (reading * CSV_ROW_BUFFER_SIZE))中讀取它,那麼您實際上將丟失第一個字節,因爲您已將其複製到代碼中的(m_csv_data_buffer + (reading * CSV_ROW_BUFFER_SIZE) - 1U)

+0

你們是對的。 'csv_row_buffer'有我想要的 - 'm_csv_data_buffer'有一個字節丟失。 – 2013-05-06 11:18:06

0

你是在一臺16bit的機器上嗎?也許你宣佈緩衝區爲char *,所以sizeof(buffer)評估爲2,snprintf只複製實際輸出「000」的前兩個字節(加終止符0x00)

我懷疑問題存在於回讀你的緩衝區的內容,而不是實際的內容,也許是:

Some dummy code to keep buffer in scope while I check it.. 

比你貼什麼

+4

如果'sizeof(char *)'爲2,則只寫入一個「0」,「snprintf」的計數包含0終止符。 – 2013-05-06 10:51:54

+0

你是對的,只有一個'0' – 2013-05-06 10:54:35

1

strncpy隱式處理空終止符,所以我猜你在從目標緩衝區地址中減去1的位置,實際上是將新行的第一個字符放入前一行的最後一個字節。

您似乎正在使用固定緩衝區大小和可變字符串長度的組合。這是你所看到的可能原因。