从指针数组中找到重复项

时间:2011-06-21 13:09:50

标签: c arrays pointers

我想找到一个指针数组中的重复项。代码如下所示。当我运行这个应用程序时,它是gining分段错误。但是当我提取这个函数时,我能够运行它就好了。可以有人请告诉我什么可以“

当我检测到重复项时,我只是将这些字符串放到名为output.txt的文件中。

我发现当使用strcmp时,它会给出这个分段错误。 但是当我提取这个函数并在一些测试代码上运行它时,它确实很好。

      main()
      {
           char *a[20];
           DIR             *dip;
           int i = 0;
           dip = opendir("src/my_folder");
           char *condition_var; 


           while ((dit = readdir(dip)) != NULL)               
           {
           condition_var = dit->name;      

            a[i] = condition_var
                            i++;
            }
            findduplicates(a,i);
       }

      char *findduplicates(char *arr[3],int count)
      {
      int i = 0;
      int j = 0;
      int val = 0;
      FILE *output = fopen("output.txt","w");
      for(i = 0;i<count;i++)
      { 
               j = i+1;
       for(;j<count;j++)
       {
             if(strcmp(arr[i],arr[j])==0)
             {
           printf("The index of a duplicate elemnt is %d\n",j);
           arr[j] = " ";

             }
        }

      }
int k = 0;
while(k<3)
{

   printf("the aarray is %s\n",arr[k]);
   fputs(arr[k],output);
   fputs("\n",output);
   k++;
}

}`

高级谢谢 麦迪

3 个答案:

答案 0 :(得分:0)

char *a[20]; // an array of char pointers. 20 elements in the array.

char *findduplicates(char *arr[3],int count)
// arr is an array of char pointers, with 3 elements in the array.

findduplicates(a, count); // this will just pass 3 of the 20 pointers
// thus when you try to access a[3], it will probably seg-fault.

试试这个:

char *findduplicates(char **arr,int count)

[编辑] 也许我错了。我刚刚写了一个小测试程序,即使将函数参数声明为char *a[0]也不会崩溃。但无论如何,请尝试我的建议。内存错误并不总是让事情崩溃......

答案 1 :(得分:0)

我写了一些东西,它会在任意字符串数组中找到重复项并打印出名称。如果您特别需要原始数组中的索引,我无法从您的问题中判断出来。此版本将对数组进行排序,原始索引将“丢失”。但是,如果您只需要知道重复的名称,则以下内容应该有效:

#include <string.h>
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>

#define TRUE 1
#define FALSE 0

/* Compare function for quicksort. Shamelessly taken directly from linux man
 * page */
static int cmpstringp(const void *p1, const void *p2)
{
   return strcmp(* (char * const *) p1, * (char * const *) p2);
}

void find_duplicates(char *strings[], size_t size)
{
    size_t i, j, last_occurrence;
    int is_unique;

    for(i = 0; i < size; ++i)
    {
        /* This variable tells us if the current element is unique */
        is_unique = TRUE;
        for(j = i; j < size; ++j)
        {
            /* Make sure we aren't comparing the element to itself */
            if((j != i) && (strcmp(strings[i], strings[j]) == 0))
            {
                /* Since the array is sorted, we store the index of the last
                 * duplicate and continue our search from there.
                 */
                last_occurrence = j;
                is_unique = FALSE;
            }
        }

        /* The element was not unique, print the name */
        if(is_unique == FALSE)
        {
            printf("Duplicate: %s\n", strings[i]);
            /* Set the counter to the next element we must check for
                             * "uniqueness" */
            i = last_occurrence;
        }
    }
}

int main(int argc, char *argv[])
{
    /* Test array */
    char *test_array[] = { "test1", "test2", "test3", "test1", 
                                   "test4", "test1", "test4" };

    /* Sort it using quicksort to make the process of finding duplicates
     * easier
     */
    qsort(test_array, 7, sizeof(char*), cmpstringp);

    find_duplicates(test_array, 7);

    return 0;
}

答案 2 :(得分:0)

我认为这部分将成为问题的根源:

    while ((dit = readdir(dip)) != NULL)               
       {
           condition_var = dit->name;      
           a[i] = condition_var;  
                         i++;
       }

我不确定readdir()是如何工作的,但我猜每次它都会返回一个指向dit的时间结构指针。 a [i]将condition_var保存为指向名称的指针。有可能稍后再调用readdir()并使用完全相同的mem空间来返回时间结构,覆盖先前condition_var指向的mem空间。

我建议采用一种更安全的方式来完成这一部分,但这可能会稍微复杂一些。

    while ((dit = readdir(dip)) != NULL)               
       {
           int len = strlen(dit->name);
           condition_var = malloc(len+1);
           memncpy(condition_var, dit->name, len+1);
           //condition_var = dit->name;      
           a[i] = condition_var;  
                         i++;
       }

请记住在程序结束时释放您使用malloced的每个mem块。 (或者您可以将所有这些留给操作系统来收集内存 - 不推荐)。代码应该是这样的:

     int j; // use another loop indicator if you already declared j for other uses.
     for(j = 0; j<i; j++)   // i is the length of a[].
     {
         free(a[j]);   
         // no worry about a[j] being NULL. free() does nothing on a NULL pointer.
         a[j] = NULL;
     }