简体   繁体   English

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

[英]Delete Words from a String Array based on Words of Another String Array in C Programming

I am trying to write a C program to delete some words from an Array of String (chars) in C programming based on another Array of String (chars). 我正在尝试编写一个C程序,根据另一个字符串数组(字符串)从C编程中的字符串数组(字符串)中删除一些单词。

I have written a program like the following. 我写了一个如下的程序。

# 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");
}

But unfortunately, the program is not working as desired. 但遗憾的是,该计划并未按预期运作。 I am not understanding what I am doing wrong in here. 我不明白我在这里做错了什么。 Can anyone please suggest me what I am doing wrong in here or an easier way of doing it. 任何人都可以告诉我我在这里做错了什么或更简单的方法。 Thanks in advance. 提前致谢。

Try this. 尝试这个。 The initial lists have had an empty string added to the end as a sentinel, and the loops have been changed to use the sentinels. 初始列表有一个空字符串作为标记添加到结尾,并且循环已更改为使用标记。 When the string to be deleted is detected, I change the first char to 0x1A (the ASCII control char for "substitution occurred" - chosen somewhat arbitrarily). 当检测到要删除的字符串时,我将第一个字符更改为0x1A(“替换发生”的ASCII控制字符 - 稍微任意选择)。 Then I walk the word list once, and when I find a sub char, i skip that string and then 'compress out' the deleted words by copying over them from the next non-null string without a sentinel char in it. 然后我走了一次单词列表,当我找到一个子字符时,我跳过该字符串,然后通过从下一个非空字符串复制删除的字词来“压缩”它们,而不包含其中的标记字符。 I could have used some trickery to avoid the second pass and copy things over in the main loop, but I did not want to over combine the logic for you. 我可以使用一些技巧来避免第二次传递并在主循环中复制一些东西,但我不想为你整合逻辑。

#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");
}

First off you need to keep track of the number of elements in each array 首先,您需要跟踪每个阵列中的元素数量

 size_t numName = 22;
 size_t numDelete = 5;

The issue is in the line for(j=0; j<22; j++) . 问题出在for(j=0; j<22; j++) When you delete a word in Name, you must not increment j . 删除名称中的单词时, 不得增加j

The basic logic isn't too bad as long as you update the number of words in numNames and update j correctly. 只要更新numNames中的单词数并正确更新j ,基本逻辑就不会太糟糕。

UPDATE I just noticed that you have your indexes for i and j reversed in strcmp . 更新我刚刚注意到你在strcmp反转了ij索引。 That's another issue. 那是另一个问题。

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. */
        }
    }
}

NOTE: I also got rid of flag it wasn't needed. 注意:我也摆脱了不需要的flag

I also was able to solve the problem by doing it like the following: 我也能够通过以下方式解决问题:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM