2016-02-06 68 views
-2

我有一個指針:轉換一個字符指針爲大寫用C

char * name; 

它包含字符串"test:case"

我打電話來與它的另一個功能,並試圖將其存儲在一個結構。但是,我想首先利用整個字符串,但似乎並不奏效。

void func(char * name) { 
    int i; 
    List * l; 

    l = malloc(sizeof(List)); 

    for(i=0; i< strlen(name); i++) { 
     name[i] = toupper(name[i]); 
    } 

    l->name = name; 
    //CALL A FUNCTION TO LATER FREE ALLOCATED MEMORY 
} 

List is a struct that has a member (char *) named name. 然而,這賽格故障。我不能在我的情況下使用非指針。當我不得不使用指針而不是字符數組,我想在字符指針的每一個值使用TOUPPER,但是這似乎並沒有工作。

+0

你是如何設置'name'的?這聽起來像你指向一個字符串文字。這些是不可修改的,你需要複製它。 – Barmar

+0

即使我不嘗試大寫(說刪除for循環的東西),並打印出名稱的結構值,它打印出正確的值,不知道你在這裏的意思。 – TEDG

+0

我不明白這個問題。段錯誤來自嘗試將其大寫。如果你不使用大寫字母,那沒有問題。 – Barmar

回答

1

你得到一個段錯誤,因爲原始的字符串大概是文字,這是不可修改的。你需要先製作一份。

void func(char * name) { 
    List * l; 

    l = malloc(sizeof(List)); 

    name = strdup(name); // make a copy of name 
    for (char *p = name; *p; p++) { 
     *p = toupper(*p); 
    } 

    l->name = name; 
} 

注意,當你以後免費l,您首先需要釋放l->name

+0

int p = name?錯誤的類型? – TEDG

+0

對不起,我在打字時從我切換到p,忘記更改類型。 – Barmar

+0

我們如何知道src字符串是一個文字? – mauro

0

既然你只設置指針l->namename,這將崩潰的那一刻原來name不再存在(也許是唯一的堆棧?)和l->name訪問。您需要malloc()空間strlen(name)+1大小,複製name那裏設置l->name到該地址。

0

您已經分配的列表,而不是名稱字符串本身。 你需要做的:

l=malloc(sizeof(List)); 
l->name=(char*)malloc(strlen(name)+1); // You need to cater for the the final null char. 

有你的代碼的一些其他問題,這裏是正確的(沒有編譯,大概接近好嗎):

void func(char *name) { 
    List * l; 
    l = (List*)malloc(sizeof(List)); 
    l->name = (char*)malloc(strlen(name)+1); 
    for(char *r=name, char *w=l->name; *r; ++r,++w) { 
    *w = toupper(*r); 
    } 
    *++w='\0'; 
} 

而在每次迭代,這段代碼都不會一次又一次地評估strlen,這會非常糟糕。

+0

他沒有分配名稱本身,因爲他想指向原始字符串。 – Barmar

0

裏有兩個代碼錯誤。

char * name 

可變名稱包含一個指向一個字符串(即,的陣列)。 當你這樣寫:

name[i] = toupper(name[i]); 

你改變原有字符的字符串 itens,如果它不是一個指向常量字符串。如果是這種情況,那就是分段錯誤。

對方誤以爲是在這裏:

l->name = name; 

你只是分配給變量結構中這是通過變量傳遞給函數的指針。你應該做一個副本,就像這樣:

strcpy(l->name, name); 

此功能將所有從第二個參數的第一內容。

但這不是一個好的解決方案。如果名稱包含一個指向常量字符串的指針,它仍然是段錯誤。

我將重寫代碼:

void func(char * name) { 
    int i; 
    List * l; 

    l = malloc(sizeof(List)); 

    char *buffer[strlen(name)]; //buffer of the contents pointed by *name* to upper case, initialized as empty string 

    for(i=0; i< strlen(name); i++) { 
     buffer[i] = toupper(name[i]); 
    } 
    buffer[i] = '\0'; //closing the string in i = strlen(name) 

    strcpy(l->name, buffer); 
    //CALL A FUNCTION TO LATER FREE ALLOCATED MEMORY 
} 

這樣一來,你操縱原始字符串的副本,而且比你做的緩衝區的副本在結構變量。

如果你這樣做:

l->name = buffer; 

你只複製一個本地指針,將與函數結束時消失。

我建議你在C中學習更多關於指針,數組和字符串的知識。實質上,一個字符串是一個char數組,最終位置爲'\ 0'。一個空字符串s在s [0]中有'\ 0'。

編輯:如果你使用的語言,這使得該字符串的副本是這樣的:

string1 = string2 

你應該總是記住,在C,這是指針賦值。因此,在C中,代碼將不得不這樣寫:

strcpy(string1, string2); 

希望有幫助。