如何解决我的挤压函数有什么问题?
现在我正在读《C 程序设计语言》这本书,这真是一段令人羞愧的经历。现在我正在练习本书中的练习 2-3,但我无法弄清楚我的挤压()函数哪里出了问题。该函数的目的是删除在字符串 2 中找到的字符串 1 中的任何字符。现在我的函数所做的就是删除字符串 1 的第一个字符,如果它在字符串 2 中找到,然后在此之后出现奇怪的行为......我查看了答案书和给出的答案让我很困惑。很难理解正在做的事情,所以我不想遵循答案书中的逻辑,而是想知道我自己的代码哪里出错了......这是下面的代码:
/* Write an alternate version of squeeze(s1,s2) that deletes each char in s1 that matches
* any char in string s2 */
/* Here's a reference for squeeze(s1,s2):
* squeeze: delete all c from s
*
* void squeeze(char s[],int c)
* {
* int i,j;
*
* for(i = j = 0; s[i] != '\0'; i++)
* if(s[i] != c)
* s[j++] = s[i];
* s[j] = '\0';
* }
*******************************************/
#include <stdio.h>
#include <string.h>
#define MAX_INPUT 100
void squeeze(char string1[],char string2[]);
int main()
{
int c,i = 0,j = 0;
char s1[MAX_INPUT + 2],s2[MAX_INPUT + 2];
printf("\nPlease enter string1\n");
while((c = getchar()) != '\n')
{
s1[i] = c;
i++;
}
s1[i] = '\0';
/* test to see if above worked */
printf("\ns1 = %s\n",s1);
printf("\nPlease enter string2\n");
while((c = getchar()) != '\n')
{
s2[j] = c;
j++;
}
s2[j] = '\0';
/* test to see if above worked */
printf("\ns2 = %s\n",s2);
printf("\nWe will now apply the squeeze function to remove any chars");
printf(" found in string2 from string1\n");
squeeze(s1,s2);
printf("Squeeze(s1,s2) = %s\n",s1);
}
void squeeze(char s1[],char s2[])
{
int i = 0,j = 1; /* for counters */
char temp; /* for char comparison */
temp = s2[0];
while(s2[i] != '\0')
{
if(s1[i] == temp)
{
s1[i] = s1[i+1];
j++;
}
else
{
j++;
}
temp = s2[j];
i++;
}
s1[i+1] = '\0';
}
我的输出如下:
Please enter string1
hello
s1 = hello
Please enter string2
help
s2 = help
We will now apply the squeeze function to remove any chars found in string2 from string1
Squeeze(s1,s2) = eello
谁能发现我的逻辑有什么问题?从答案书中我猜我需要第三个计数器,k,在某个地方,但我看不出我对函数进行编程的方式的原因..我知道我错过了一些东西!非常感谢大家:)
回答(谢谢弗拉德!):
void squeeze(char s1[],char s2[])
{
int i = 0,j = 0;
do
{
int k = 0;
while(s2[k] != '\0' && s2[k] != s1[i])
++k;
if (s2[k] == '\0')
{
if ( j != i)
s1[j] = s1[i];
++j;
}
} while (s1[i++] != '\0');
}
解决方法
你的函数没有意义。
while循环根据s2的长度执行
while(s2[i] != '\0')
但是,您使用相同的索引 i
来检查字符串 s1
。
if(s1[i] == temp)
但是字符串 s1
通常可以比字符串 s2
短或大。因此该函数可以调用未定义的行为。
s1
中的每个字符也应从字符串 s2
的开头开始检查。
可以声明和定义函数(不使用标准 C 字符串函数),如下面的演示程序所示。
#include <stdio.h>
char * squeeze( char s1[],const char s2[] )
{
if ( *s2 != '\0' )
{
size_t i = 0;
size_t j = 0;
do
{
size_t k = 0;
while ( s2[k] != '\0' && s2[k] != s1[i] ) ++k;
if ( s2[k] == '\0' )
{
if ( j != i ) s1[j] = s1[i];
++j;
}
} while ( s1[i++] != '\0' );
}
return s1;
}
int main(void)
{
char s1[] = "Hello World!";
const char *s2 = "aeiou";
puts( s1 );
puts( squeeze( s1,s2 ) );
return 0;
}
程序输出为
Hello World!
Hll Wrld!
,
我使用 tmp
缓冲区复制不包含字符。比较简单,可以查一下。
void squeeze(char s1[],char s2[]){
int i,j,k = 0;
char* tmp;
// tmp buffer initial size can be maximum s1 length
tmp = malloc(strlen(s1) + 1);
// loop until s1 character is null
i = 0;
while(s1[i] != '\0'){
// loop until character is found or to the end.
// break if s2 reached to the end or s1[i] == s2[j]
j = 0;
while(s2[j] != '\0' && s2[j] != s1[i]){
j++;
}
// if j reached to the end,add into tmp buffer
if(s2[j] == '\0'){
// set current character
tmp[k] = s1[i];
// increase index
k++;
} else {
printf("Found %c\n",s1[i]);
}
// next character
i++;
}
// last character must be null
tmp[k] = '\0';
// tmp copy to s1
strcpy(s1,tmp);
// free tmp buffer
free(tmp);
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。