2009-12-06 11 views
0

Je suis assez nouveau à ce sujet, donc j'ai essayé de compiler le principal à la page 119 (§5.11) le long de ses dépendances. J'ai réussi à obtenir une construction propre avec ceci:Essayer qsort sur K & R "Le langage de programmation 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; 
    } 
} 

Mais quand je le lance dans une fenêtre DOS (Windows 7 pour ce qu'il vaut la peine), l'invite de commande de curseur accepte plusieurs lignes d'entrée d'entrée clé, et .. . Et quoi exactement? Après avoir tapé quelques lignes de geek, rien ne se passe. J'ai juste Ctrl C en dehors et je suis de retour à une invite de commande.

Alternativement je compose quelques lignes de choses dans un fichier test.txt et essayé de courir

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

Cela jette juste une erreur (une victoire 7 apparaît de dialogue qui dit « mybuild.exe a cessé de fonctionner "). Il trouve le fichier test.txt; ça "arrête de fonctionner".

Que puis-je faire pour exécuter ce programme avec succès? (J'essaie juste de ne jamais l'avoir vu courir avant.) Merci à tous pour votre aide.

Répondre

0

Si vous essayez simplement de tester qsort, vous pouvez simplement avoir un tableau de chaînes, et le transmettre simplement, avec votre cas de test connu.

Si vous voulez lire à partir d'un fichier, vous devez utiliser quelque chose comme fopen pour ouvrir le fichier:

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

Une fois que vous l'ouvrez, vous pouvez lire dans les mots en utilisant fread.

Cet exemple montre l'ouverture, l'écriture, la lecture, la fermeture d'un fichier:

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

Je voudrais aller avec juste avoir un tableau statique que, pour commencer, juste pour tester votre implémentation qsort.

+0

Merci. Avant que je trouve la redirection dans le livre, je sentais quelque chose comme fopen allait devoir être employé. En supposant que l'ajout à une fonction de la bibliothèque serait un non non, même si juste pour faire quelque chose, j'étais, et je ne suis toujours pas sûr de la façon de placer cela dans le code que j'ai déjà copié du livre. Je voudrais même coder en dur un chemin de fichier dedans, mais je ne suis pas sûr dans quel snip il devrait être. – user225626

+0

Vous pouvez simplement le mettre dans le main, de cette façon vous pouvez ensuite tester le reste de votre code, comme vous appellerez alors normalement vos fonctions de bibliothèque, puisque vous avez l'information dont vous avez besoin. –

0

Ajoutez quelques printf() dans des endroits stratégiques pour voir ce que votre programme fait. Pour commencer, essayez de savoir s'il est coincé à l'intérieur readlines(), qsort(), ou writelines().

Donc, ajoutez printf() s à la main, juste avant d'appeler chacune de ces fonctions. Une fois que vous savez dans lequel l'ordinateur est bloqué, vous pouvez répéter cette technique sur cette fonction elle-même, en affichant peut-être la valeur des variables locales pour vous aider à comprendre ce qui se passe.

+0

Merci, je pense que c'est une bonne idée. J'applique généralement ce principe aux langues que je connais plus (pensez "MsgBox"). Mais je n'ai aucune idée de ce qu'il faut écrire dans printf() dans cette situation particulière. Un exemple aiderait honnêtement. – user225626

+0

Supposons que vous sachiez que le programme est bloqué dans 'qsort()'. Vous remarquez qu'il y a une boucle 'for' dans qsort. Vous remarquerez également que 'qsort()' appelle d'autres fonctions, y compris elle-même. Mettez 'printf (" pour démarrer \ n ");' avant la boucle et 'printf (" pour terminer \ n ");' après la boucle pour vérifier si la boucle est en cours d'exécution pour toujours. Si ce n'est pas le cas, essayez de déterminer laquelle des fonctions que vous appelez ne revient pas. C'est en fait un problème plutôt difficile à résoudre, mais si vous y travaillez assez longtemps, vous trouverez la réponse, et plus vous le ferez souvent, plus vite vous apprendrez. – Artelius

+0

Merci. CA aide. – user225626

3
  1. appuyez sur F6 ou Ctrl + Z pour terminer l'entrée dans une console. En ajoutant le fprintf (stderr, ...) à votre code, j'ai trouvé que le programme ne fonctionne plus en pile. vous avez probablement eu tort.comme

si (gauche> = droite) droite;

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

Yin, wow, merci! Est-ce génial? Ça fonctionne maintenant. – user225626

+0

Encore une question, selon la suggestion d'Artelius ci-dessous: Quel était le reste du printf() que vous avez écrit? Juste pour me lancer afin que je puisse utiliser cette technique dans le futur. Merci encore. Et à James Black et Artelius, j'étudierai plus loin ce que vous avez utilement suggéré. Merci a tous. – user225626

+0

utiliser printf() aux endroits comme: après l'entrée: pour vous assurer que vous chargez les données correctement au début d'une fonction récursive ou des fonctions que vous n'êtes pas sûr ... –

0
if (left >= right) 
    right; 

Vouliez-vous dire

if (left >= right) 
    return; 

?

+0

Oui. Yin a dit la même chose. Merci à vous deux. J'ai une autre question si ce n'est pas trop demander, cependant: La chose s'imprime, c'est tout ce que je voulais vraiment en dernière analyse, mais ... ça ne fonctionne pas. Je ne peux pas dire ça. Il fait quelque chose, mais ce n'est pas en accord avec n'importe quel schéma de tri que je peux reconnaître, numériquement ou par ordre alphabétique, ascendant ou descendant. (Je ne peux pas dire que ce soit aléatoire non plus, mais ce n'est pas un tri selon la définition classique). – user225626

+0

Oups, je viens de trouver que j'avais un "1" où un "i" aurait dû être dans la fonction qsort. C'est un soulagement; tout se trie parfaitement maintenant. Merci encore à tous. – user225626

Questions connexes