Как упорядочить аргументы командной строки в лексикографическом порядке, используя функцию? - PullRequest
0 голосов
/ 19 февраля 2019

Я работаю над программой, которая принимает аргументы командной строки и разделяет их пополам, а затем упорядочивает их в лексикографическом порядке.Например:

привет, мир!

превратится в:

он

ld!

llo

wor

У меня есть основной метод, который читает аргументы, функция, которая разделяет аргументы, и, наконец, функция, которая должна упорядочивать половинки в лексикографическом порядке.Я не могу заставить это работать должным образом из-за ошибок типа аргумента в методе lexicographicSort и несовместимого типа указателя в методе main.У меня проблемы с исправлением этих синтаксических ошибок, как именно я их исправлю?Кроме того, есть ли здесь что-нибудь, что могло бы вызвать логические ошибки?Это то, что я до сих пор:

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

int splitString(char arg[], int n)
{
   int len = strlen(arg);
   int len1 = len/2;
   int len2 = len - len1; // Compensate for possible odd length
   char *s1 = malloc(len1 + 1); // one for the null terminator
   memcpy(s1, arg, len1);
   s1[len1] = '\0';
   char *s2 = malloc(len2 + 1); // one for the null terminator
   memcpy(s2, arg + len1, len2);
   s2[len2] = '\0';
   printf("%s\n", s1);
   printf("%s\n", s2);
   free(s1);
   free(s2);

   return 0;
}

int lexicographicalSort(char *arg[], int n) 
{
    char temp[50];

    for(int i = 0; i < n; ++i)
        scanf("%s[^\n]",arg[i]); 

    for(int i = 0; i < n - 1; ++i)
        for(int j = i + 1; j < n ; ++j)
        {
            if(strcmp(arg[i], arg[j]) > 0)
            {
                strcpy(temp, arg[i]);
                strcpy(arg[i], arg[j]);
                strcpy(arg[j], temp);
            }
        }

    for(int i = 0; i < n; ++i)
    {
        puts(arg[i]);
    }

    return 0;   
}

int main(int argc, char *argv[])
{
    if (argc > 1) 
    {
        for (int i = 1; i < argc; i++) 
        {
            int j = 1;
            int k = strlen(argv[i]);

            splitString(argv[i], j);
            lexicographicalSort(argv[i], j);

        }
    }

}

Ответы [ 2 ]

0 голосов
/ 21 февраля 2019

После разделения строки C требуется один дополнительный char для хранения дополнительного нулевого терминатора.Есть один ответ, который обходит это, сохраняя длину.Для полноты, это ближе к вашему первоначальному замыслу: выделить достаточно места для копирования аргументов программы.Возможно, он работает медленнее, но можно свободно использовать строки в другом месте программы.

#include <stdlib.h> /* malloc free EXIT qsort */
#include <stdio.h>  /* fprintf */
#include <string.h> /* strlen memcpy */
#include <errno.h>  /* errno */

static int strcompare(const void *a, const void *b) {
    const char *a_str = *(const char *const*)a, *b_str = *(const char *const*)b;
    return strcmp(a_str, b_str);
}

int main(int argc, char **argv) {
    char *spacev = 0, **listv = 0;
    size_t spacec = 0, listc = 0;
    int is_done = 0;
    do { /* "Try." */
        int i;
        char *sv;
        size_t j;
        /* This requires argc > 1. */
        if(argc <= 1) { errno = EDOM; break; }
        /* Allocate maximum space. */
        for(i = 1; i < argc; i++) spacec += strlen(argv[i]) + 2;
        if(!(spacev = malloc(spacec)) || !(listv = malloc(argc * 2))) break;
        sv = spacev;
        /* Copy and split the arguments. */
        for(i = 1; i < argc; i++) {
            const char *const word = argv[i];
            const size_t word_len = strlen(word),
                w0_len = word_len / 2, w1_len = word_len - w0_len;
            if(w0_len) {
                listv[listc++] = sv;
                memcpy(sv, word, w0_len);
                sv += w0_len;
                *(sv++) = '\0';
            }
            if(w1_len) {
                listv[listc++] = sv;
                memcpy(sv, word + w0_len, w1_len);
                sv += w1_len;
                *(sv++) = '\0';
            }
        }
        /* Sort. */
        qsort(listv, listc, sizeof listv, &strcompare);
        for(j = 0; j < listc; j++) printf("%s\n", listv[j]);
        is_done = 1;
    } while(0); if(!is_done) {
        perror("split");
    } {
        free(spacev);
        free(listv);
    }
    return is_done ? EXIT_SUCCESS : EXIT_FAILURE;
}

Это проще, чем ваш оригинал;вместо того, чтобы выделять каждую строку по отдельности, она подсчитывает максимальное количество необходимых char с (плюс два для двух нулевых терминаторов) и выделяет блок сразу (space). Указатели на новый список также должны выделяться,максимум 2 * argc.После того, как вы скопируете и измените список аргументов, у вас есть фактический массив строк, которые можно qsort.

0 голосов
/ 20 февраля 2019

Основная схема проста.Создайте массив кортежей {start_pointer, length}.Занимайтесь программированием аргументов, чтобы разбить их.Заполните массив соответствующим образом.Выполните сортировку с помощью qsort или любого другого выбора по вашему выбору.

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

char *s = "hello, world! . hello.....";
char *pc;
int i, n, nargs;

struct pp{
 char *p;
 int   l;
};

struct pp args[10], hargs[20];
struct pp *pargs;

int cmp(const void * v0, const void * v1) {
   struct pp *pv0 = v0, *pv1 = v1;
   return strncmp(pv0->p, pv1->p, pv0->l);
}

int main(void)
{
 for(pc = s, i = 0; *pc; ++i){
  sscanf(pc, "%*[^ ]%n", &n);
  if(n > 0){
   args[i].p = pc;
   args[i].l = n;
  }
  for(pc += n, n = 0; isspace(*pc); ++pc);
 }
 for(nargs = i, i = 0; i < nargs; ++i)
  printf("%d arg is: %.*s\n", i, args[i].l, args[i].p);
 putchar('\n');
 for(i = 0, pargs = hargs; i < nargs; ++i){
  if(args[i].l == 1){
   pargs->p = args[i].p;
   pargs->l = 1;
   pargs = pargs + 1;
  }else {
   pargs->p = args[i].p;
   pargs->l = args[i].l / 2;
   pargs = pargs + 1;
   pargs->p = args[i].p + args[i].l / 2;
   pargs->l = args[i].l - args[i].l / 2;
   pargs = pargs + 1;
  }
 }
 putchar('\n');
 for(nargs = pargs - hargs, i = 0; i < nargs; ++i)
  printf("%d arg is: %.*s\n", i, hargs[i].l, hargs[i].p);
 qsort(hargs, nargs, sizeof(struct pp), cmp);
 putchar('\n');
 for(i = 0; i < nargs; ++i)
  printf("%d arg is: %.*s\n", i, hargs[i].l, hargs[i].p);

 return 0;
}

https://rextester.com/GSH22767

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...