2016-08-24 29 views
2

對不起,任何可能重複的問題。我一直在谷歌搜索我的編譯器錯誤的解決方案,現在一個星期,嘗試了不同的解決方法,從這裏的各種答案,但我不斷收到一些錯誤。如何正確地從字符數組中刪除字符(有或沒有轉換爲字符串)?

目前我正在學習C++,試圖建立一個程序,它基本的東西,如元音/輔音數量,信去除等等,直到我到了自定義信函去除一部分,一切工作正常。基本上,使用字符函數(根據我的知識)幾乎不可能做到這一點,而轉換爲字符串似乎會產生其他類型的錯誤。

下面是代碼片段,我不斷收到錯誤:正如你所看到的,原來的'

int main() 

{ 
char s[1000], phrasal[10], service[50], key1[] = "1", key2[] = "2", key3[] = "3", key4[] = "4", key5[] = "5", key6[] = "6", key0[] = "0", *p, letterToRemove; 

int vowel=0, vowel2=0, consonant=0, consonant2=0, b, i, j, k, phrase=0, minusOne, letter, idxToDel; 

void pop_back(); 

char *s_bin; 

if (strcmp (service, key4) ==0) 
{ 
string str(s); 

cout<<endl<<"Please insert the letter you would like removed from your "<<phrasal<<":"<<endl; 

cin>>letterToRemove; 

s.erase(remove(s.begin(), s.end(),letterToRemove), s.end()); 

cout<<endl<<s<< "\n"<<endl; 
} 

,並在這裏被初始化變量我使用一個char數組。在第一個代碼示例我曾嘗試將其轉換成一個字符串數組(字符串str(S)),但是這會導致以下編譯錯誤:在的請求構件「擦除」:

  • 錯誤',這是非班級類型'char [1000]'
  • 錯誤:請求成員'開始'的's',它是非班級類型'char [1000]'
  • 錯誤:請求's'中的成員'end',它是非類類型'char [1000]'
  • 錯誤:請求成員'結束'在's'中,它是非類類型'char [1000 ]'

其他解決方法我試過是這樣的:

if(strcmp(service, key4)==0) 

{std::string s(s); 

cout<<endl<<"Please insert the letter you would like removed from your "<<phrasal<<":"<<endl; 

cin>>letterToRemove; 

s.erase(remove(s.begin(), s.end(),letterToRemove), s.end()); 

cout<<endl<<s<< "\n"<<endl; 
} 

現在,這裏的有趣的部分,我沒有得到任何錯誤,任何爲這一個,但只要調試崩潰,因爲我選擇定製信去除功能。下面是這樣說的:

"terminate called after throwing an instance of 'std::length_error' what(): basic_string::_S_create          This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information."

任何幫助將不勝感激,停留在這一塊,現在一個星期!

P.S.如果我或主持人在回答問題後刪除了這個問題,可以嗎?我很確定我不是第一個問這個問題的人,但是,正如之前提到的,即使在回答類似問題的答案後,我仍然會收到這些錯誤。

+1

你用C或C++編碼嗎? 's'是一個字符串嗎?如果你用C++編碼,'s'是一個字符串,那麼爲什麼不用'std :: string'來開頭呢? –

+2

不,不要問一個問題,得到答案,然後刪除問題。我們在這裏是一個社區,你的問題和答案可以幫助其他人。 – bolov

+1

至於您的錯誤,請嘗試使用例如而不是「str.erase(...)」。 –

回答

5

對於你必須使用 std::remove代替erase,並手動插入空終止字符數組:

auto newEnd = std::remove(std::begin(s), std::end(s), letterToRemove); 
*newEnd = '\0'; 
+0

謝謝你和@ baddger964答案是s eems已經解決了這個問題。然而,在使用_string str(s)_轉換之後,_char s [] _數組到底發生了什麼?我的代碼由一些循環組成,這些循環將返回到某些點,操作員需要根據_cin.getline_格式插入一個單詞/短語(儘可能詳細,您必須插入一個等於'_cin.getline(service,50)_';根據你的輸入,標準將不得不對** s **數組應用一些** char **函數)。感謝您的時間。 – Eludium

+0

_「在使用字符串str(s)對其進行轉換後,char s []數組發生了什麼?」_ - Nothing。這些字符被複制到'std :: string'對象中,並且該數組保持不變。 – emlai

+0

謝謝@tuple_cat,太棒了! – Eludium

0

對於您的第一個解決方法:

string str(s); 

本聲明聲明字符串命名爲str,並且內容被初始化的內容爲s

本聲明作爲你反對s

所以你需要調用str.erase()s.erase()

+0

謝謝,這已證明有用! – Eludium

1

如果你有一個通用的陣列,可能會或可能不會衰減到一個指針,你有數量無影響數組中的元素,但沒有其他終止符(即它不是一個C型的零終止字符串),那麼這裏有一個解決方案:

首先,我想你認爲鄰接如何在內存中的數組。例如,如果我們有字符

char array[X] = { 'A', 'B', 'C', 'D', ... }; 

這個陣列會看起來像這樣在內存

 
+---+---+---+---+-----+ 
| A | B | C | D | ... | 
+---+---+---+---+-----+ 

如果你想從數組中刪除信'B'你發現這封信的位置的陣列,然後複製下一個字母('C')到原來的位置,而下一個字母('D')到下一個字母的地方,等

當然,你可以做到這一點使用一個循環:

size_t index_to_remove = 1; // The index of 'B' 
for (size_t i = index_to_remove = 1; i < element_count - 1; ++i) 
    array[i] = array[i + 1]; 

上面的循環很簡單,很容易弄清楚,並且很容易在調試器中一步步完成。它也不是很有效,特別是如果陣列很大。

上述所有的複製實際上可以使用單個調用memmove函數來完成:

memmove(&array[index_to_remove], 
     &array[index_to_remove + 1], 
     element_count - index_to_remove - 1); 

以上的通話將基本上做的是一樣的我們之上,但在一個更加高效和優化的方式循環。

使用上述任何一種方法,循環或memmove通話將離開陣列像這樣:

 
+---+---+---+-----+ 
| A | C | D | ... | 
+---+---+---+-----+ 

重要提示:記住更改element_count你「刪除」之後的字符,所以它反映了新的尺寸。

+0

是的,這就是它的工作原理,但是對於我的代碼,您沒有已經知道的要刪除的元素的位置;操作員輸入一個數字/字母,程序將不得不在字符串數組中搜索該元素......這引起了另一個疑問:我應該在** strchr **函數之後應用什麼算法,它基本上會做什麼你在上面的例子中指出了什麼?非常詳細的答案感謝,但我很欣賞它。 – Eludium

+0

@Teo如果您在此數組上使用'strchr'或任何其他C字符串函數,那麼它*是一個字符串,您應該真的使用'std :: string'。 –

+0

@Teo至於你在評論中的問題,你實際上可以減去兩個(相關)指針來獲得差異。如果你從你從'strchr'得到的(非空)指針中減去's',你會得到一個可以用作索引的偏移量。或者直接在調用'memmove'時使用'strchr'的結果。 –

相關問題