2009-09-29 55 views
3

我正在從一組數據庫字段構建一個固定長度的記錄的C++應用程序。我正在編寫一個函數,它將接受輸出記錄爲char*,要寫入的字符串以及該字段的總長度。該函數的目的是將字符串複製到char指針的當前位置,然後用空格填充剩餘的長度。這是我正在做的一個簡單的例子。我可以增加傳遞給函數的char *嗎?

void writeOut(char* output, string data, const int length) { 
    if ((int) data.size() > length) { 
     //Just truncate it 
     data = data.substr(0, length); 
    } 
    int index = 0; 
    while (index < (int) data.size()) { 
     *output++ = data[index++]; 
    } 
    while (index++ < length) { 
     *output++ = ' '; 
    } 
} 

int test() { 
    char output[100]; 
    writeOut(output, "test1", 10); 
    writeOut(output, "test2", 10); 
    writeOut(output, "test3test4test5", 10); 
    cout << output; 
} 

我希望看到類似這樣的內容。

test1  test2  test3test4     

相反,我得到的是...

test3test4 

因此它遞增char*函數內,但僅限於功能。當功能結束時,char*就在它剛剛開始的地方。是否有可能傳遞一個指針,使指針在調用函數中更新?

如果你不能說,我很新的C++。任何建議將不勝感激。

回答

8

既然你不通過引用傳遞你的論點,編譯器創建的指針的副本,並相應地修改函數中的副本。

將您的功能簽名更改爲以下內容。

void writeOut(char*& output, string data, const int length) 

您可能還需要考慮通過stringconst string&,如果你不打算修改它。

+1

只要確保傳入一個char *,而不是char [],因爲你不能增加數組的值。 – 2009-09-29 17:48:51

+0

另外:這會破壞他的cout <<輸出行,除非他製作了指針的副本。你必須做一個char *指向輸出,然後使用它。 – 2009-09-29 18:39:37

+0

謝謝。出於某種原因,我認爲你不能傳遞一個指針的引用。 – 2009-09-29 19:46:41

6

你可以做到你是什麼通過保持一個新的字符指針後,但不能增加「輸出」變量,然後再次使用它 unincremented(在COUT線)。

例如,你可以這樣做:

char* writeOut(char* output, string data, const int length) { 
    if ((int) data.size() > length) { 
     //Just truncate it 
     data = data.substr(0, length); 
    } 
    int index = 0; 
    while (index < (int) data.size()) { 
     *output++ = data[index++]; 
    } 
    while (index++ < length) { 
     *output++ = ' '; 
    } 
    return output; // return the new position here! 
} 

int test() { 
    char output[100]; 
    char *outputLocation = output; 
    outputLocation = writeOut(outputLocation, "test1", 10); 
    outputLocation = writeOut(outputLocation, "test2", 10); 
    outputLocation = writeOut(outputLocation, "test3test4test5", 10); 
    cout << output; 
} 
+0

+1雖然其他的答案回答了這個問題,我想你提供一個更好的方法:) – AraK 2009-09-29 17:28:59

+0

感謝。我更喜歡這種方法,因爲它使得指針可選,而不是必需的,以便使用該方法。 – 2009-09-29 17:52:14

+0

+1,謝謝。我想過這種方法,但無法弄清楚它的語法。這是一個好主意。 – 2009-09-29 19:48:19

8

你想通過一個char **函數。

void writeOut(char** output, string data, const int length) { 
    if ((int) data.size() > length) { 
     //Just truncate it 
     data = data.substr(0, length); 
    } 
    int index = 0; 
    while (index < (int) data.size()) { 
     *(*output)++ = data[index++]; 
    } 
    while (index++ < length) { 
     *(*output)++ = ' '; 
    } 
} 

int test() { 
    char output[100]; 
    char *pos = output; 
    writeOut(&pos, "test1", 10); 
    writeOut(&pos, "test2", 10); 
    writeOut(&pos, "test3test4test5", 10); 
    cout << output; 
} 

(手頭上沒有編譯器,但這個應該工作)

+1

+1,因爲這似乎是一個更傳統的方式來完成這 – Tony 2009-09-29 17:30:33

+1

我認爲pos必須是char ** pos =&output; – 2009-09-29 17:31:00

+0

@Douglas:如果不是這樣,它的地址傳遞:WriteOut的(POS,「測試1」 ... – 2009-09-29 17:37:56

0

你需要按引用傳遞。

0

要理解的重要一點是函數的參數是按值傳遞的,即它們被複制。

函數的第一個參數是一個指針,換句話說就是一個指向內存的數字。當您調用該功能時,該號碼將從test()複製到printOut(),這允許printOut()訪問test()分配的內存。

正如其他人所建議的,您可以返回指針的新值,或將其作爲參考傳入。否則,您可以使用指針指針,它將允許您更新printOut()中的指針。

2

發生了什麼事是每個每次調用WriteOut的你傳遞同一個位置(即開始),以通話時間。

你需要的是你,你叫WriteOut的待着另一個變量。有幾種方法可以做到這一點:

第一,「最簡單」的選項是讓你在「參考指針」傳遞參數:

void writeOut (char *& output, ...) { 
    // ... 
} 

int test() { 
    char output[100]; 
    char * p = output; 
    writeOut (p, "test1", 10); 
    writeOut (p, "test2", 10); 
    // ... 
} 

這工作,因爲參數output現在是一個別名爲主體中的指針p。因此,對writeOut中的參數所做的更改也會發生在p

下一個最簡單的方法是每次都返回新的位置:

char * writeOut (char * output, ...) { 
    // ... 


    return output; 
} 

int test() { 
    char output[100]; 
    char * p = output; 
    p = writeOut (p, "test1", 10); 
    p = writeOut (p, "test2", 10); 
    // ... 
} 

這裏,參數被修改在函數內部,我們在主每次更新p

最後,你可以一個指針就WriteOut的參數以指針:

void writeOut (char ** output, ...) { 
    // ... 

    while (index < (int) data.size()) { 
    **output = data[index++]; 
    (*output)++; 
    } 

    // ... 
} 

int test() { 
    char output[100]; 
    char * p = output; 
    writeOut (&p, "test1", 10); 
    writeOut (&p, "test2", 10); 
    // ... 
} 

這裏發生的事情是,我們的參數不再指向「產出」,而是指向「P」的地址。在我考慮這個之前,我幾乎肯定會選擇參考選項。

+0

+1,用於解釋不同的選項之間的差異的感謝。我最初提交的感謝 – 2009-09-29 19:49:38

0

爲什麼不直接使用snprintf?

int writeOut(char *output, char *data, int length) 
{ 
    return snprintf(output, length + 1, "%-*s", length, data); 
} 

void test() 
{ 
    char output[100]; 
    char *outputLocation = output; 
    outputLocation += writeOut(outputLocation, "test1", 10); 
    outputLocation += writeOut(outputLocation, "test2", 10); 
    outputLocation += writeOut(outputLocation, "test3test4test5", 10); 
    printf("%s\n", output); 
} 

我認爲這很容易。我猜,你呢。

+0

大大改善,一個聰明的同事,感謝史蒂夫! – 2009-09-29 17:56:55

+0

它沒有發生對我來說,我可以像這樣使用printf。一個問題,但。我所有的輸入數據都是字符串格式。與只是將字符從字符串移動到字符數組相比,printf不會引入一些開銷嗎? – 2009-09-29 19:54:19

+0

不幸的是我不知道C++字符串的細節。我猜你會有很多基於STL字符串的開銷,這些字符串可以通過使用C風格的字符數組得到改進。 – 2009-09-29 21:15:56

相關問題