HiveBrain v1.2.0
Get Started
← Back to all entries
patterncModerate

C the large print

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
printthelarge

Problem

This is the Longest lines challenge from CodeEval:

Challenge


Write a program which reads a file and outputs a specified number of lines, sorted on length in descending order.

Specifications



  • The first argument is a path to a file.



  • The file contains multiple lines.



  • The first line indicates the number of lines to output.



  • The following lines are of differing lengths and presented randomly.



  • Print the specified number of lines in descending order of length.




Constraints



  • The number in the first line is a valid positive integer.



  • The input file is correctly formatted.




Sample Input

3
Longest Lines Challenge
Hodor
Code Review is incredible
Test Cases are difficult to write
Hello World
Simple Overlord


Sample Output

Test Cases are difficult to write
Code Review is incredible
Longest Lines Challenge


My solution:

#include 
#include 
#include 

#define LINE_BUFFER 128

void initialize(char lines_to_print[][LINE_BUFFER], int number_of_lines, FILE *file) {
    for (int i = 0; i  shortest_long_line_length) {
            strcpy(lines_to_print[end], line);
            sort_lines(lines_to_print, number_of_lines);
            shortest_long_line_length = strlen(lines_to_print[end]);
        }
    }

    print_lines(lines_to_print, number_of_lines);
    return 0;
}

Solution

Algorithm

Let's redo our processing a bit, shall we? Let's read the file line by line, parse the necessary data, and then process that data for optimal speed. You should only need two for loops in this code, one to parse input and one to output data.

-
In order to do this, lets create a struct that contains two members, the string from the file and the length of the line. We want to store the string so we don't have to go back into our file and try to seek the line we need, and the length we are going to store for fewer calls overall to strlen().

-
Use a for loop to parse all this data quickly. We compute the length in place to speed up future comparisons:

for(size_t i = 0; fgets(buf, MAX_LINE_LENGTH, file); ++i) 
{
    lineData[i].str = strdup(buf);
    lineData[i].len = strlen(buf) - 1;  // lose the newline
}


-
Now we have all the data we need. Let's sort our data, as you do! But we are going to have to rework the callback function qsort() uses to sort based on that lineData.len member from above.

-
Now that we have a sorted array, we can loop over the array with a for loop and use the counter variable to access the first items in the array up until that specified number input at the beginning.

Miscellaneous

-
Don't abstract too much. I don't think you need a separate method like sort_lines().

-
On the other hand, you could move more of your processing outside of main(). Parse the command line arguments if there are any and then call another function to handle the rest.

-
Don't forget to close your file (although this might add time to your program).

-
You don't have to return 0 at the end of main(). The C standard knows how frequently this is used, and lets us omit it.


C99 & C11 §5.1.2.2(3)


...reaching the } that terminates the main() function returns a
value of 0.

Code Snippets

for(size_t i = 0; fgets(buf, MAX_LINE_LENGTH, file); ++i) 
{
    lineData[i].str = strdup(buf);
    lineData[i].len = strlen(buf) - 1;  // lose the newline
}

Context

StackExchange Code Review Q#131881, answer score: 11

Revisions (0)

No revisions yet.