C中的字符串

时间:2014-01-08 16:00:59

标签: c string

我正在尝试解决一个C问题,我必须使用指针对n个字符串进行排序。

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

void sort (char *s, int n)
{
    int i,j; char aux[]="";
    for (i=1;i<=n-1;i++)
    {
        for (j=i+1;j<=n;j++) //if s[i]> s[j] switch
        {
            if (strcmp(*(s+i),*(s+j))==1)
            {
                strcpy(aux,*(s+i);
                strcpy(*(s+i),*(s+j));
                strcpy(*(s+j),*(s+i));
            }
        } 
    }

}

void show(char *s, int n)
{
    int i;
    for (i=1;i<=n;i++)
    {
        printf("%s",*(s+i));
    }
}
int main()
{
    int i,n; char *s;
    printf("give the number of strings:\n");
    scanf("%d",&n);
    s=(char*)calloc(n,sizeof(char));
    for (i=1;i<=n;i++)
    {
        printf("s[%d]= ",i);
        scanf("%s",s+i);
    }
    sort(s,n);
    show(s,n);


    return 0;
}

我收到的警告是当我使用strcmp进行比较以及使用strcpy切换*(s+i)*(s+j)值时发出的警告。

"passing argument 2 of strcmp makes pointer from integer without a cast"

4 个答案:

答案 0 :(得分:3)

  

我得到的警告是当我使用strcmp进行比较时以及当我使用strcpy来切换左*(s+i)*(s+j)值时发出的警告。

"passing argument 2 of strcmp makes pointer from integer without a cast"

strcmpstrcpy的错误论据。 strcmpstrcpy的签名是

int strcmp(char *string1, char *string2); 
char *strcpy(char *dest, const char *src)  

但是你传递的是char类型的参数。 Remove from (S + I)and *(S + J)`。它应该是

if (strcmp((s+i), (s+j))==1)
{
      strcpy(aux, (s+i));
      strcpy((s+i), (s+j));
      strcpy((s+j), (s+i));
}  

另一个问题是你没有为指针s分配内存。对于字符,您可以将其声明为

 s = malloc ( (n + 1)*sizeof(char) );  

或只是

 s = malloc ( n + 1 ); // +1 is for string terminator '\0'

答案 1 :(得分:1)

您似乎误解了strcmp()的返回值;当且仅当两个字符串参数相等时,它才是0(零)的整数。你正在测试1,它只是很少;它没有特别的意义。

考虑使用qsort()

答案 2 :(得分:1)

您为每个1字节的n个字符串分配空间。最简单的方法是假设每个字符串将小于某个设置长度,如40个字节。然后你会像这样分配内存:

s=(char*)calloc(n*(40),sizeof(char));

然后你的scanf需要修改:

scanf("%s",s+(i*40));

现在,字符串1将位于* s,字符串2将位于*(s + 40),等等。请记住,字符串以空字符(0x00)结尾,因此字符串只能包含39个字符。任何未使用的数据也将是0x00。 为排序算法做同样的s +(i * 40),比较&gt; 0,而不是== 1,strcmp,strcpy需要指针。那你应该好。

答案 3 :(得分:0)

在你的代码中存在很多错误:在变量声明,内存分配和指针使用方面。

首先请记住,您应该始终保留足够的空间来存储字符串值,并且请注意不要尝试存储长度大于保留空间的字符串。

另外你应该非常小心地管理指针(s + 1不指向第一个字符串,而是指向第二个字符串,s + n指向已分配的内存)

因此,正如其他答案所述,您应该决定字符串的最大大小,然后为它们分配适当的内存量。 然后我建议你使用指向字符串的指针,即char**来访问你的字符串并管理排序,这样代码更易读,排序更快(你不需要复制字符串,但只能切换指针)

所以你的主要功能应该是:

int main()
{
  int i, n;

  // Declare the pointer to the memory where allocate the space for the strings
  char* a;  // points to a char ( == is a string)

  // Declare the pointer to the memory where store the pointer to the strings
  char** s; // points to a char* ( == is a pointer to a string)

  printf("give the number of strings:\n");
  scanf("%d", &n);

  // Allocate the memory for n strings of maximum 40 chars + one more for the null terminator
  a=(char*)calloc(n*41, sizeof(char));

  // Allocate memory for n pointers to a string
  s=(char**)calloc(n, sizeof(char*));

  // Notice the 0-based loop
  for (i=0; i<n; i++)
  {
    s[i] = a + i*41; // set the i-th element of s to point the i*41-th char in a
    printf("s[%d]= ", i);
    scanf("%40s", s[i]); // read at least 40 characters in s[i], 
                        // otherwise it will overflow the allocated size 
                        // and could generate errors or dangerous side effects
  }

  sort(s,n);
  show(s,n);

  // Remember always to free the allocated memory
  free(s);
  free(a);

  return 0;
}

sort函数对指针数组进行排序,而不复制字符串:

void sort (char** s, int n)
{
  int i, j; 
  char* aux;

  // Notice the 0-based loop
  for (i=0; i<n; i++)
  {
    for (j=i+1; j<n; j++) //if s[i]> s[j] switch
    {
      if (strcmp(s[i], s[j])>0)
      {
        // You don't need to copy strings because you simply copy pointers
        aux = s[i];
        s[i] = s[j];
        s[j] = aux;
      }
    } 
  }
}

最后显示正确的show函数:

void show(char** s, int n)
{
  int i;

  // Notice the 0-based loop
  for (i=0; i<n; i++)
  {
    printf("%s", s[i]);
  }
}

我无法测试代码,但它应该可行

添加了其他选项

1)如果您遇到动态内存分配问题,可以使用静态分配,主要功能是:

int main()
{
  int i, n;

  // Declare an array of fixed lenght strings
  char s[100][41]; // You manage max 100 strings

  printf("give the number of strings:\n");
  scanf("%d", &n);

  // Ensure that n is less or equal maximum
  if (n>100)
  {
    printf("you'll be asked for a maximum of 100 strings\n");
    n=100;
  }

  // Notice the 0-based loop
  for (i=0; i<n; i++)
  {
    printf("s[%d]= ", i);
    scanf("%40s", s[i]); // read at least 40 characters in s[i], 
                         // otherwise it will overflow the allocated size 
                         // and could generate errors or dangerous side effects
  }

  sort(s,n);
  show(s,n);

  // You don't need to free any memory

  return 0;
}

所有其他功能保持不变。

2)然而,如果你想要内存中你需要的最大自由度,你可以为每个字符串分别为所需的大小选择一个两个分配内存,在这种情况下你的主要功能将是:

int main()
{
  int i, n;

  char buffer[1000]; // You need a buffer to read input, before known its actual size

  // Declare the pointer to the memory where store the pointer to the strings
  char** s; // points to a char* ( == is a pointer to a string)

  printf("give the number of strings:\n");
  scanf("%d", &n);

  // Allocate memory for n pointers to a string
  s=(char**)calloc(n, sizeof(char*));

  // Notice the 0-based loop
  for (i=0; i<n; i++)
  {
    printf("s[%d]= ", i);
    scanf("%999s", buffer); // read at least 999 characters in buffer, 
                            // otherwise it will overflow the allocated size 
                            // and could generate errors or dangerous side effects

    // Allocate only the memory you need to store the actual size of the string
    s[i] = (char*)calloc(strlen(buffer)+1, sizeof(char)); // Remember always 1 more char for the null terminator

    // Copy the buffer into the newly allocated string
    strcpy(s[i], buffer);
  }

  sort(s,n);
  show(s,n);

  // Remember always to free the allocated memory
  // Now you have first to free the memory allocated for each string
  for (i=0; i<n; i++)
  {
    free(s[i]);
  }

  // Then you can free the memory allocated for the array of strings
  free(s);

  return 0;
}

所有其他功能也保持不变。