December SPECIAL! For a limited time only. Get 20% discount on a LIFETIME PRO account!Want more features on Pastebin? Sign Up, it's FREE!
tweet
Guest

Untitled

By: a guest on Sep 25th, 2015  |  syntax: C  |  size: 4.50 KB  |  views: 86  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print  |  QR code  |  clone
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. #define MIN(a,b) a < b ? a : b
  5. #define MAX_LINE_SIZE 256
  6.  
  7. char* from;
  8. char* to;
  9.  
  10. // Get a line up to len from file and save it into word, returning wether
  11. // anything was read
  12. int get_line(FILE* file, char* word, size_t len)
  13. {
  14.     int i = 0;
  15.     char c;
  16.     for (; i < len - 1 && (c = getc(file)) != EOF; i++ )
  17.     {
  18.         if (c != '\n')
  19.         {
  20.             // Skip carriage returns
  21.             if (c != '\r')
  22.                 word[i] = c;
  23.             else
  24.                 i -= 1;
  25.         }
  26.         else
  27.             break;
  28.     }
  29.     word[i] = '\0';
  30.     return i;
  31. }
  32.  
  33. // Move a set number of lines further down the file
  34. void forward(FILE* file, long lines)
  35. {
  36.     char temp[MAX_LINE_SIZE];
  37.     for (long i = 0; i < lines; i++)
  38.         get_line(file, temp, MAX_LINE_SIZE);
  39. }
  40.  
  41. // Get the line in file, beginning at file_pos and return the new file_pos
  42. void fget_line(FILE* file, long* file_pos, char* word, int bufsize)
  43. {
  44.     fseek(file, *file_pos, SEEK_SET);
  45.     get_line(file, word, bufsize);
  46.     *file_pos = ftell(file);
  47. }
  48.  
  49. // Count the number of lines in the file corresponding to filename
  50. long count_lines(char* filename)
  51. {
  52.     long lines = 0;
  53.     char line[MAX_LINE_SIZE];
  54.  
  55.     FILE* file = fopen(filename, "r");
  56.  
  57.     while ((get_line(file, line, MAX_LINE_SIZE)))
  58.         lines++;
  59.  
  60.     fclose(file);
  61.  
  62.     return lines;
  63. }
  64.  
  65. int main(int argc, char** argv)
  66. {
  67.     if (argc == 2)
  68.     {
  69.         // Create the file to use alongside the original one
  70.         char swap_name[strlen(argv[1]) + 6];
  71.         strcpy(swap_name, argv[1]);
  72.         strcat(swap_name, ".swap");
  73.  
  74.         from = argv[1];
  75.         to = swap_name;
  76.  
  77.         long total_len = count_lines(from);
  78.  
  79.         for (long sub_len = 1; sub_len < total_len; sub_len *= 2)
  80.         {
  81.             FILE* from_file_a = fopen(from, "r");
  82.  
  83.             FILE* from_file_b = fopen(from, "r");
  84.             forward(from_file_b, sub_len);
  85.  
  86.             FILE* to_file = fopen(to, "w");
  87.  
  88.             for (long remaining_len = total_len; remaining_len > 0; remaining_len -= sub_len * 2)
  89.             {
  90.                 if (remaining_len > sub_len)
  91.                 {
  92.                     long a_pos = 0;
  93.                     long b_pos = 0;
  94.  
  95.                     long a_len = sub_len;
  96.                     long b_len = MIN(sub_len, remaining_len - sub_len);
  97.  
  98.                     char a_val[MAX_LINE_SIZE];
  99.                     char b_val[MAX_LINE_SIZE];
  100.  
  101.                     get_line(from_file_a, a_val, MAX_LINE_SIZE);
  102.                     get_line (from_file_b, b_val, MAX_LINE_SIZE);
  103.  
  104.                     for (int cycles = 0; cycles < a_len + b_len; cycles++)
  105.                     {
  106.                         if (a_pos == a_len || strcmp(a_val, b_val) > 0)
  107.                         {
  108.                             b_pos++;
  109.                             fprintf(to_file, "%s\n", b_val);
  110.                             if (b_pos != b_len)
  111.                                 get_line(from_file_b, b_val, MAX_LINE_SIZE);
  112.                         }
  113.                         else
  114.                         {
  115.                             a_pos++;
  116.                             fprintf(to_file, "%s\n", a_val);
  117.                             if (a_pos != a_len)
  118.                                 get_line(from_file_a, a_val, MAX_LINE_SIZE);
  119.                         }
  120.                     }
  121.  
  122.                     // Advance the positions for the next cycle
  123.                     forward(from_file_a, a_len);
  124.                     if (remaining_len > sub_len * 3)
  125.                         forward (from_file_b, b_len);
  126.                 }
  127.                 else
  128.                 {
  129.                     char line[MAX_LINE_SIZE];
  130.                     while ((get_line(from_file_b, line, MAX_LINE_SIZE)))
  131.                         fprintf(to_file, "%s\n", line);
  132.                 }
  133.             }
  134.  
  135.             fclose(from_file_a);
  136.             fclose(from_file_b);
  137.             fclose(to_file);
  138.  
  139.             // Swap the two "adresses"
  140.             char* temp = to;
  141.             to = from;
  142.             from = temp;
  143.         }
  144.  
  145.         // Make sure the sorted lines are in the original file
  146.         if (to == argv [1])
  147.         {
  148.             FILE* to_file = fopen(argv[1], "w");
  149.             FILE* from_file = fopen ( swap_name, "r" );
  150.  
  151.             char line[MAX_LINE_SIZE];
  152.             while ((get_line ( from_file, line, MAX_LINE_SIZE)))
  153.                 fprintf(to_file, "%s\n", line);
  154.         }
  155.         remove(swap_name);
  156.     }
  157.  
  158.     return 0;
  159. }
clone this paste RAW Paste Data
Top