2009-12-06 2 views
0

Я довольно новичок в этом, поэтому я попытался составить главный на стр. 119 (§5.11) вдоль w/его зависимостей. Мне удалось получить чистую сборку с этим:Попытка qsort на K & R «Язык программирования C»

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

#define ALLOCSIZE 10000 
#define MAXLINES 5000 
#define MAXLEN 1000 

int getline(char *, int); 
char *alloc(int); 
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 numcmp(char *, char *); 

static char allocbuf[ALLOCSIZE]; 
static char *allocp = allocbuf; 


/* getline: read a line, return length */ 
int getline(char *line, int max) 
{ 
    if (fgets(line, max, stdin) == NULL) 
     return 0; 
    else 
     return strlen(line); 
} 


char *alloc(int n) 
{ 
    if (allocbuf + ALLOCSIZE - allocp >= n) { 
     allocp += n; 
     return allocp - n; 
    } else 
     return 0; 
} 


/* readlines: read input lines */ 
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'; /* delete newline */ 
     strcpy(p, line); 
     lineptr[nlines++] = p; 
     } 
    return nlines; 
} 


/* writelines: write output lines */ 
void writelines(char *lineptr[], int nlines) 
{ 
    int i; 

    for (i = 0; i < nlines; i++) 
     printf("%s\n", lineptr[i]); 
} 


void swap(void *v[], int i, int j) 
{ 
    void *temp; 

    temp = v[i]; 
    v[i] = v[j]; 
    v[j] = temp; 
} 


/* qsort: sort v[left]...v[right] into increasing order */ 
void qsort(void *v[], int left, int right, 
      int (*comp)(void *, void *)) 
{ 
    int i, last; 
    void swap(void *v[], int, int); 

    if (left >= right) 
     right; 
    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, 1); 
    swap(v, left, last); 
    qsort(v, left, last-1, comp); 
    qsort(v, last+1, right, comp); 
} 


#include <stdlib.h> 

/* numcmp: compare s1 and s2 numerically */ 
int numcmp(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; 
} 


/* strcmp01: return <0 if s<t , 0 if s==t, >0 if s>t */ 
int strcmp01(char *s, char *t) 
{ 
    for(; *s == *t; s++, t++) 
     if(*s == '\0') 
     return 0; 
    return *s - *t; 
} 


/* sort input lines */ 
main(int argc, char *argv[]) 
{ 
    int nlines; 
    int numeric = 0; 

    if (argc > 1 && strcmp01(argv[1], "-n") == 0) 
     numeric = 1; 
    if ((nlines = readlines(lineptr, MAXLINES)) >= 0) { 
     qsort((void **) lineptr, 0, nlines-1, 
     (int (*)(void*,void*))(numeric ? numcmp : strcmp01)); 
     writelines(lineptr, nlines); 
     return 0; 
    } 
    else { 
     printf("input too big to sort\n"); 
     return 1; 
    } 
} 

Но когда я запускаю его в окне DOS (Win 7, для чего это стоит), то команда курсор проворная принимает несколько строк ввода ключа входа, и .. . И что именно? После того, как я набираю несколько строк греческого, ничего не происходит. Я просто Ctrl C, и я возвращаюсь к командной строке.

В качестве альтернативы я написал несколько строк материала в файл test.txt и попытался запустить

[DIR\]mybuild.exe <[DIR\]test.txt

Это просто кидает ошибку (появляется диалоговое окно, Win 7, что говорит «mybuild.exe перестал работать «). Он делает найти файл test.txt; это просто «остановить работу».

Что можно сделать для успешного запуска этой программы? (Я просто пытаюсь, чтобы это никогда не видела, чтобы он бежал где-то раньше.) Спасибо, всем, за вашу помощь.

ответ

0

Если вы просто пытаетесь протестировать qsort, тогда вы можете просто иметь массив строк и просто передать это с помощью своего известного тестового примера.

Если вы хотите прочитать из файла вам нужно будет использовать что-то вроде FOPEN, чтобы открыть файл:

http://msdn.microsoft.com/en-us/library/z5hh6ee9%28VS.80%29.aspx

После того, как вы откроете его, вы можете прочитать в словах с использованием Fread.

Этот пример показывает открытие, запись, чтение, закрытие файла:

http://msdn.microsoft.com/en-us/library/kt0etdcs%28VS.100%29.aspx

