2016-11-23 53 views
2

我的意圖是將source字符串複製到dest字符串。如果我編譯以下程序:Memset和字符

#include <stdio.h> 

int main(void) { 
    char dest[6]; 
    char source[6]; 

    strcpy(dest,source); 

    while (*dest) { printf("%c",*dest++); } 
    while (*source) {printf("%c",*source++); } 

    return 0; 
} 

我得到一個運行時錯誤。我懷疑這是因爲strcpy從源到目的地複製,直到遇到\0。但是,它沒有遇到空字符,並且一直保持從緩衝區複製直到發生運行時錯誤。爲了解決這個問題,我修改了代碼如下:

#include <stdio.h> 

int main(void) { 
    char dest[6]; 
    char source[6]; 


    memset(dest, '\0', 6*sizeof(dest)); //trying to set dest to '/0' 
    strcpy(dest,source); 

    while (*dest) { printf("%c",*dest++); } 
    while (*source) {printf("%c",*source++); } 

    return 0; 
} 

我得到以下錯誤:

prog.c:11:38: error: lvalue required as increment operand

while (*dest) { printf("%c",*dest++); } 
           ^

prog.c:11:38: error: lvalue required as increment operand

while (*dest) { printf("%c",*source++); } 
            ^

爲什麼會出現這種情況?

+3

第一個程序[不編譯](http://ideone.com/2Zy1hx)出於同樣的原因,第二個程序沒有。你確定這是你使用的來源嗎? – templatetypedef

+1

另外,您不能將++應用於數組。 :-) – templatetypedef

+3

相反,如果dest是一個數組,dest ++不是合法的C代碼。 – templatetypedef

回答

4

對於初學者它是應如果你要它在另一個字符數組複製被零終止源陣列使用標準的C函數strcpy。因此,而不是這種說法

memset(dest, '\0', 6*sizeof(dest)); 

的你至少應該寫

memset(source, '\0', 6*sizeof(source)); 
     ^^^^^^    ^^^^^^^ 

然而,即使這種說法是錯誤的,因爲它會覆蓋分配給數組的內存。 sizeof(source)已經等於6個字節,因爲它是從數組宣言

char source[6]; 

因此隨後必須編寫

事實上有足夠的寫要麼喜歡

char source[6] = { '\0' }; 

或者像

char source[6] = ""; 

或類似

char source[6]; 
source[0] = '\0'; 

數組是不可修改的左值。因此,你可以不寫,例如下面的方式

while (*dest) { printf("%c",*dest++); } 

而是這句話的,你可以寫

for (char *p = dest; *p; ++p) { printf("%c", *p); } 

要考慮到什麼也不會輸出,因爲數組包含一個空字符串。您可以用一些非空字符串文字初始化源數組。

+0

這一行:'memset(source,'\ 0',6 * sizeof(source));'不正確。 'sizeof(source)'是6,6 * 6是36,所以這將清除36個字節,在第一個6之後超出數組邊界的末尾。結果是未定義的行爲,並可能導致seg故障事件。建議刪除'6 *' – user3629249

+0

@ user3629249您在發表評論之前是否閱讀過整篇文章?:) –

+0

是的,我確實閱讀了整篇文章和答案。您的答案是傳播OP發佈的代碼中的一個問題。 – user3629249

-1

strcpy是不安全的功能,更喜歡使用strncpy

錯誤是由於您嘗試增加數組(這是一個右值)(即常數,您不能將它放在符號=的左側)。

的常用方法迭代數組是使用像這樣的指針:

char *p = dest; 
while (*p) { printf("%c",*p++); } 
+0

謹慎解釋downvoting? –

+0

我沒有downvote,但'strncpy'不只是'strcpy'的更安全版本。由於歷史原因,它實際上做了一些非常令人驚訝的事情,因此它在許多情況下可能不是你想要的。 –

+0

據我所知,strncpy的缺點是,如果達到最大大小,它不會添加'\ 0'字節,但這不是問題,因爲他使用的是未初始化的數據,而且對我來說似乎只是嘗試和操縱指針和內存。 –

1

下面的代碼乾淨地編譯,並執行所需的操作。

發佈的代碼與此之間的差異被評論。

#include <stdio.h> // printf() 
#include <string.h> // strcpy() 

int main(void) 
{ 
    char dest[6]; // declared, containing garbage 
    char source[6] = "12345"; // declared, containing the string "12345\0" 

    strcpy(dest,source); 
    // now both arrays contain the string "12345\0" 

    // best to use a 'for()' statement for indexing through an array 
    for(size_t i=0; dest[i]; i++) { printf("%c", dest[i]); } 
    printf("\n"); // output the buffered data to the terminal 
    for(size_t i=0; source[i]; i++) { printf("%c", source[i]);} 
    printf("\n"); // output the buffered data to the terminal 

    // note, the following lines contain a precedence problem in 
    // the increment expressions and 
    // the address of an array declaration cannot be incremented 
    //while (*dest) { printf("%c",*dest++); } 
    //while (*source) {printf("%c",*source++); } 

    //return 0;// with modern C compilers, 
      // this line is not necessary in a 'main()' function 
      // when returning 0 
} // end function: main