我的代码存在循环问题。我有一个方法,需要两个字符数组(短语,字符)。字符数组包含必须单独读取并与短语进行比较的字符。如果匹配,则每次出现的字符都会从短语中删除。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//This method has two parameters: (str, c)
//It will remove all occurences of var 'c'
//inside of 'str'
char * rmstr(char * c, char * str) {
//Declare counters and pointers
int stemp = 0;
int ctemp = 0;
char *p = str;
char *d = c;
//Retrieve str count
while(str[stemp] != '\0') {
stemp++;
}
//Retrieve c count
while(c[ctemp] != '\0') {
ctemp++;
}
//Output information
printf("String Count: %d\n",stemp);
printf("Character Count: %d\n",ctemp);
//Iterate through arrays
for (int i = 0; i != stemp; i++) {
for (int j = 0; j != ctemp; j++) {
if (c[j] != str[i]){
*p++ = str[i];
}
break;
}
printf("%s\n",str);
}
*p = 0;
return str;
}
int main()
{
char c[256] = "ema";
char input[256] = "Great message!";
char *result = rmstr(c, input);
printf("%s", result);
return 0;
}
在这种情况下,输入内容为“好消息!”我想删除所有出现的字符:e,m,a(如main中所指定)。
使用上面的代码,输出如下:
Grat mssag!
它仅循环1次迭代并删除'e'。我希望它也可以遍历“ m”和“ a”。
答案 0 :(得分:1)
在修复导致内部循环退出的break;
之后,重新排列循环并遍历要删除的字符,同时检查str
中的字符可能是有意义的。如果您将str
中的每个字符与字符c
相匹配,则可以更方便地将其中的每个字符减1。如果您正在使用string.h
之类的memmove
中的函数来向下移动字符,则没关系。
仅使用指针手动完成str
并删除c
中所有字符的简单实现可能类似于以下内容:
#include <stdio.h>
char *rmstr (char *str, const char *chars)
{
const char *c = chars; /* set pointer to beginning of chars */
while (*c) { /* loop over all chars with c */
char *p = str; /* set pointer to str */
while (*p) { /* loop over each char in str */
if (*p == *c) { /* if char in str should be removed */
char *sp = p, /* set start pointer at p */
*ep = p + 1; /* set end pointer at p + 1 */
do
*sp++ = *ep; /* copy end to start to end of str */
while (*ep++); /* (nul-char copied on last iteration) */
}
p++; /* advance to next char in str */
}
c++; /* advance to next char in chars */
}
return str; /* return modified str */
}
int main (void) {
char c[] = "ema";
char input[] = "Great message!";
printf ("original: %s\n", input);
printf ("modified: %s\n", rmstr (input, c));
return 0;
}
(执行此操作的方法有很多-您在很大程度上取决于您。是否使用上面的指针,还是获取长度并使用字符串索引也是一个选择的问题)
使用/输出示例
$ ./bin/rmcharsinstr
original: Great message!
modified: Grt ssg!
如果您确实想使用memmove
(以解决源和目标的重叠性质),则每次str
中的字符将str
中的其余字符向下移一匹配c
中的字符,则可以按原始顺序保留循环,例如
#include <string.h>
char *rmstr (char *str, const char *chars)
{
char *p = str; /* set pointer to str */
while (*p) { /* loop over each char in str */
const char *c = chars; /* set pointer to beginning of chars */
while (*c) { /* loop over all chars with c */
while (*c == *p) { /* while the character matches */
memmove (p, p + 1, strlen (p)); /* shuffle down by 1 */
c = chars; /* reset c = chars to check next */
}
c++; /* advance to next char in chars */
}
p++; /* advance to next char in str */
}
return str; /* return modified str */
}
(确保您了解为什么在这种情况下必须重置c = chars;
)
最后,如果您确实想要这样做的简便方法,则可以使用strpbrk
和memmove
并将函数简化为:
#include <string.h>
char *rmstr (char *str, const char *chars)
{
/* simply loop using strpbrk removing the character found */
for (char *p = strpbrk (str, chars); p; p = strpbrk (str, chars))
memmove (p, p+1, strlen(p));
return str; /* return modified str */
}
(在C语言中,猫皮总是有不止一种方法)
输出是相同的。看看这里的东西,如果您还有其他问题,请告诉我。