在C编程中基于另一个字符串数组的字删除字符串数组中的字

时间:2014-05-09 17:58:27

标签: c arrays string

我正在尝试编写一个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");
}

但不幸的是,该计划没有按预期运作。我不明白我在这里做错了什么。任何人都可以告诉我我在这里做错了什么或更简单的方法。提前谢谢。

3 个答案:

答案 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--;
    }
}
}