
фикс вариант 1
Код: Выделить всё
#include <stdio.h>
#include <string.h>
#define MAXLINES 5000 /* максимальное число строк */
char *lineptr[MAXLINES]; /* указатели на строки текста */
int readlines(char *lineptr[], int nlines);
void writelines(char *lineptr[], int nlines);
void qsort_(void *lineptr[], int left, int right,
int(*comp)(void *, void *));
int numcp(const char *, const char *);
/*сортировка строк из входного потока*/
main(int argc, char *argv[])
{
int nlines; /*кол-во считанных строк*/
int numeric = 0; /*1 если числовая сортировка*/
if (argc > 1 && strcmp(argv[1], "-n") == 0)
numeric = 1;
if ((nlines = readlines(lineptr, MAXLINES)) >= 0) {
qsort_((void **) lineptr, 0, nlines-1,
(int (*)(void *, void *))(numeric ? numcp : strcmp));
writelines(lineptr, nlines);
return 0;
}else{
printf("input too big to sort\n");
return 1;
}
}
/*qsort_: сортировка v[left] ... v[right] в порядке возрастания*/
void qsort_(void *v[], int left, int right,
int (*comp)(void *, void *))
{
int i, last;
void swap(void *v[], int i, int j);
if (left >= right) /*ничего не делать, если в массиве*/
return; /*меньше двух элементов*/
swap(v, left, (left + right) / 2);
last = left;
for (i = left+1; i<= right; i++)
if((*comp)(v[i], v[left]) < 0)
swap(v, ++last, i);
swap(v, left, last);
qsort_(v, left, last-1, comp);
qsort_(v, last+1, right, comp);
}
#include <stdlib.h>
/*numcp: сравнение строк s1 и s2 по числовым значениям*/
int numcp(const char *s1, const char *s2)
{
double v1, v2;
v1 = atof(s1);
v2 = atof(s2);
if (v1 < v2)
return -1;
else if (v1 > v2)
return 1;
else
return 0;
}
void swap(void *v[], int i, int j)
{
void *temp;
temp = v[i];
v[i] = v[j];
v[j] = temp;
}
#define MAXLEN 1000
int getline(char*, int);
char *alloc(int);
/*readlines: считывание строк из входного потока*/
int readlines(char *lineptr[], int maxlines)
{
int len, nlines;
char *p, line[MAXLEN];
nlines = 0;
while ((len = getline(line, MAXLEN)) >0)
if(nlines >= maxlines || (p = alloc(len)) == NULL)
return -1;
else {
line[len-1] = '\0';/*удаление конца строки*/
strcpy(p, line);
lineptr[nlines++] = p;
}
return nlines;
}
/*writelines: вывод в выходной поток*/
void writelines(char *lineptr[], int nlines)
{
int i;
for(i = 0; i< nlines; i++)
printf("%s\n", lineptr[i]);
}
/*getline: считывает строку в s, возвращает её длину*/
int getline(char s[], int lim)
{
int c, i;
for (i = 0; i<lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
s[i] = c;
if (c == '\n') {
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
#define ALLOCSIZE 10000 /*объём имеющейся памяти*/
static char allocbuf[ALLOCSIZE]; /*буфер памяти для alloc*/
static char *allocp = allocbuf; /*Следующая свободная позиция*/
char *alloc(int n) /*возвращает указатель на n символов*/
{
if (allocbuf + ALLOCSIZE - allocp >= n) { /*есть место*/
allocp += n;
return allocp - n; /*старый p*/
} else /*недостаточно места в буфере*/
return 0;
}

фикс вариант 2
Код: Выделить всё
#include <stdio.h>
#include <string.h>
#define MAXLINES 5000 /* максимальное число строк */
char *lineptr[MAXLINES]; /* указатели на строки текста */
int readlines(char *lineptr[], int nlines);
void writelines(char *lineptr[], int nlines);
void qsort_(void *lineptr[], int left, int right,
int(*comp)(const void *, const void *));
int numcp(const char *, const char *);
/*сортировка строк из входного потока*/
main(int argc, char *argv[])
{
int nlines; /*кол-во считанных строк*/
int numeric = 0; /*1 если числовая сортировка*/
if (argc > 1 && strcmp(argv[1], "-n") == 0)
numeric = 1;
if ((nlines = readlines(lineptr, MAXLINES)) >= 0) {
qsort_((void **) lineptr, 0, nlines-1,
(int (*)(const void *, const void *))(numeric ? numcp : strcmp));
writelines(lineptr, nlines);
return 0;
}else{
printf("input too big to sort\n");
return 1;
}
}
/*qsort_: сортировка v[left] ... v[right] в порядке возрастания*/
void qsort_(void *v[], int left, int right,
int (*comp)(const void *, const void *))
{
int i, last;
void swap(void *v[], int i, int j);
if (left >= right) /*ничего не делать, если в массиве*/
return; /*меньше двух элементов*/
swap(v, left, (left + right) / 2);
last = left;
for (i = left+1; i<= right; i++)
if((*comp)(v[i], v[left]) < 0)
swap(v, ++last, i);
swap(v, left, last);
qsort_(v, left, last-1, comp);
qsort_(v, last+1, right, comp);
}
#include <stdlib.h>
/*numcp: сравнение строк s1 и s2 по числовым значениям*/
int numcp(const char *s1, const char *s2)
{
double v1, v2;
v1 = atof(s1);
v2 = atof(s2);
if (v1 < v2)
return -1;
else if (v1 > v2)
return 1;
else
return 0;
}
void swap(void *v[], int i, int j)
{
void *temp;
temp = v[i];
v[i] = v[j];
v[j] = temp;
}
#define MAXLEN 1000
int getline(char*, int);
char *alloc(int);
/*readlines: считывание строк из входного потока*/
int readlines(char *lineptr[], int maxlines)
{
int len, nlines;
char *p, line[MAXLEN];
nlines = 0;
while ((len = getline(line, MAXLEN)) >0)
if(nlines >= maxlines || (p = alloc(len)) == NULL)
return -1;
else {
line[len-1] = '\0';/*удаление конца строки*/
strcpy(p, line);
lineptr[nlines++] = p;
}
return nlines;
}
/*writelines: вывод в выходной поток*/
void writelines(char *lineptr[], int nlines)
{
int i;
for(i = 0; i< nlines; i++)
printf("%s\n", lineptr[i]);
}
/*getline: считывает строку в s, возвращает её длину*/
int getline(char s[], int lim)
{
int c, i;
for (i = 0; i<lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
s[i] = c;
if (c == '\n') {
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
#define ALLOCSIZE 10000 /*объём имеющейся памяти*/
static char allocbuf[ALLOCSIZE]; /*буфер памяти для alloc*/
static char *allocp = allocbuf; /*Следующая свободная позиция*/
char *alloc(int n) /*возвращает указатель на n символов*/
{
if (allocbuf + ALLOCSIZE - allocp >= n) { /*есть место*/
allocp += n;
return allocp - n; /*старый p*/
} else /*недостаточно места в буфере*/
return 0;
}

фикс вариант от MOZGIII
Код: Выделить всё
#include <stdio.h>
#include <string.h>
#define MAXLINES 5000 /* максимальное число строк */
char *lineptr[MAXLINES]; /* указатели на строки текста */
int readlines(char *lineptr[], int nlines);
void writelines(char *lineptr[], int nlines);
void qsort_(void *lineptr[], int left, int right,
int(*comp)(void *, void *));
int numcp(char *, char *);
/*сортировка строк из входного потока*/
main(int argc, char *argv[])
{
int nlines; /*кол-во считанных строк*/
int numeric = 0; /*1 если числовая сортировка*/
if (argc > 1 && strcmp(argv[1], "-n") == 0)
numeric = 1;
if ((nlines = readlines(lineptr, MAXLINES)) >= 0) {
qsort_((void **) lineptr, 0, nlines-1,
numeric ? (int (*)(void *, void *))numcp : (int (*)(void *, void *))strcmp);
writelines(lineptr, nlines);
return 0;
}else{
printf("input too big to sort\n");
return 1;
}
}
/*qsort_: сортировка v[left] ... v[right] в порядке возрастания*/
void qsort_(void *v[], int left, int right,
int (*comp)(void *, void *))
{
int i, last;
void swap(void *v[], int i, int j);
if (left >= right) /*ничего не делать, если в массиве*/
return; /*меньше двух элементов*/
swap(v, left, (left + right) / 2);
last = left;
for (i = left+1; i<= right; i++)
if((*comp)(v[i], v[left]) < 0)
swap(v, ++last, i);
swap(v, left, last);
qsort_(v, left, last-1, comp);
qsort_(v, last+1, right, comp);
}
#include <stdlib.h>
/*numcp: сравнение строк s1 и s2 по числовым значениям*/
int numcp(char *s1, char *s2)
{
double v1, v2;
v1 = atof(s1);
v2 = atof(s2);
if (v1 < v2)
return -1;
else if (v1 > v2)
return 1;
else
return 0;
}
void swap(void *v[], int i, int j)
{
void *temp;
temp = v[i];
v[i] = v[j];
v[j] = temp;
}
#define MAXLEN 1000
int getline(char*, int);
char *alloc(int);
/*readlines: считывание строк из входного потока*/
int readlines(char *lineptr[], int maxlines)
{
int len, nlines;
char *p, line[MAXLEN];
nlines = 0;
while ((len = getline(line, MAXLEN)) >0)
if(nlines >= maxlines || (p = alloc(len)) == NULL)
return -1;
else {
line[len-1] = '\0';/*удаление конца строки*/
strcpy(p, line);
lineptr[nlines++] = p;
}
return nlines;
}
/*writelines: вывод в выходной поток*/
void writelines(char *lineptr[], int nlines)
{
int i;
for(i = 0; i< nlines; i++)
printf("%s\n", lineptr[i]);
}
/*getline: считывает строку в s, возвращает её длину*/
int getline(char s[], int lim)
{
int c, i;
for (i = 0; i<lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
s[i] = c;
if (c == '\n') {
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
#define ALLOCSIZE 10000 /*объём имеющейся памяти*/
static char allocbuf[ALLOCSIZE]; /*буфер памяти для alloc*/
static char *allocp = allocbuf; /*Следующая свободная позиция*/
char *alloc(int n) /*возвращает указатель на n символов*/
{
if (allocbuf + ALLOCSIZE - allocp >= n) { /*есть место*/
allocp += n;
return allocp - n; /*старый p*/
} else /*недостаточно места в буфере*/
return 0;
}
Pr0Ger,
MOZGIII, спасибо, теперь у меня есть 3 варианта, в которых компилятор не ругается, 2-й более-менее понятен.
Не ясно, почему, если функции qsort_(); в 4-м аргументе нужен указатель comp такого вида int(*comp)(void *, void *), и мы приводим его к этому виду, но
если одна из приводимых функций strcmp(
const char *,
const char *); а другая numcp(char *, char *); то
компилятор ругается,
а
если же обе таковы strcmp(
const char *,
const char *); numcp(
const char *,
const char *); то
компилится нормально(1-й вариант).
MOZGIII
вообще не знает что эта штука будет возвращать - она не типизированная
в исходном варианте её пытаются привести к нужному типу (int (*)(void *, void *)), но почему-то это компилятор считает неправильным
Не пойму разницу [с точки зрения компилятора]
Код: Выделить всё
(int (*)(void *, void *))(numeric ? numcp : strcmp) //исходный вар-т, 4-й аргумент: преобразовать к нужному типу указатель, полученный после условного оператора : ?
numeric ? (int (*)(void *, void *))numcp : (int (*)(void *, void *))strcmp //в 4-й аргумент направить уже преобразованный к нужному типу ук-ль
по смыслу вроде одинаковые вещи, в 1-м случае результат, получившийся после действия условного оператора приводится к нужному типу, а во 2-м аргументы условного оператора преобразуются к нужному типу.