2015-01-06 2 views
0

Правильно, поэтому после многих попыток я наконец получил код, который может принимать целочисленные значения из файла и сортировать их рядом с их соответствующими именами.Сортировка плавающих точек из файла в C

Например:

Пользователь file____________ Оценка файла ___________--

User1    4 
User2    6 
User3    2 
User4    3 

Моя программа имеет возможность сортировки оценка файла в порядке убывания, сохраняя при этом первый нетронутым.

Это дает:

User2    6 
User1    4 
User4    3 
User3    2 

Теперь, это не моя проблема, функции кода отлично. Однако, как расширенное назначение. баллы теперь являются плавающими точками.

Мое внутреннее мышление было: Просто, просто измените все значения целочисленных переменных на поплавки. Это работает, за исключением того, что он не сортирует их после запятой.

Вместо того, чтобы давать «немой» код, я собираюсь дать идеальный код и отметить свои изменения. .

#include <stdio.h>  /* printf */ 
#include <stdlib.h>  /* qsort */ 

struct Element 
{ 
    int userId; 
    int score; 
}; 

int ascendingSortCompareFunction (const void * a, const void * b) 
{ 
    return (((struct Element *)a)->score - ((struct Element *)b)->score); 
} 

int descendingSortCompareFunction (const void * a, const void * b) 
{ 
    return -ascendingSortCompareFunction(a, b); 
} 

void readFromFile(const char *const filename, struct Element **elements, size_t *count) 
{ 
FILE *file; 
void *auxiliary; 
int index; 
int score; 
char line[512]; 

if ((elements == NULL) || (count == NULL)) 
    return; 
*elements = NULL; 
file  = fopen("TIStotS.txt", "r"); 
if (file == NULL) 
    return; 

index = 0; 
while (fgets(line, sizeof(line), file) != NULL) 
{ 
    if (sscanf(line, "%d", &score) == 1) 
    {    //^^Changed to %f 
     auxiliary = realloc(*elements, (1 + *count) * sizeof(struct Element)); 
     if (auxiliary == NULL) 
     { 
      free(*elements); 
      fclose(file); 

      *elements = NULL; 

      return; 
     } 
     *elements     = auxiliary; 
     (*elements)[*count].userId = 1 + index; 
     (*elements)[*count].score = score; 

     *count += 1; 
     index += 1; 
    } 
} 
fclose(file); 
} 

int main() 
{ 
size_t   count; 
size_t   n; 
struct Element *elements; 
size_t   size; 

elements = NULL; 
size  = sizeof(struct Element); 
count = 0; 

readFromFile("TIStotS.txt", &elements, &count); 
if ((elements != NULL) && (count > 0)) 
{ 
    qsort(elements, count, size, descendingSortCompareFunction); 
    printf ("UserID\tScore (Descending Sort)\n"); 

    for (n = 0 ; n < count ; n++) 
    { 

    int end, loop, line; 
    char str[512]; 

    FILE *fd = fopen("PDfirstN.txt", "r"); 
    if (fd == NULL) 
    { 
     printf("Failed to open file\n"); 
     getch(); 
    } 
line=elements[n].userId; 

for(end = loop = 0;loop<line;++loop){ 
    if(0==fgets(str, sizeof(str), fd)){//include '\n' 
     end = 1;//can't input (EOF) 
     break; 
    } 
} 
if(!end) 
printf("%s",str); 
printf("%d\n",elements[n].score); 
    //^^ changed to %.2f 
fclose(fd); 


    } 
    free(elements); 
} 
getchar(); 

return 0; 
} 

Это дает код для целого сортировочного, когда я изменить все забьет переменные из% d-% е, сортирует в файле как:

4.23 
    3.75 
    3.78 
    3.23 
    2.25 

Если значения не отсортирован правильно, и только сделали их первой значащей цифры

Edit: я уже превратился Int счет в поплавковой балла и т.д., это не исправить то

+3

int score; должен быть double/float –

+0

Для другой задачи сортировки в вопросе, где вы используете командную строку 'sort', решение состоит в том, чтобы добавить больше полей в' struct', а затем написать соответствующие функции сравнения, используя 'strcmp' для строк. Кстати, вы задали этот вопрос другим пользователем? –

+0

@iharob Нет, я украл его ответ – ThatBlueJuice

ответ

4

Вам нужно также изменить йа tatypes (из переменных и полей оценки) от int s до double s

BTW, несколько компиляторов могут предупредить вас об этой ошибке (например, GCC при составлении с gcc -Wall -Wextra -g) на scanf

2

Измените тип переменной оценки на float.

struct Element 
{ 
    int userId; 
    float score; /* instead of int score; 
}; 

и здесь

int index; 
float score; /* instead of int score; */ 
char line[512]; 

и, наконец,

if (sscanf(line, "%f", &score) == 1) /* instead of if (sscanf(line, "%d", &score) == 1) */ 

И фиксируем сравнить функции

if (((struct Element *)a)->score == ((struct Element *)b)->score) 
    return 0; 
return (((struct Element *)a)->score < ((struct Element *)b)->score) ? -1 : 1 

не изменяя тип score элемента и score, переходящая в scanf, значение было усечено, делая 3.75 и 3.78 ->3 == 3 при усечении, и, следовательно, порядок сортировки, который вы наблюдали.

+0

Я сделал это. он не сортирует их неправильно – ThatBlueJuice

+1

Неправильное изменение функций сравнения для возврата поплавков. Определение функции сравнения, переданное в 'qsort()', является 'int (* compar) (const void *, const void *)' - оно должно возвращать 'int', представляющий результат сравнения. См. Http://www.cplusplus.com/reference/cstdlib/qsort/. – frasnian

+0

@frasnian, что я выбрал ... Вы абсолютно правы. –

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