Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 使用fgets对字符串数组进行排序_C_Arrays - Fatal编程技术网

C 使用fgets对字符串数组进行排序

C 使用fgets对字符串数组进行排序,c,arrays,C,Arrays,我试图创建一个程序,它接受一个整数值,然后决定可以输入的字符串的数量,这是循环两次。一旦输入了两组字符串,我的程序就应该对它们进行排序,并根据它们的长度降序输出它们。当我输出结果时,我没有得到我应该得到的结果 #include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { int i, num_of_str; //int j; //int a;

我试图创建一个程序,它接受一个整数值,然后决定可以输入的字符串的数量,这是循环两次。一旦输入了两组字符串,我的程序就应该对它们进行排序,并根据它们的长度降序输出它们。当我输出结果时,我没有得到我应该得到的结果

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

int main(void)
{

    int i, num_of_str;
    //int j;
    //int a;
    //int n;
    char input[100];

    scanf("%d", &num_of_str);

    char** strings = malloc(num_of_str * sizeof(char*));

    for (i = 0; i < num_of_str; i++) {

        fgets(input, 100, stdin);
        strings[i] = malloc(strlen(input) * sizeof(char*));
        strcpy(strings[i], input);
    }

    scanf("%d", &num_of_str);

    for (i = 0; i < num_of_str; i++) {

        fgets(input, 100, stdin);
        strings[i] = malloc(strlen(input) * sizeof(char*));
        strcpy(strings[i], input);
    }

    int a;
    int b;
    char* temp;

    for (a = 0; a < num_of_str; a++) {
        for (b = a + 1; b < num_of_str; b++) {
            if (strlen(strings[a]) < (strlen(strings[b]))) {

                temp = strings[a];
                strings[a] = strings[b];
                strings[b] = temp;
            }
        }
    }

    for (a = 0; a < num_of_str; a++) {
        printf("%s\n", strings[a]);
    }
    return EXIT_SUCCESS;
}
#包括
#包括
#包括
内部主(空)
{
int i,n个字符的数量;
//int j;
//INTA;
//int n;
字符输入[100];
scanf(“%d”、&num\u of\u str);
char**strings=malloc(num_of_str*sizeof(char*));
对于(i=0;i
我不知道你为什么要买两套,有一件事我想说的是你正在使用 用于获取字符串数量的scanf和字符串的fgets。因此,您可能会丢失第一个条目
因此。

以下是代码中的一些问题:

  • 未检查返回指针
    malloc()
    。需要检查它,因为如果失败,它的
    void*
    指针可以返回
    NULL
    。您可以像这样检查
    malloc()

    ptr = malloc(......);
    if (ptr == NULL) {
        /* handle error */
    }
    
  • 未检查
    scanf()
    的返回值。这需要检查是否找到
    numstr
    的1个整数值。您可以通过以下方式进行验证:

    if (scanf("%d", &numstr) != 1) {
        /* handle error */
    }
    
  • 字符串[i]
    未正确分配。由于这是一个
    char*
    指针,因此需要分配大量
    char
    字节,而不是
    char*
    指针。您还需要将
    +1
    添加到分配中,以确保它们有足够的空间容纳空终止符
    \0
    。因此,不是:

    strings[i] = malloc(strlen(input) * sizeof(char*));
    
    你可以做:

    strings[i] = malloc(strlen(input)+1);
    
    注意:
    sizeof(char)
    始终为1,因此无需在此处包含它

  • 您的代码不会在第二个
    numstr
    上更新
    **strings
    。如果
    numstr
    最终成为一个更大的字符串,您将访问超出
    **字符串限制的字符串,这将导致问题。您可能需要使用此处来调整内存块的大小。一种方法是跟踪第一个
    numstr
    ,然后对照第二个
    numstr
    ,如果它们不同,调整
    字符串的大小。
    以下是一个例子:

    prev_numstr = numstr;
    
    printf("Enter number of strings for set 2:\n");
    if (scanf("%zu ", &numstr) != 1) {
        /* handle exit */
    }
    
    if (numstr != prev_numstr) {
        void *temp = realloc(strings, numstr * sizeof(*strings));
        if (temp == NULL) {
            /* handle exit */
        }
        strings = temp;
    } 
    
  • 由于
    scanf()
    在输入缓冲区中留下一个
    \n
    字符,因此需要在调用
    fgets()
    之前清除该字符。您只需通过执行
    scanf(“%d”和&num\u of_str)
    添加一个空格,这将消耗缓冲区中剩余的所有空白

  • 必须选中
    fgets()
    ,因为在读取行失败时,它可能返回
    NULL
    指针。它还会在缓冲区的末尾追加一个
    \n
    字符,因此您可能需要在某个时候删除此换行符

  • 使用
    malloc()
    realloc()
    进行的任何堆分配必须在最后使用取消分配

  • 由于
    void*malloc(size\u t size)
    需要
    size\u t
    ,因此最好在此处使用
    size\u t
    变量

由于您的代码在排序方面没有问题,下面是一些使用以下要点的示例代码:

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

#define LINESIZE 100

int main(void) {
    char input[LINESIZE];
    size_t numstr, prev_numstr, slen;
    void *temp = NULL;

    printf("Enter number of strings for set 1:\n");
    if (scanf("%zu ", &numstr) != 1 || numstr < 1) {
        fprintf(stderr, "Invalid value\n");
        exit(EXIT_FAILURE);
    }

    char **strings = malloc(numstr * sizeof(*strings));
    if (strings == NULL) {
        fprintf(stderr, "Cannot allocate %zu strings\n", numstr);
        exit(EXIT_FAILURE);
    }

    /* Set 1 */
    for (size_t i = 0; i < numstr; i++) {
        if (fgets(input, LINESIZE, stdin) != NULL) {
            slen = strlen(input);

            /* removes newline */
            if (slen > 0 && input[slen-1] == '\n') {
                input[slen-1] = '\0';
            }

            strings[i] = malloc(strlen(input)+1);
            if (strings[i] == NULL) {
                fprintf(stderr, "Cannot allocate %zu bytes for string\n", strlen(input)+1);
                exit(EXIT_FAILURE);
            }

            strcpy(strings[i], input);
        }       
    }

    /* keeps track of previous number of strings */
    prev_numstr = numstr;

    printf("Enter number of strings for set 2:\n");
    if (scanf("%zu ", &numstr) != 1 || numstr < 1) {
        fprintf(stderr, "Invalid value\n");
        exit(EXIT_FAILURE);
    }

    /* only enters if size is different */
    if (numstr != prev_numstr) {
        temp = realloc(strings, numstr * sizeof(*strings));
        if (temp == NULL) {
            fprintf(stderr, "Cannot reallocate %zu spaces\n", numstr);
            exit(EXIT_FAILURE);
        }
        /* perhaps temp could could freed here */
        strings = temp;
    } 

    /* Set 2 */
    for (size_t i = 0; i < numstr; i++) {
        if (fgets(input, LINESIZE, stdin) != NULL) {
            slen = strlen(input);
            if (slen > 0 && input[slen-1] == '\n') {
                input[slen-1] = '\0';
            }

            strings[i] = malloc(strlen(input)+1);
            if (strings[i] == NULL) {
                fprintf(stderr, "Cannot allocate %zu bytes for string\n", strlen(input)+1);
                exit(EXIT_FAILURE);
            }

            strcpy(strings[i], input);
        }       
    }

    /* printing and freeing strings */
    for (size_t i = 0; i < numstr; i++) {
        printf("%s\n", strings[i]);
        free(strings[i]);
        strings[i] = NULL;
    }

    /* freeing double pointer 'strings' itself */
    free(strings);
    strings = NULL;

    exit(EXIT_SUCCESS);
}
#包括
#包括
#包括
#定义线宽100
内部主(空){
字符输入[行大小];
尺寸numstr,上一个numstr,slen;
void*temp=NULL;
printf(“输入集合1的字符串数:\n”);
如果(scanf(“%zu”,&numstr)!=1 | | numstr<1){
fprintf(stderr,“无效值\n”);
退出(退出失败);
}
字符**字符串=malloc(numstr*sizeof(*字符串));
if(strings==NULL){
fprintf(stderr,“无法分配%zu字符串”,numstr);
退出(退出失败);
}
/*第1组*/
对于(大小i=0;i0&&input[slen-1]='\n'){
输入[slen-1]='\0';
}
字符串[i]=malloc(strlen(输入)+1);
if(字符串[i]==NULL){
fprintf(stderr,“无法为字符串\n分配%zu字节”,strlen(输入)+1);
退出(退出失败);
}
strcpy(字符串[i],输入);
}       
}
/*跟踪以前的字符串数*/
prev_numstr=numstr;
printf(“输入集合2的字符串数:\n”);
如果(scanf(“%zu”,&numstr)!=1 | | numstr<1){
fprintf(stderr,“无效值\n”);
退出(退出失败);
}
/*仅在大小不同时输入*/
如果(numstr!=上一个numstr){
temp=realloc(字符串,numstr*sizeof(*字符串));
if(temp==NULL){
fprintf(stderr,“无法重新分配%zu空间”,numstr);
退出(退出失败);
}
/*也许临时工可以在这里释放*/
字符串=温度;
} 
/*第2组*/
对于(大小i=0;i0&&input[slen-1]='\n'){
输入[slen-1]='\0';
}