Я бы с просто имея статический массив, хотя, для начала, просто чтобы проверить вашу реализацию QSort.

+0

спасибо. Прежде чем я нашел <переадресацию в книге, я чувствовал, что нужно что-то вроде fopen. Угадав, что добавление этого в библиотечную функцию было бы неважно, даже если бы что-то получилось, я был и до сих пор не уверен, как помещать это в код, который я уже скопировал из книги. Я хотел бы даже жестко закодировать путь к файлу в нем, но я не уверен, в какой из них это должно быть. – user225626

+0

Вы можете просто поместить его в основное меню, таким образом, вы сможете проверить остальную часть своего кода, так как вы просто будете нормально обращаться к своим библиотечным функциям, так как у вас есть информация, которая вам нужна. –

0

Сообщите своим друзьям и близким о нашем магазине printf() s в стратегически важных местах, чтобы увидеть, что зависит от вашей программы.

Для начала попробуйте выяснить, застрял ли он внутри readlines(), qsort(), или writelines().

Итак, добавьте printf() s в main, непосредственно перед вызовом каждой из этих функций. Как только вы узнаете, какой из них застрял в компьютере, вы можете повторить этот метод на самой этой функции, возможно, отображая значение локальных переменных, чтобы помочь вам понять, что происходит.

+0

Спасибо, я думаю, что это отличная идея. Обычно я применяю этот принцип к языкам, с которыми я больше знаком (подумайте «MsgBox»). Но я не знаю, что писать внутри printf() в этой конкретной ситуации. Пример будет честно помочь. – user225626

+0

Предположим, вы знаете, что программа застряла внутри 'qsort()'. Вы заметили, что внутри qsort существует цикл 'for'. Вы также замечаете, что 'qsort()' вызывает другие функции, включая себя. Поместите 'printf (" для запуска \ n ");' перед циклом и 'printf (" для завершения \ n ");' после цикла, чтобы проверить, работает ли цикл навсегда. Если нет, попробуйте определить, какая из функций, которые вы вызываете, не возвращается. На самом деле это довольно сложная проблема, но если вы работаете над ней достаточно долго, вы найдете ответ, и чем чаще вы это сделаете, тем быстрее вы научитесь. – Artelius

+0

Спасибо. Это помогает. – user225626

3
  1. нажмите F6 или Ctrl + Z, чтобы завершить ввод в консоли.

  2. , добавив fprintf (stderr, ...) в ваш код, я обнаружил, что на самом деле у программы заканчивается стек. вы, вероятно, ошиблись.подобный

если (левый> = правый) правый;

void qsort(void *v[], int left, int right, 
      int (*comp)(void *, void *)) 
{ 
    int i, last; 
    void swap(void *v[], int, int); 

fprintf(stderr, "left %d right %d\n", left, right); 
    if (left >= right) 
     right; 
    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, 1); 
    swap(v, left, last); 
    qsort(v, left, last-1, comp); 
    qsort(v, last+1, right, comp); 
} 
+0

Инь, ничего себе, спасибо! Это потрясающе? Он работает сейчас. – user225626

+0

Еще один вопрос, по предложению Артелиуса ниже: Какая была остальная часть printf(), которую вы написали? Просто чтобы начать меня, чтобы я мог использовать эту технику в будущем. Еще раз спасибо. И Джеймсу Блэку и Артелиусу, я еще раз изучу то, что вы предложили. Спасибо всем. – user225626

+0

использовать printf() в таких местах как: после ввода: чтобы вы правильно загрузили данные в начале рекурсивной функции или каких-либо функций, которые вы не уверены ... –

0
if (left >= right) 
    right; 

Вы имели в виду

if (left >= right) 
    return; 

?

+0

Да. Инь сказала то же самое. Спасибо вам обоим. У меня есть еще один вопрос, если это не слишком много, чтобы спросить: вещь печатается, и все, что я действительно делал в конечном счете, но ... это не сортировка. Я не могу сказать этого. Он что-то делает, но это не соответствует какому-либо шаблону, который я могу распознать, в цифровом или в алфавитном порядке, по восходящему или нисходящему. (Я не могу сказать, что это тоже случайность, но это не сортировка в соответствии с классическим определением таких). – user225626

+0

Упс, я только что обнаружил, что у меня есть «1», где «i» должно было быть в функции qsort. Какое облегчение; теперь все отлично. Еще раз спасибо. – user225626

Смежные вопросы