【问题标题】:I'm trying to use strcmp() to sort a string array in C我正在尝试使用 strcmp() 对 C 中的字符串数组进行排序
【发布时间】:2025-12-12 01:00:01
【问题描述】:

我有一个让我头疼的家庭作业挑战。问题是:

构建一个使用字符串数组存储以下名称的程序:
*“佛罗里达”
*“俄勒冈”
*“加利福尼亚”
*“格鲁吉亚”
使用前面的字符串数组,编写您自己的 sort() 函数,使用 strcmp() 函数按字母顺序显示每个州的名称。

这是给我带来问题的代码:

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

//function prototype
int sort(char *, char *);

int main() 
{
    char *strStates[] = {"Florida", "Oregon", "California", "Georgia"};
    char *strSorted[] = {0};
    int x;

    printf("\nThe list of states before being sorted in alphabetical order: ");

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

    sort(strStates[x], strSorted[x]);

    printf("\nThe list of states sorted alphabetically are: ");

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

    return 0;

}//end main

//function definition
int sort(char *string1, char *string2)
{
    int x;
    int y;

    for (x = 0; x < 3; x++) 
    {
        for (y = 1; y < 4; y++) 
        {
            if ((strcmp(string1[x], string1[y])) > 0) 
            {
                strcpy(string2, string1[x]);
                strcpy(string1[x], string1[y]);
                strcpy(string[y], string2);
            }//end if

       }//end inner for loop

    }//end outer for loop

}//end sort()

我在编译时遇到了一系列错误:

Chapter_8_Challenge_3.c:45:16: warning: incompatible integer to pointer conversion passing 'char' to parameter of type 'const char *'; take the address with & [-Wint-conversion]
                    if ((strcmp(string1[x], string1[y])) > 0) 
                                ^~~~~~~~~~
                                &  
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/string.h:77:25: note: passing argument to parameter here
int      strcmp(const char *, const char *);
                        ^  
Chapter_8_Challenge_3.c:45:28: warning: incompatible integer to pointer conversion passing 'char' to parameter of type 'const char *'; take the address with & [-Wint-conversion]
                    if ((strcmp(string1[x], string1[y])) > 0) 
                                            ^~~~~~~~~~
                                            &  
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/string.h:77:39: note: passing argument to parameter here
int      strcmp(const char *, const char *);
                                      ^  
Chapter_8_Challenge_3.c:47:21: warning: incompatible integer to pointer conversion passing 'char' to parameter of type 'const char *'; take the address with & [-Wint-conversion]
                            strcpy(string2, string1[x]);
                                            ^~~~~~~~~~
                                            &  
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/secure/_string.h:83:33: note: expanded from macro 'strcpy'
  __builtin___strcpy_chk (dest, src, __darwin_obsz (dest))
                            ^  
Chapter_8_Challenge_3.c:48:12: warning: incompatible integer to pointer conversion passing 'char' to parameter of type 'const void *' [-Wint-conversion]
                            strcpy(string1[x], string1[y]);
                                   ^~~~~~~~~~  
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/secure/_string.h:83:53: note: expanded from macro 'strcpy'
  __builtin___strcpy_chk (dest, src, __darwin_obsz (dest))
                                                ^  
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/secure/_common.h:39:54: note: expanded from macro '__darwin_obsz'
#define __darwin_obsz(object) __builtin_object_size (object, _USE_FORTIFY_LEVEL > 1 ? 1 : 0)
                                                 ^  
Chapter_8_Challenge_3.c:48:12: warning: incompatible integer to pointer conversion passing 'char' to parameter of type 'char *'; take the address with & [-Wint-conversion]
                            strcpy(string1[x], string1[y]);
                                   ^~~~~~~~~~
                                   &  
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/secure/_string.h:83:27: note: expanded from macro 'strcpy'
  __builtin___strcpy_chk (dest, src, __darwin_obsz (dest))
                      ^  
Chapter_8_Challenge_3.c:48:24: warning: incompatible integer to pointer conversion passing 'char' to parameter of type 'const char *'; take the address with & [-Wint-conversion]
                            strcpy(string1[x], string1[y]);
                                               ^~~~~~~~~~
                                               &  
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/secure/_string.h:83:33: note: expanded from macro 'strcpy'
  __builtin___strcpy_chk (dest, src, __darwin_obsz (dest))
                            ^  
Chapter_8_Challenge_3.c:49:12: error: use of undeclared identifier 'string'; did you mean 'string1'?
                            strcpy(string[y], string2);
                                   ^~~~~~
                                   string1  
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/secure/_string.h:83:27: note: expanded from macro 'strcpy'
  __builtin___strcpy_chk (dest, src, __darwin_obsz (dest))
                      ^  
