[英]reverse vowels in string in c
I'm a beginner programmer. 我是一个初学者程序员。 I was trying out the problem of reversing vowels in a string.
我正在尝试反转一串元音的问题。
Ex: input: zabedfigu, output: zubidfega 例如:输入:zabedfigu,输出:zubidfega
When I run the following code, I get a runtime error. 当我运行以下代码时,出现运行时错误。 I've tried to change the conditions within incrementing the pointer pc1 upto only upto the middle index etc., but that either gives me a runtime error or doesn't give me the required output.
我试图在将指针pc1递增到仅直到中间索引等范围内更改条件,但是这给了我运行时错误或没有给我所需的输出。 I'd like some help on what to do to make my code work as well as any new way of solving the problem.
我想要一些有关如何使我的代码正常工作以及解决问题的新方法的帮助。 TIA.
TIA。
#include<stdio.h>
char* reverseVowels(char* str)
{
char *pc1, *pc2;
int i;
pc1 = &str[0];
for(i=0; str[i]!='\0';++i)
;
pc2 = &str[i-1];
while(pc1!=pc2)
{
if((*pc1=='a')||(*pc1=='e')||(*pc1=='i')||(*pc1=='o')||(*pc1=='u'))
{
while(pc2!=pc1)
{
if((*pc2=='a')||(*pc2=='e')||(*pc2=='i')||(*pc2=='o')||(*pc2=='u'))
{
char temp;
temp = *pc1;
*pc1 = *pc2;
*pc2 = temp;
++pc2;
break;
}
else
++pc2;
}
++pc1;
}
else
++pc1;
}
//return str;
return NULL;
}
int main()
{
char string[20], *pstr;
scanf("%s", string);
//pstr = reverseVowels(string);
//printf("%s", pstr);
reverseVowels(string);
printf("%s", string);
return 0;
}
The problem here is that you are incrementing both pointers the one in the 0 position, and the one in the end position. 这里的问题是,您将两个指针都在0位置递增,并将一个指针在结束位置递增。 The first pointer should increment, and the second one should decrement, thus instead of doing this:
第一个指针应该增加,第二个指针应该减少,因此不要这样做:
++pc2;
You should do this 你应该做这个
--pc2;
The problem is occurring when you are going to increment the pointer variable value of pc2
, instead of decrementing the pointer variable pc2
value like this --pc
. 当您要递增
pc2
的指针变量值,而不是像--pc
这样递减指针变量pc2
值时, --pc
。
Updated 更新
According to cleblanc 's comment , my previous answer was not working for an input like abade
, so then I changed the code to fix that problem. 根据cleblanc的评论 ,我先前的答案不适用于
abade
类的输入,因此我更改了代码以解决该问题。
#include <stdio.h>
char* reverseVowels(char* str)
{
char *pc1, *pc2;
int i;
pc1 = &str[0];
for(i=0; str[i]!='\0';++i)
;
pc2 = &str[i-1];
while(pc1<pc2)
{
if((*pc1=='a')||(*pc1=='e')||(*pc1=='i')||(*pc1=='o')||(*pc1=='u'))
{
while(pc2!=pc1)
{
if((*pc2=='a')||(*pc2=='e')||(*pc2=='i')||(*pc2=='o')||(*pc2=='u'))
{
char temp;
temp = *pc1;
*pc1 = *pc2;
*pc2 = temp;
--pc2;
break;
}
else
--pc2;
}
++pc1;
}
else
++pc1;
}
//return str;
return NULL;
}
int main()
{
char string[20], *pstr;
scanf("%s", string);
//pstr = reverseVowels(string);
//printf("%s", pstr);
reverseVowels(string);
printf("%s\n", string);
return 0;
}
You have several answers and comments pointing out the fundamental flaw in your code — that you're incrementing pc2
instead of decrementing it. 您有几个答案和注释,指出了代码的基本缺陷-您要递增
pc2
而不是递减pc2
。 However, I think your algorithm is more complicated than need be. 但是,我认为您的算法比需要的复杂。 You could:
你可以:
pc1 < pc2
: pc1 < pc2
:
pc1
is not pointing at a vowel, increment it pc1
没有指向元音,则将其递增 pc2
is not pointing at a vowel, decrement it pc2
没有指向元音,则将其递减 With test code, and with the addition of an is_vowel()
function which detects both upper-case and lower-case vowels, I ended up with: 使用测试代码,并添加了一个
is_vowel()
函数,该函数可以同时检测大写和小写的元音,最后我得到了:
#include <ctype.h>
#include <stdio.h>
#include <string.h>
static inline int is_vowel(int c)
{
c = tolower(c);
return (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u');
}
static void reverse_vowels(char *string)
{
char *p1 = string;
char *p2 = p1 + strlen(p1); // '\0' is not a vowel
while (p1 < p2)
{
while (p1 < p2 && !is_vowel((unsigned char)*p1))
p1++;
while (p1 < p2 && !is_vowel((unsigned char)*p2))
p2--;
if (p1 != p2)
{
char c = *p1;
*p1++ = *p2;
*p2-- = c;
}
}
}
int main(void)
{
#ifdef INTERACTIVE
char line[1024];
while (fgets(line, sizeof(line), stdin) != NULL)
{
line[strcspn(line, "\n")] = '\0';
printf("Input: [%s]\n", line);
reverse_vowels(line);
printf("Output: [%s]\n", line);
}
#else
char strings[][40] =
{
"",
"a",
"b",
"ab",
"abe",
"abeci",
"nnnnummmmmmmmmmmmippppoqq",
"AbleWasIEreISawElba",
"A Man, A Plan, A Canal - Panama!"
};
enum { NUM_STRINGS = sizeof(strings) / sizeof(strings[0]) };
for (int i = 0; i < NUM_STRINGS; i++)
{
printf("Input: [%s]\n", strings[i]);
reverse_vowels(strings[i]);
printf("Output: [%s]\n", strings[i]);
}
#endif /* INTERACTIVE */
return 0;
}
You can compile it with -DINTERACTIVE
to give you an interactive test, or by default it gives a fixed set of tests. 您可以使用
-DINTERACTIVE
进行编译,以提供交互式测试,或者默认情况下,它提供一组固定的测试。
Default output: 默认输出:
Input: []
Output: []
Input: [a]
Output: [a]
Input: [b]
Output: [b]
Input: [ab]
Output: [ab]
Input: [abe]
Output: [eba]
Input: [abeci]
Output: [ibeca]
Input: [nnnnummmmmmmmmmmmippppoqq]
Output: [nnnnommmmmmmmmmmmippppuqq]
Input: [AbleWasIEreISawElba]
Output: [ablEWasIerEISawelbA]
Input: [A Man, A Plan, A Canal - Panama!]
Output: [a Man, a Plan, a CAnal - PAnamA!]
Sample interactive session (my program was called rv61
): 样本交互式会话(我的程序称为
rv61
):
$ rv61
Input: []
Output: []
a
Input: [a]
Output: [a]
b
Input: [b]
Output: [b]
ab
Input: [ab]
Output: [ab]
ae
Input: [ae]
Output: [ea]
abcde
Input: [abcde]
Output: [ebcda]
ablewasiereisawelba
Input: [ablewasiereisawelba]
Output: [ablewasiereisawelba]
palindromic nonsense
Input: [palindromic nonsense]
Output: [pelendromic nonsinsa]
vwlsmssng
Input: [vwlsmssng]
Output: [vwlsmssng]
AManAPlanACanal-Panama!
Input: [AManAPlanACanal-Panama!]
Output: [aManaPlanaCAnal-PAnamA!]
a big and complex sentence with multiple words of a number of lengths and so on
Input: [ a big and complex sentence with multiple words of a number of lengths and so on ]
Output: [ o bog and cemplox sentunca woth moltepli wurds if e nember ef longths and si an ]
$
Note that the testing tests a number of degenerate cases — an empty string, a string with no vowels, a string with one vowel, etc. The palindromic tests benefit from supporting mixed case — it's hard to spot that vowels have been swapped if they're all lower case and the text is a palindrome. 请注意,该测试会测试多种退化的情况-空字符串,不带元音的字符串,不带元音的字符串等。回文测试得益于支持混合大小写的情况-很难发现如果元音已被交换,都是小写,文字是回文。
Another test that could be applied is to reverse the vowels twice; 可以应用的另一个测试是将元音反转两次。 the output should be the same as the input.
输出应与输入相同。 Conservation tests can be important.
保存测试可能很重要。 (If you had a sort which didn't preserve all the elements in the array but added random new ones and/or dropped initial ones, you wouldn't be happy. But that's a topic for another day.)
(如果您的排序没有保留数组中的所有元素,而是添加了随机的新元素和/或删除了初始元素,那么您将不会感到高兴。但这是另一天的主题。)
Having a simple test harness along the lines shown can be helpful for library functions. 沿所示方向使用简单的测试工具有助于库功能。 Many of my library functions have a
#ifdef TEST
… #endif
at the end to allow them to be tested for sanity. 我的许多库函数的末尾都有一个
#ifdef TEST
… #endif
,以便对其进行完整性测试。 The best tests verify that the result is what is expected; 最好的测试可以验证结果是否符合预期。 these ones are lazy and leave it to visual inspection to validate the output.
这些都是懒惰的,将其留给目视检查以验证输出。 If it was a library function, there'd be a header to declare the function which would be
#include
d in the source, and the function would not be static
. 如果它是一个库函数,那么将有一个标头声明该函数,该标头在源代码中将是
#include
d,而该函数将不是static
。 (My default compilation options require either a declaration of the function before it is defined, or the function must be static
. I make functions static
in sample code like this since there's no other file referencing the function, so there's no need for a header to declare the function, and only headers should declare externally visible functions.) (我的默认编译选项或者需要一个功能的声明中定义之前,或函数必须是
static
。我做的功能static
样品中像这样的代码,因为没有其他文件中引用的功能,所以没有必要为一个头声明该函数,并且只有标头应该声明外部可见的函数。)
Note too that the is_vowel
name is carefully chosen to avoid the reserved names in the C standard: 还要注意,
is_vowel
名称是精心选择的,以避免在C标准中保留名称:
Function names that begin with either
is
orto
, and a lowercase letter may be added to the declarations in the<ctype.h>
header.以
is
或to
开头的函数名称以及小写字母可以添加到<ctype.h>
标头中的声明中。
Using isVowel()
would have been OK too; 使用
isVowel()
也可以。 using isvowel()
would be using a reserved name. 使用
isvowel()
将使用保留名称。
Bill Woodger commented : Bill Woodger 评论 :
Why the comment about '\\0' not being a vowel?
为什么有关“ \\ 0”不是元音的评论? …
...
With the code as shown, after the initialization of p2
, it is true that *p2 == '\\0'
. 使用所示的代码,在
p2
初始化之后,确实*p2 == '\\0'
。 The observation the '\\0'
is not a vowel matters if the string is non-empty because if it matched the is_vowel()
predicate, the null byte could be moved to some point earlier in the string, truncating it. 如果字符串非空,则观察到
'\\0'
不是元音很重要,因为如果字符串与is_vowel()
谓词匹配,则可以将空字节移至字符串中的较早位置,从而将其截断。
Suppose the function was reverse_controls()
instead of reverse_vowels()
and the test used iscntrl()
instead of is_vowel()
. 假设函数是
reverse_controls()
而不是reverse_vowels()
,并且测试使用了iscntrl()
而不是is_vowel()
。 Then the code would have to handle it differently for a non-zero length string because the null byte would be reported as a control character and that would send things awry — it would be swapped with the first other control character (if there was another) in the string, truncating the string. 然后,对于非零长度的字符串,代码将不得不以不同的方式处理它,因为空字节将被报告为控制字符,并且会发送错误消息-将与第一个其他控制字符(如果有另一个)交换在字符串中,截断字符串。 That is not what's intended.
那不是故意的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.