2015-07-20 15 views
-1

我寫了一個簡單的函數,它將帶有擴展名的文件名並返回擴展名和文件名減去擴展名。 它工作正常,但當我測試它時,我發現有些地方我的文件名被重置。並不總是,但有時。在操作上有數據重置的字符數組

#include <stdio.h> 
#include <string.h> 
#include <string> 

#define EXTENSION_STR_MAX   (16) 
#define METADATA_STR_MAX      (129) 
struct meta_data_t 
{ 
    char filename[METADATA_STR_MAX]; 
    char fileextension[EXTENSION_STR_MAX]; 
}; 

void GetFileExtMetadata(const char* fileName, char* fileExt, char* updateFileName) 
{ 
    // NULL Checks 
    if((NULL == fileName) || (NULL == fileExt) || (NULL == updateFileName)) 
    { 
     printf("NULL :-/ \n"); 
     return; 
    } 

    // Find the position of the last dot 
    char * pch = NULL; 
    pch = strrchr(fileName, '.'); 
    if((NULL == pch) || (fileName == pch)) 
    { 
     printf("Nope\n"); 
    } 
    else 
    { 
     // Copy ot the extension 
     char fileextension[15]; 
     strncpy(fileextension, (pch+1),15); 
     strcpy(fileExt, "."); 
     strcat(fileExt, fileextension); 

     // Remove the extension formthe filename 
     *pch = '\0'; 
     strncpy(updateFileName, fileName, (METADATA_STR_MAX-1)); 
     updateFileName[METADATA_STR_MAX-1] = 0; 
    } 
} 

int main() 
{ 
    meta_data_t test1 = {}; 
    meta_data_t test2 = {}; 
    meta_data_t test3 = {}; 
    char tempfilename[METADATA_STR_MAX]; 

    strncpy(test1.filename, "Poker Face.mp3", (METADATA_STR_MAX-1)); 
    test1.filename[METADATA_STR_MAX-1] = 0; 

    strncpy(test2.filename, "Love.is.in.the.air.wma is the ext", (METADATA_STR_MAX-1)); 
    test2.filename[METADATA_STR_MAX-1] = 0; 

    strncpy(test3.filename, "Crazy.ThisisatesttoCheckLength", (METADATA_STR_MAX-1)); 
    test3.filename[METADATA_STR_MAX-1] = 0; 

    printf("%s \n",test1.filename); 
    printf("%s \n",test2.filename); 
    printf("%s \n\n",test3.filename); 

    strncpy(tempfilename, test1.filename, (METADATA_STR_MAX-1)); 
    tempfilename[METADATA_STR_MAX-1] = 0; 
    GetFileExtMetadata(tempfilename, test1.fileextension, test1.filename); 

    printf(" BEFORE %s \n",test2.filename); 
    strncpy(tempfilename, test2.filename, (METADATA_STR_MAX-1)); 
    tempfilename[METADATA_STR_MAX-1] = 0; 
    GetFileExtMetadata(tempfilename, test2.fileextension, test2.filename); 
    printf(" AFTER1 %s \n",test2.filename); 

    strncpy(tempfilename, test3.filename, (METADATA_STR_MAX-1)); 
    tempfilename[METADATA_STR_MAX-1] = 0; 
    GetFileExtMetadata(tempfilename, test3.fileextension, test3.filename); 
    printf(" AFTER2 %s \n",test2.filename); // NOT GOOD 

    printf("%s - %s\n",test1.filename, test1.fileextension); 
    printf("%s - %s\n",test2.filename, test2.fileextension); 
    printf("%s - %s\n",test3.filename, test3.fileextension); 

    printf("%s \n",test1.filename); 
    printf("%s \n",test2.filename); 
    printf("%s \n",test3.filename); 

    return 0; 
} 

結果: 撲克Face.mp3 Love.is.in.the.air.wma是內線 Crazy.ThisisatesttoCheckLength

BEFORE Love.is.in.the.air.wma is the ext 
AFTER1 Love.is.in.the.air 
AFTER2 
Poker Face - .mp3 
- .wma is the ext 
Crazy - .ThisisatesttoCh 
Poker Face 

Crazy 

我看到THT的文件名Love.is.在我第三次運行該功能後,空氣變得空虛。我無法理解爲什麼會發生這種情況。 任何線索? 謝謝

回答

1

是不是緩衝區來保持文件擴展名太小?它看起來像是16個字符(EXTENSION_STR_MAX),但是「Love.is.in.the.air.wma」不止於此。所以你得到了經典的緩衝區溢出。

+0

這絕對是這裏的問題。 –

+0

Love.is.in.the.air.wma存儲在test2.filename中,其大小爲129 METADATA_STR_MAX。另外,它已經正確地打印了Love.is.air.air.wma兩次,第三次是空的。 – BlueBottle

+0

是的,你是對的。導致緩衝區溢出的字符串實際上是。這是最好的檢查長度。只要做一步一步的調試並觀察緩衝區內容(fileExt)。 – Nikolay

0

嘗試調試代碼一次,你會發現你的答案。 在複製另一個字符串之前,重置「tempfilename」的內容。 安全編碼。