如何将一个字符串数组传递给该程序中的函数?

时间:2015-03-26 15:50:39

标签: c arrays c-strings

我是C的完全初学者,我们在类中有一个赋值,用于获取给定的字符串列表,将它们放在一个字符串数组中,然后将其传递给用户定义的排序函数,该函数按字母顺序打印它们。每当我运行我的代码时,它不会给出任何编译器错误,但它也会在运行时立即崩溃。调试给我一个分段错误,但它没有给我一个导致它的特定行。我正在通过Dev C ++中包含的gcc编译器运行我的代码。 这是我的代码。任何帮助,将不胜感激。我认为我的问题是尝试将一个字符串数组传递给函数,但是我无法找到关于这个主题的任何答案我能理解。

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

void sort(char *[]);

int main()
{
    char *states[4] = {0};
    states[0] = "Florida";
    states[1] = "Oregon";
    states[2] = "California";
    states[3] = "Georgia";

    sort(states);

    return 0;
}

void sort(char *ptr[])
{
    int i, j;
    char temp[20];
    for ( i = 1; i <= 4; i++ )
    {
        for ( j = 1; j <= 4; j++ )
            {
                if (strcmp(ptr[j-1], ptr[j]) > 0)
                {
                    strcpy(temp, ptr[j-1]);
                    strcpy(ptr[j-1], ptr[j]);
                    strcpy(ptr[j], temp);
                }
            }
    }

    int x;
    for ( x = 0; x < 4; x++ )
    {
        printf("%s", ptr[x]);
        printf("\n");
    }
}

3 个答案:

答案 0 :(得分:3)

我看到的问题:

  1. 您在for循环中使用了错误的索引。

    而不是:

    for ( i = 1; i <= 4; i++ )
    {
        for ( j = 1; j <= 4; j++ )
    
  2. 使用:

        for ( i = 0; i < 4; i++ )   // Keep the values in the range 0 - 3.
        {
            for ( j = 0; j < 4; j++ )
    
    1. 您正在修改只读内存。

      使用时:

      states[0] = "Florida";
      

      states[0]具有包含字符串"Florida"的只读地址的值。如果您修改了sort中正在执行的地址的值,则表示您正在输入未定义的行为区域。

    2. 您可以通过切换指针而不是复制值来解决问题。

          // Use char* for temp instead of an array
          char* temp;
          if (strcmp(ptr[j-1], ptr[j]) > 0)
          {
              temp = ptr[j-1];
              ptr[j-1] = ptr[j];
              ptr[j] = temp;
          }
      

      附录,回应OP的评论

      以下版本的sort适用于我:

      void sort(char *ptr[])
      {
         int i, j;
         char* temp;
         for ( i = 0; i < 4; i++ )
         {
            // NOTE:
            // This is different from your version.
            // This might fix your problem.
            for ( j = i+1; j < 4; j++ )
            {
               if (strcmp(ptr[j-1], ptr[j]) > 0)
               {
                  temp = ptr[j-1];
                  ptr[j-1] = ptr[j];
                  ptr[j] = temp;
               }
            }
         }
      
         for ( i = 0; i < 4; i++ )
         {
            printf("%s", ptr[i]);
            printf("\n");
         }
      }
      

答案 1 :(得分:1)

崩溃的原因是j <= 4。另一个问题是你想要将指针交换到字符串而不是字符。

void sort(char *ptr[])
{
    int i, j;
    char *temp;
    for (i = 0; i < 4; i++) // sticking to array boundary convention
    {
        for ( j = 1; j < 4; j++ )
        {
            if (strcmp(ptr[j-1], ptr[j]) > 0)
            {
                // swap pointers 
                tmp = ptr[j];
                ptr[j] = ptr[j-1]; 
                ptr[j-1] = ptr[j];
            }
        }
    }

    for (i = 0; i < 4; i++)
        printf("%s\n", ptr[i]);
}

答案 2 :(得分:0)

C标准库已经附带了对任意数据数组进行排序的功能。它被称为qsort

qsort可以根据您使用其第四个参数(比较函数)提供的任何标准对数组进行排序。在这种情况下,我们有一个自然的比较函数,我们希望能够使用qsort期望的内容。

因此,下面mycmpstr适当地转换传入指针,并返回使用strcmp比较字符串的结果。我们知道qsort将使用常量char指针的常量指针来调用我们的比较函数,并且我们已经投射了#39}。适当。

请记住,您正在排序指向字符数组的指针。这意味着,您不需要自己移动字符串,只需要移动指针。您可以使用strcmp来确定哪个指针应该基于它们所指向的字符串的排序。

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

int mycmpstr(const void *p, const void *q) {
    const char *const *x = p;
    const char *const *y = q;
    return strcmp(*x, *y);
}

int main(void)
{
    int i;
    const char *states[] = {
        "Florida", "Oregon", "California", "Georgia"
    };

    qsort(
        states,
        4,
        sizeof(char *),
        mycmpstr
    );

    for (i = 0; i < 4; i += 1) {
        puts(states[i]);
    }

    return 0;
}

输出:

$ clang -Wall -O1 sortex.c -o sortex
$ ./sortex
California
Florida
Georgia
Oregon