从字符串数组中打印排序的字符串

时间:2016-03-02 16:17:20

标签: c string

我需要以下程序的帮助:

从输入的字符串数组中打印所有排序的字符串。 假设字符按字典顺序排序(也假设字符串中的唯一字符是字母)。

Example:
INPUT:
n=2
1. string: stack
2. string: exchange
OUTPUT:
No sorted strings

我在访问以下程序中的某些变量时遇到问题:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 30

char** read(int *pn);
int isSorted(char *str);
char** sortedArr(char **str,int pn);

char** read(int *pn)
{
   do
   {
       printf("n = ");
       scanf("%d",pn);
   }
   while(*pn < 1);

   char **arr;
   arr=(char **)malloc(*pn * sizeof(char *));
   int i;
   for(i=0; i<*pn;i++)
       arr[i]=(char *)malloc(MAX+1);

   for(i=0; i<*pn; i++)
   {
       printf("%d. word: ",i+1);
       scanf("%s",arr[i]);
   }

   return arr;
}

int isSorted(char *str)
{
    int i,j;
    for(i=0; i<strlen(str)-1;i++)
        for(j=i+1; j<strlen(str); j++)
            if(strcmp(str+i,str+j) > 0)
                return 1;
    return 0;
}

char** sortedArr(char **str,int pn)
{
    char **sortArr;
    sortArr=(char **)malloc(pn * sizeof(char *));

    int i;
    for(i=0; i<pn; i++)
    {
        if(isSorted(sortArr[i]))
            sortArr[i]=(char *)malloc(MAX+1);
    }

    for(i=0; i<pn; i++)
    {
        if(isSorted(sortArr[i]))
            printf("%d. word: %s",sortArr+i);
    }

    return sortArr;
}

int main()
{
    char **arr;
    char **sortArr;
    int pn;

    arr=read(&pn);

    sortArr=sortedArr(arr,pn);

    int i;
    for(i=0; i<pn; i++)
        free(arr[i]);
    free(arr);
    return 0;
}

问题是如何在函数 sortedArr()中访问变量 pn

3 个答案:

答案 0 :(得分:1)

更改sortedArr函数,以便 pn 作为参数: char ** sortedArr(char ** str,int pn)...

然后,在main()中,将sortArr = sortedArr(arr)更改为sortArr = sortedArr(arr,pn),以将值传递给函数。然后,您可以在sortedArr函数中使用 pn 值。

答案 1 :(得分:1)

一个令人头疼的问题是:

for(i=0; i<*pn;i++)
    arr[i]=(char *)malloc(strlen(arr+i)+1);

for(i=0; i<*pn; i++)
{
    printf("%d. word: ",i+1);
    scanf("%s",arr[i]);
}

您应该将两者结合起来,因为在知道word的长度之前,您无法正确分配。为谁知道strlen(arr+i)+1处的内容分配一些arr+i是没有意义的(除非arr+i恰好是 nul-terminated 字符串,未定义的行为)。当您输入输入时,您可以/应该使用一个临时缓冲区来保存输入,直到您可以验证它是您想要的。至少,测试返回scanf以确保您实际上已成功转换为您期望的输入类型。例如:

for (i = 0; i < *pn; i++)
{
    char buf[64] = "";          /* however long is sufficient for word */

    printf ("%d. word: ",i+1);

    if (scanf ("%63[^\n']%*c",buf) == 1)
        arr[i] = strdup (buf);  /* allocates/copies buf for arr[i]  */
    else {
        fprintf (stderr, "error: invalid input for word[%d].\n", i);
    }
}

注意:您在sortedArr中有类似的分配问题)

对于您的排序,您需要将pn作为参数传递给sortedArr,这样您至少知道要处理的字符串数量。为什么不让sortedArr函数调用qsort并对您在read中创建的数组进行排序,而不是循环并尝试比较相邻元素。如果要保留原始数组和已排序数组,请sortedArr调用memcpy并创建arr的副本,然后在副本上调用qsort。您需要做的就是为compare创建一个字符串比较qsort函数来比较arr或副本,例如:

/* comparison function for qsort (char **) */
int cmp_str (const void *a, const void *b)
{
    /*  The actual arguments to this function are "pointers to
        pointers to char", but strcmp(3) arguments are "pointers
        to char", hence the following cast plus dereference 

        note: to reverse sort order, swap a and b, below  */

    return strcmp (* (char * const *) a, * (char * const *) b);
}

然后您可以使用

arr(或副本)进行排序
qsort (arr, pn, sizeof *arr, cmp_str);

更容易出错,然后是一次性循环和索引尝试。试一试,如果您有疑问,请告诉我。

答案 2 :(得分:1)

您的计划有几个问题,我会尝试解决大部分问题。

让我们从// Java syntax, but similar to other languages Actions actions = new Actions(driver); WebElement elementToMoveTo = driver.findElement(...); actions.moveToElement(elementToMoveTo).perform(); 函数开始,如果您的目标是检查一个单词是否排序了所有字符,那么您不需要使用strcmp或嵌套循环。所有你需要的是这样的:

isSorted

我将打印功能与输入功能分开并复制,以便:

// check if  all the character in the string are sorted
int isSorted( char *str )
{
    int i, length = strlen(str) - 1;

    for ( i=0; i < length; i++ )
        if ( str[i] > str[i+1] )
            return 0;
    return 1;
}

有几种方法可以从stdin读取一些单词,有些方法可以在其他答案中找到。我将使用它,但你应该检查从malloc返回的所有指针:

void print( char **str, int n )
{
    int i;
    for ( i = 0; i < n; i++ ) {
        printf("word %d: %s\n", i + 1, str[i]);
    }
}

然后,我不确定你是否只想打印那些排序&#34;排序&#34;或者你实际上需要复制它们(以后打印)。我会告诉你后者:

char** read(int *pn)
{
    char buffer[BUFSIZE];

    printf("Please, enter number of words: ");
    while ( *pn < 1  && fgets(buffer, BUFSIZE, stdin) ) {
        sscanf(buffer, "%d", pn);
    }

    int i = 0, length;
    printf("\nPlease, enter the words: \n");
    char **arr = malloc(*pn * sizeof(char *));
    while ( i < *pn ) {
        // read words one line at a time
        if ( !fgets(buffer, BUFSIZE, stdin) )
            break;

        length = strlen(buffer);
        // ignore empty lines
        if ( length < 2 )
            continue;

        arr[i] = malloc(length);
        memcpy(arr[i],buffer,length);
        // add the null terminator
        arr[i][length - 1] = '\0';

        ++i;
    }
    *pn = i;
    return arr;
}

最后是main函数(以及释放已分配内存的函数):

// return an array of string containing only the sorted ones
char** sortedArr( char **str, int n, int *m)
{
    char **sortArr = NULL;
    char *sorted = calloc(n,1);
    int i;
    *m = 0;
    // first find (and count) the sorted strings
    for ( i = 0; i < n; i++ ) {
        if ( isSorted(str[i]) ) {
            // maybe you need only to print str[i] now...
            sorted[i] = 1;
            ++(*m);
        }
    }
    // then copy the sorted. I'm not sure if you need this
    int j = 0, length = 0;
    if ( *m ) {
        sortArr = malloc(*m * sizeof(char *));
        for ( i = 0; i < n; i++ ) {
            if ( !sorted[i] )
                continue;
            length = strlen(str[i]) + 1;
            sortArr[j] = malloc(length);
            memcpy(sortArr[j],str[i],length);
        }
    }
    free(sorted);
    return sortArr;
}

希望它有所帮助。告诉我是否有什么问题或者我误解了你的任务。