我的 squeeze() 函数有什么问题?
What is wrong with my squeeze() function?
现在我正在努力完成“C 程序设计语言”一书,天哪,这是一次令人羞愧的经历。现在我正在做书中的练习 2-3,但我无法弄清楚我的 squeeze() 函数哪里出了问题。该函数的目的是删除字符串 1 中在字符串 2 中找到的任何字符。现在我的所有函数所做的就是删除 string1 的第一个字符(如果它在 string2 中找到),然后在这之后表现得很奇怪。我查看了答题簿和给出的答案让我很困惑。很难理解正在做的事情,所以我没有遵循答案书中的逻辑,而是想知道我自己的代码哪里出错了……下面是代码:
/* 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] != '[=10=]'; i++)
* if(s[i] != c)
* s[j++] = s[i];
* s[j] = '[=10=]';
* }
*******************************************/
#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] = '[=10=]';
/* 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] = '[=10=]';
/* 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] != '[=10=]')
{
if(s1[i] == temp)
{
s1[i] = s1[i+1];
j++;
}
else
{
j++;
}
temp = s2[j];
i++;
}
s1[i+1] = '[=10=]';
}
我的输出如下:
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] != '[=12=]' && s2[k] != s1[i])
++k;
if (s2[k] == '[=12=]')
{
if ( j != i)
s1[j] = s1[i];
++j;
}
} while (s1[i++] != '[=12=]');
}
你的函数没有意义。
while循环根据s2的长度执行
while(s2[i] != '[=10=]')
但是您使用相同的索引 i
来检查字符串 s1
.
if(s1[i] == temp)
但是字符串 s1
通常可以比字符串 s2
更短或更大。所以函数可以调用未定义的行为。
s1
中的每个字符也应在字符串 s2
中从头开始检查。
函数可以声明和定义(不使用标准 C 字符串函数),如下面的演示程序所示。
#include <stdio.h>
char * squeeze( char s1[], const char s2[] )
{
if ( *s2 != '[=12=]' )
{
size_t i = 0;
size_t j = 0;
do
{
size_t k = 0;
while ( s2[k] != '[=12=]' && s2[k] != s1[i] ) ++k;
if ( s2[k] == '[=12=]' )
{
if ( j != i ) s1[j] = s1[i];
++j;
}
} while ( s1[i++] != '[=12=]' );
}
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] != '[=10=]'){
// 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] != '[=10=]' && s2[j] != s1[i]){
j++;
}
// if j reached to the end, add into tmp buffer
if(s2[j] == '[=10=]'){
// 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] = '[=10=]';
// tmp copy to s1
strcpy(s1, tmp);
// free tmp buffer
free(tmp);
}
现在我正在努力完成“C 程序设计语言”一书,天哪,这是一次令人羞愧的经历。现在我正在做书中的练习 2-3,但我无法弄清楚我的 squeeze() 函数哪里出了问题。该函数的目的是删除字符串 1 中在字符串 2 中找到的任何字符。现在我的所有函数所做的就是删除 string1 的第一个字符(如果它在 string2 中找到),然后在这之后表现得很奇怪。我查看了答题簿和给出的答案让我很困惑。很难理解正在做的事情,所以我没有遵循答案书中的逻辑,而是想知道我自己的代码哪里出错了……下面是代码:
/* 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] != '[=10=]'; i++)
* if(s[i] != c)
* s[j++] = s[i];
* s[j] = '[=10=]';
* }
*******************************************/
#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] = '[=10=]';
/* 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] = '[=10=]';
/* 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] != '[=10=]')
{
if(s1[i] == temp)
{
s1[i] = s1[i+1];
j++;
}
else
{
j++;
}
temp = s2[j];
i++;
}
s1[i+1] = '[=10=]';
}
我的输出如下:
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] != '[=12=]' && s2[k] != s1[i])
++k;
if (s2[k] == '[=12=]')
{
if ( j != i)
s1[j] = s1[i];
++j;
}
} while (s1[i++] != '[=12=]');
}
你的函数没有意义。
while循环根据s2的长度执行
while(s2[i] != '[=10=]')
但是您使用相同的索引 i
来检查字符串 s1
.
if(s1[i] == temp)
但是字符串 s1
通常可以比字符串 s2
更短或更大。所以函数可以调用未定义的行为。
s1
中的每个字符也应在字符串 s2
中从头开始检查。
函数可以声明和定义(不使用标准 C 字符串函数),如下面的演示程序所示。
#include <stdio.h>
char * squeeze( char s1[], const char s2[] )
{
if ( *s2 != '[=12=]' )
{
size_t i = 0;
size_t j = 0;
do
{
size_t k = 0;
while ( s2[k] != '[=12=]' && s2[k] != s1[i] ) ++k;
if ( s2[k] == '[=12=]' )
{
if ( j != i ) s1[j] = s1[i];
++j;
}
} while ( s1[i++] != '[=12=]' );
}
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] != '[=10=]'){
// 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] != '[=10=]' && s2[j] != s1[i]){
j++;
}
// if j reached to the end, add into tmp buffer
if(s2[j] == '[=10=]'){
// 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] = '[=10=]';
// tmp copy to s1
strcpy(s1, tmp);
// free tmp buffer
free(tmp);
}