Chapter_8_Challenge_3.c:36:16: note: 'string1' declared here
int sort(char *string1, char *string2)
           ^  
Chapter_8_Challenge_3.c:49:12: error: use of undeclared identifier 'string'
                            strcpy(string[y], string2);
                                   ^  
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/secure/_string.h:83:53: note: expanded from macro 'strcpy'
  __builtin___strcpy_chk (dest, src, __darwin_obsz (dest))
                                                ^  
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/secure/_common.h:39:54: note: expanded from macro '__darwin_obsz'
#define __darwin_obsz(object) __builtin_object_size (object, _USE_FORTIFY_LEVEL > 1 ? 1 : 0)  
                                                 ^
6 warnings and 2 errors generated.

【问题讨论】:

  • 究竟有什么问题?
  • 你有什么问题?没有人会为你做作业。
  • 比如?编辑您的主要帖子,包括您尝试过的内容以及遇到的问题。
  • “我遇到了一系列错误”没有什么价值。发布错误以及与该错误相关的行。
  • 现在看看你的帖子。它看起来像您的编译器输出吗?你能说出一条错误消息在哪里结束,另一条从哪里开始吗?

标签: c arrays string strcmp


【解决方案1】:

1. 在你的函数sort -

if((strcmp(string1[x],string1[y]))>0) //string1[x] is of type char-Wrong argument to strcmp 
        {
            strcpy(string2, string1[x]);          // same problem as aboce for all 
            strcpy(string1[x], string1[y]);
            strcpy(string[y], string2);
        }//end if 

这个 string1 已经是 char * 并且 string1[x] 将是 char 类型。所以这会调用未定义的行为

2.main -

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

sort(strStates[x], strSorted[x]);

也许您打算将 char 指针数组 (strStates) 作为第一个参数,将 (strSorted) 作为第二个参数。那么上面sort中的问题也就解决了。

3. 最后你运行int sort() 没有return 任何东西,所以你又得到了自己UB

注意 - 您得到的错误是因为将 char 传递给字符串函数。

【讨论】:

    【解决方案2】:

    除了sort 函数参数的错误之外,您还应该考虑使用strcpy。您不能将一个字符串文字复制到另一个字符串文字中,因为它们是只读的。

    你真的需要复制字符串吗?您输入了指向字符串的指针数组。您可以只对那些指针进行排序,而无需触及实际的字符串。

    您可以只传递该指针数组并对其进行排序:

    void sort(char *strStates[])
    {
        int x, y;
    
        for (x = 0; x < 3; x++) 
        {
            for (y = x + 1; y < 4; y++)
            {
                if ((strcmp(strStates[x], strStates[y])) > 0) 
                {
                    char *tmp = strStates[x];
                    strStates[x] = strStates[y];
                    strStates[y] = tmp;
                }//end if
           }//end inner for loop
        }//end outer for loop
    }//end sort()
    

    可以叫sort(strStates)

    您还可以考虑将数组大小传递给该函数以避免幻数34void sort(char *strStates[], int size)

    【讨论】:

    • 感谢@OrestHera 完美运行!我想我在尝试使用另一个字符串数组将排序值复制到时让自己感到困惑。
    【解决方案3】:

    您的 sort 函数接收 2 个字符串作为参数,因此 if ((strcmp(string1[x], string1[y])) &gt; 0) 正在尝试将两个字符与 strcmp 进行比较。你的排序函数应该更像这样:

    void sort(char **unsortedStrings){
        int x;
        int y;
        for (x = 0; x < 3; x++) 
        {
            for (y = x+1; y < 4; y++) 
            {
                if ((strcmp(unsortedStrings[x], unsortedStrings[y])) > 0) 
                {
                    // There is no need to use strcpy here, just re-order the pointers
                    char *tmp = unsortedStrings[x];
                    unsortedStrings[x] = unsortedStrings[y];
                    unsortedStrings[y] = tmp;
                }//end if
    
          }//end inner for loop
    
       }//end outer for loop
    }//end sort()
    

    此外,您的排序函数说它应该返回一个 int,但没有返回任何内容。要么你返回一些东西(比如return 1,如果一切正常,或者return 0,如果失败)或者你应该将它声明为void

    【讨论】:

    • 感谢 E 先生的帮助。您帮助清除了错误,但列表没有排序。当我运行修改后的代码时,它编译如下:按字母顺序排序之前的州列表:佛罗里达州俄勒冈州加利福尼亚州乔治亚州按字母顺序排序的州列表是:加利福尼亚州俄勒冈州佛罗里达州乔治亚州
    • 没有注意到,但循环开始索引是错误的。我刚刚编辑了它,现在试试
    • 超出范围:unsortedStrings[y] for y = 4
    • 您在修复它时在 for 循环中添加了 &lt;= 是对的。我会编辑