我正在尝试编写一个C程序,根据另一个字符串数组(字符串)从C编程中的字符串数组(字符串)中删除一些单词。
我写了一个类似以下的程序。
# include <stdio.h>
# include <string.h>
void main()
{
int i, j, k, flag;
char Name[200][100] = {"descent","of","man","the","ascent","of","man","the","old","man","and","the","sea","a","portrait","of","the","artist","as","a","young","man"};
char Delete[200][100] = {"the","of","and","as","a"};
printf("Words are : \n\n");
for (i = 0; i<22; i++)
{
printf("%s, ", Name[i]);
}
printf("\n\nWords for deletion are: \n\n");
for (i = 0; i<5; i++)
{
printf("%s, ", Delete[i]);
}
printf("\n\n");
for(i=0; i<5; i++)
{
flag = 0;
for(j=0; j<22; j++)
{
if(strcmp(Name[i],Delete[j]) == 0)
{
flag = 1;
}
if (flag == 1)
{
for (k = j; k<22-1; k++)
{
strcpy(Name[k],Name[k+1]);
}
strcpy(Name[22-1],"");
}
}
}
printf("Words after deletion is : \n\n");
for (i = 0; i<22; i++)
{
printf("%s ", Name[i]);
}
printf("\n");
}
但不幸的是,该计划没有按预期运作。我不明白我在这里做错了什么。任何人都可以告诉我我在这里做错了什么或更简单的方法。提前谢谢。
答案 0 :(得分:1)
试试这个。初始列表有一个空字符串作为标记添加到结尾,并且循环已更改为使用标记。当检测到要删除的字符串时,我将第一个字符更改为0x1A(&#34的ASCII控制字符;发生替换&#34; - 稍微任意选择)。然后我走了一次单词列表,当我找到一个子字符时,我跳过那个字符串,然后“压缩”#39;删除的单词通过从下一个非空字符串复制它们而没有其中的sentinel字符。我可以使用一些技巧来避免第二次传递并在主循环中复制一些东西,但我不想为你合并逻辑。
#include <stdio.h>
#include <string.h>
void main()
{
int i, j;
/* both lists end with a sentinal string of "" */
char Name[200][100] = {"descent","of","man","the","ascent","of","man","the","old","man","and","the","sea","a","portrait","of" ,"the","artist","as","a","young","man",""};
char Delete[200][100] = {"the","of","and","as","a", ""};
printf("Words are : \n\n");
for( i=0; Name[i][0] != 0x00; i++ ) {
printf("%s, ", Name[i]);
}
printf("\n\nWords for deletion are: \n\n");
for( j=0; Delete[j][0] != 0x00; j++ ) {
printf("%s, ", Delete[j]);
}
printf("\n\n");
/* mark for removal */
for( i=0; Name[i][0] != 0x00; i++ ) {
for( j=0; Delete[j][0] != 0x00; j++ ) {
if(strcmp(Name[i],Delete[j]) == 0) {
Name[i][0]=0x1A; /* ASCII ctrl char for substitute - chosen arbitrarily */
}
}
}
/* one pass to remove */
for( i=0, j=0; Name[i][0] != 0x00; i++,j++ ) {
while( Name[i][0] == 0x1A )
i++;
if(i!=j)
strcpy(Name[j],Name[i]);
}
strcpy(Name[j],Name[i]);
printf("Words after deletion are: \n\n");
for( i=0; Name[i][0] != 0x00; i++ ) {
printf("%s ", Name[i]);
}
printf("\n");
}
答案 1 :(得分:1)
首先,你需要跟踪每个数组中元素的数量
size_t numName = 22;
size_t numDelete = 5;
问题出在for(j=0; j<22; j++)
行。当您删除姓名中的字词时,不得增加j
。
只要更新numNames中的单词数并正确更新j
,基本逻辑就不会太糟糕。
更新我刚刚注意到您i
和[{1}}的索引在j
中被撤消了。那是另一个问题。
strcmp
注意:我也摆脱了for (i = 0; i < numDelete; i++)
{
for (j = 0; j < numName;)
{
if (strcmp(Name[j], Delete[i]) == 0)
{
for (k = j; k < numName - 1; k++)
{
strcpy(Name[k], Name[k+1]);
}
strcpy(Name[numName - 1], "");
numName--; /* After deleting a name, reduce the size of the name array */
}
else
{
j++; /* Only increment j when not deleting. */
}
}
}
它不需要。
答案 2 :(得分:0)
我也能够通过以下方式解决问题:
len = 22;
for(i=0; i<5; i++)
{
flag = 0;
for(j=0; j<len; j++)
{
if(strcmp(Name[j],Delete[i]) == 0)
{
for (k = j; k<len-1; k++)
{
strcpy(Name[k],Name[k+1]);
}
strcpy(Name[len-1],"");
len--;
}
}
}