[英]Remove Vowels from string using pointers in C
我正在嘗試使用指針從2D數組字符串中刪除元音。 我能夠通過其ASCII值檢測到元音,但是字符串沒有得到更新。
代碼的這一部分不能更改。
void remove_vowel(char strings[NUM_STRINGS][STRING_LENGTH])
我的代碼哪里出問題了?
更新的代碼:
void remove_vowel(char strings[NUM_STRINGS][STRING_LENGTH])
{
// loop through each row, starting intitally points to last element
for (char(*p)[STRING_LENGTH] = strings; p != strings + NUM_STRINGS; ++p) {
// variable q points to the first element
for (char *q = *p; q != *p + STRING_LENGTH; ++q) {
if (*q != 'a' && *q != 'e' && *q != 'i' && *q != 'o' && *q != 'u') {
//printf("%c",*q);
*q = *q;
}
}
}
}
我能夠使用下面列出的解決方案重新編寫代碼。 感謝大家的幫助!
解
void remove_vowel(char strings[NUM_STRINGS][STRING_LENGTH])
{
// store the array in a pointer
char(*wordHolder)[STRING_LENGTH] = strings;
// loop through each row
for (int i = 0; i < NUM_STRINGS; i++)
{
// assign worl
char *letter = *wordHolder;
char *dest = *wordHolder;
// check if null character
while (*letter != '\0') {
// check for vowels
if (*letter != 'a' && *letter != 'e' && *letter != 'i' && *letter != 'o' && *letter != 'u') {
// assign non-vowel letter to destination
*dest++ = *letter;
}
// move to next letter
letter++;
}
// add null pointer to end of destination
*dest = '\0';
// increment pointer position to next word
wordHolder++;
}
}
這個問題已經隨着時間而改變,最初是針對c ++提出的 。 我在這里留下它的歷史的目的,但它並不適用於新的目標Ç
remove_if
應該可以解決您的問題,其中:
刪除是通過移動(通過移動分配)范圍中的元素來完成的,要刪除的元素出現在范圍的開頭。 保留了剩余元素的相對順序,並且容器的物理大小未更改。
您可以像這樣利用remove_if
:
void removeVowel(char strings[][STRING_LENGTH]) {
for (auto p = strings; p != next(strings, NUM_STRINGS); ++p) {
remove_if(begin(*p), end(*p), [vowels = "aeiouAEIOU"s](const auto& i){return vowels.find(i) != string::npos;});
}
}
這個非常簡單的解決方案要求char[]
元素以'\\0'
結尾。 remove_if
只是將所有元音字符移到忽略它們的'\\0'
字符之后。 在以下情況下,這可能不是可行的解決方案:
'\\0'
結尾的char[]
,這是一個非常糟糕的設計決定,但是如果您在那兒,讓我們在評論中討論解決方法 STRING_LENGTH
非常大; remove_if
每次都搜索STRING_LENGTH
元素,因此,如果字符串比包含的數組短得多,請考慮使用next(*p, strlen(*p) + 1)
代替end(*p)
注釋strings
參數,用於C ++函數參數:
如果類型是“的陣列
T
”或“結合的未知的陣列T
”,它是由型“指針替換T
” [ 源 ]
因此,數組主要維度中的任何值都將被丟棄並視為參數被轉換為指針。 因此,您將在我的代碼中看到另一個代碼,其中未填充數組函數參數的主要維度,因為當對具有不同主要維度的數組進行排序時,它對傳遞的數組的實際大小沒有任何要求,並因此可能造成混亂未經警告即接受。
雄辯地說,您會注意到我的代碼和其他代碼中的所有非主要尺寸都將被填充。 這是由於以下事實:
多維數組與常規數組非常相似。 就像數組一樣,多維數組存儲為相同類型的對象的連續序列。 需要注意的重要事項是定義每個尺寸的尺寸的數字。 因此,在不提供多維數組長度的情況下也無法傳遞多維數組[ source ]
因此,您會注意到我們可以調用begin(*p)
和end(*p)
但不能調用
或
begin(strings)
。 end(strings)
對於初學者,您應該將現有的remove_vowel()
例程分為(至少) 三個獨立的函數:
void remove_vowel(std::string& s)
{
...
}
void remove_vowel(std::vector<std::string>& strings)
{
for(auto&& s : strings)
remove_vowel(s);
}
void remove_vowel(char strings[NUM_STRINGS][STRING_LENGTH]) // can't change this signature
{
...
}
現在,您的問題減少到兩個(或三個)幾乎完全不相關的部分:
std::string
刪除元音 我建議您編寫更多的“類似於C ++”的代碼。
#include <string> // needed for string container
#include <vector> // needed for vector container
// This function removes all vowels from a std::string
std::string removeVowels(std::string input) {
std::vector<std::string> vowels = {"a", "e", "i", "o", "u", "A", "E", "I", "O", "U"}; // create and initilise a dynamic array with all vowels, that should be filtered
// Iterate over all vowels
for(const std::string vowel : vowels) {
// Get first position of the appearance of the vowel,
// exit if none are found
while(auto pos = input.find(vowel) != std::string::npos) {
// replace vowel with empty string
input.erase(pos, vowel.size());
}
}
// return our result
return input;
};
我編譯並測試了此示例。
我讓您編寫函數,該函數需要2D字符串數組並使用此函數。 考慮在c樣式數組上使用std :: vector。
讓我們考慮一下C語言的等效項。
在C語言中,您需要將文本視為數組。 對於陣列, 擦除插槽時,需要移動其余項目以覆蓋擦除的插槽。
讓我們從那里開始。
void dont_copy_vowels(char text_array[STRING_LENGTH])
{
char * p_source = &text_array[0];
char * p_destination = &text_array[0];
const unsigned int length = strlen(text_array);
while (*p_source != '\0')
{
static const char vowels[] = "aeiou";
if (strchr(vowels, *p_source) != NULL)
{
++p_source;
continue; // don't copy vowels.
}
// Copy the letter or symbol.
*p_destination++ = *p_source++;
}
*p_destination = '\0';
}
由於您使用的是C樣式字符串數組,因此需要將以上代碼放入循環中:
for (unsigned int string_index = 0;
string_index < NUMBER_OF_STRINGS;
++string_index)
{
dont_copy_vowels(strings[string_index]);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.