如何从char数组中正确删除字符(有或没有转换为字符串)?

时间:2016-08-24 11:42:48

标签: c++ arrays string char

提前抱歉任何可能的重复问题。我一直在谷歌搜索我的编译器错误的解决方案,一个星期了,尝试了不同的解决方法,从这里的各种答案,但我一直有一些错误。

我正在学习C ++,尝试构建一个程序来完成基本的东西,如元音/辅音计数,删除字母等。一切正常,直到我找到自定义字母删除部分。基本上,使用字符函数(根据我的知识)几乎不可能这样做,而转换为字符串似乎会产生其他类型的错误。

以下是我不断收到错误的代码片段:

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;
}

这里是我使用的初始化变量:

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;

如您所见,原始的&#39; 是一个字符数组。在第一个代码示例中,我尝试将其转换为字符串数组( string str(s)),但这会导致以下编译错误:

  • 错误:请求会员&#39;删除&#39; in&#39; s&#39;,这是非类型&#39; char [1000]&#39;
  • 错误:请求会员&#39;开始&#39; in&#39; s&#39;,这是非类型&#39; char [1000]&#39;
  • 错误:请求会员&#39;结束&#39; in&#39; s&#39;,这是非类型&#39; char [1000]&#39;
  • 错误:请求会员&#39;结束&#39; in&#39; s&#39;,这是非类型&#39; char [1000]&#39;

我尝试的另一种解决方法是:

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。如果我或主持人在回答完问题后将其删除,是否可以?我很确定我不是第一个问这个问题的人,但是,正如之前提到的那样,即使在回答了类似问题的答案之后,我仍然会收到这些错误。

3 个答案:

答案 0 :(得分:6)

对于必须使用的char数组  std::remove而不是erase,并手动插入空终止符:

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

答案 1 :(得分:1)

如果你有一个通用数组,可能会或者可能没有衰减到指针,并且你有数组中的元素数但没有其他终结符(即它不是C风格的零终止字符串),那么这是一个解决方案:

首先,我想让你想一想数组在内存中的外观。例如,如果我们有一个字符数组

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

此数组在内存中将如下所示

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

如果您要从该数组中删除字母'B',您会找到该字母的位置,然后将下一个字母('C')复制到其位置,然后填写下一个字母({ {1}})进入下一个字母等等。

您当然可以使用一个循环执行此操作:

'D'

上述循环很简单,易于理解,并且易于在调试器中逐步完成。它也不是很有效,特别是如果阵列很大的话。

所有上述复制实际上都可以通过对memmove函数的单次调用来完成:

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(&array[index_to_remove], &array[index_to_remove + 1], element_count - index_to_remove - 1); 调用,将保留数组:

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

重要说明: 请在“删除”字符后更改memmove,以便它反映新的尺寸。

答案 2 :(得分:0)

第一个解决方法:

string str(s);

此语句声明一个名为str的字符串,内容初始化为s

的内容

此声明对您的对象s

无效

因此,您需要致电str.erase()而不是s.erase()