2

I wrote a program that connects to a server and recieves lines of code from it and then prints all the code lines to a text file, the thing is, that the server sends all the code lines not in order, what I mean is that in the text file that contains the code lines there is not order, it can be line 55 and after it line 33, I am trying to write a function that will sort the file so the code lines will be in order, I know I need to use bubble sort and do a casting of the line numbers which are in string to int, but I have never tried bubble sorting a text file before, here is my code:(ignore the notes)

#define  _WINSOCK_DEPRECATED_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<winsock2.h>
#include<windows.h>
#include<string.h>


#define LEN 1024

void sortcode(FILE *fp);
int main(void)
{
    FILE *fp;
    fp = fopen("theCode.txt", "wt");
    int i;
    WSADATA info;
    char str[LEN];
    str[LEN - 1] = NULL;
    char str2[LEN];
    str2[LEN - 1] = NULL;
    char temp[8] = "5000000"; // the row number
    int j = strlen(temp) - 1;// the index of the temp string
    int k = 0;
    int err;
    err = WSAStartup(MAKEWORD(2, 0), &info);
    if (err != 0)
    {
        printf("WSAStartup failed with error: %d\n", err);
        exit(1);
    }
    int s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (s == INVALID_SOCKET)
    {
        printf("Error creating socket = %d\n", WSAGetLastError());
    }
    else
    {
        printf("Socket function succeeded\n");
    }
    struct sockaddr_in clientService;
    clientService.sin_family = AF_INET;
    clientService.sin_addr.s_addr = inet_addr("54.152.161.133");
    clientService.sin_port = htons(6714);
    int cResult = connect(s, (struct socketaddr*)&clientService, sizeof(clientService));
    if (cResult == SOCKET_ERROR)
    {
        printf("Connect function failed with error: %d\n", WSAGetLastError());
        cResult = closesocket(cResult);
        if (cResult == SOCKET_ERROR)
        {
            printf("Close socket function closed with an error: %1d\n", WSAGetLastError());
        }
        WSACleanup();
        //return 1;
    }
    //Until this part, it's all taken from the slideshow.
    send(s, "100", LEN, 0); //Sending code 100: Requesting to connect.
    printf("Request to connect was sent using 100\n");
    recv(s, str, LEN, 0); //Recieving a code to the string str.
    printf("Code recieved: %s\n", str);
    if (strcmp("101", str) == 0)
    {
        printf("Connection was successful\n");
    }
    else
    {
        printf("The connection failed\n");
    }
    send(s, "400", LEN, 0); //Sending a request for the number of code lines.
    printf("Request for the amount of code lines was sent using 400\n");
    recv(s, str, LEN, 0); //Recieving the answer on str, you'll get code 401+The number of lines for example 4010079.
    printf("String recieved: %s\n", str);
    printf("The amount of code lines: 0079\n");
    printf("%s", str);
    for (k = 1; k <= 7; k++)
    {
        for (i = 0; i <= 9; i++)
        {
            temp[j] = i + 0x30;
            send(s, temp, LEN, 0);
            recv(s, str, LEN, 0);
            fprintf(fp, str);
            fprintf(fp, "\n");
        }
        temp[j - 1] = k + 0x30;
        temp[j] = 0 + 0x30;
    }
    //You need to add the part with the files where you print all the lines including the code in them to a txt file.
    //Good Luck, first try to solve that i to string conversion.
    system("PAUSE");
    return (0);
}
void sortcode(FILE *fp)
{
    int i, j, k;
    char str2[LEN];
    fp = fopen("theCode.c", "rt");
    for (i = 0; i < 79; i++)
    {
        for (j = 3; j < 7; j++)
        {

        }
    }
}
Paul R
  • 208,748
  • 37
  • 389
  • 560
Jokerah
  • 47
  • 6

2 Answers2

0

You could read the entire file into an array of lines. Then you could use qsort() in stdlib.h to sort your array.

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

static int compare_lines( const void* left, const void* right )
{
    const char* l = *((char**)left);
    const char* r = *((char**)right);
    return strcmp( l, r );
}

int main(int argc, char* argv[])
{
    char** lines           = NULL;
    size_t number_of_lines = 0;

    const char* fruits[] = {
        "Banana",
        "Orange",
        "Ugli Fruit",
        "Pomegranate",
        "Peach",
        "Apple",
        "Blueberry",
        "Raspberry",
        "Guava",
        "Cherry",
        "Star Fruit",
        "Pomelo",
        "Kiwi",
        "Pineapple",
        "Fig",
        "Papaya"
    };

    size_t len = sizeof(fruits) / sizeof(fruits[0]);

    for( size_t i = 0; i < len; i++ )
    {
        void* p = realloc( lines, (number_of_lines + 1) * sizeof(char*) );
        if( p ) lines = p;
        else goto done;

        lines[ number_of_lines ] = malloc( strlen(fruits[ i ]) + 1 );
        strcpy( lines[ number_of_lines ], fruits[ i ] );
        number_of_lines++;
    }

    qsort( lines, number_of_lines, sizeof(char*), compare_lines );


    for( size_t i = 0; i < number_of_lines; i++ )
    {
        printf( "%zu.) %s\n", i, lines[ i ] );
    }

done:
    if( number_of_lines > 0 && lines )
    {
        for( size_t i = 0; i < number_of_lines; i++ ) free( lines[ i ] );
        free( lines );
    }
    return 0;
}

EDIT: Fixed pointer bug in compare_lines().

Man Vs Code
  • 1,058
  • 10
  • 14
  • The comparator is given pointers to two values to compare; think of one as being the one on the left and the other on the right. The comparator has to return a negative value if the left sorts before the right, a positive value if the left sorts after the right, and zero if the values sort as equal. I'm not yet convinced that the code in the answer is correct, though. I think I'd expect to be using `char *lhs = *(char **)left; char *rhs = *(char **)right; return strcmp(lhs, rhs);` -- but I've not double-checked that by executing it. Note that the call to `qsort()` needs to be in a function. – Jonathan Leffler Jun 26 '15 at 17:34
  • The line numbers would need to be 0-padded and all be the same length (which we don't know), otherwise extracting the line numbers from the text would be needed. – Weather Vane Jun 26 '15 at 17:37
  • I checked. This comparator works OK: `static int compare(const void *p_lhs, const void *p_rhs) { const char *lhs = *(char **)p_lhs; const char *rhs = *(char **)p_rhs; return strcmp(lhs, rhs); }`. Test yours; I don't think it will be correct. (It didn't crash, but the strings were not in what I'd recognize as a sorted order.) – Jonathan Leffler Jun 26 '15 at 17:47
  • Wow. I go off to lunch and everyone is linting and running my snippet against MISRA rules. lolz My snippet was meant to lead @Jokerah in the right direction. – Man Vs Code Jun 26 '15 at 17:54
  • Posting inaccurate code isn't helpful -- lunchtime or no. You'll notice you've not been given net negative votes (yet). Please attend to your answer and show correct working code. – Jonathan Leffler Jun 26 '15 at 18:02
  • Like I said, I meant to point him in the right direction. The code was fixed and a complete example written. – Man Vs Code Jun 26 '15 at 18:23
0

Even if you are determined to write your own sort function instead of using qsort(), the bubble sort algorithm is a pretty bad choice for more than a bare handful of items.

If you're willing to buffer all the lines in memory until you've read and sorted all of them, as is probably your best bet, then you should consider sorting them as you go. Each time you read a new line, find its place among those already read, and insert it there. This is essentially an insertion sort.

If you expect your lines to be mostly in order, then search linearly for each insertion point, from back to front. This is the standard insertion sort, and it does extremely well for inputs that are approximately in order. For large numbers of lines in no particular order, you could consider instead using a binary search to find each insertion point.

If you use a linked list to hold the lines (a reasonable choice if you don't know in advance how many there will be), then the binary-search alternative scales well to large inputs.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • Thanks, some of the problems I am faced with is that in the text file, there is the line number and after it what is written in this line, since it is a string type I need to convert it to int so I can check if one line number is bigger than the other, since I am trying to sort a text file which is something new for me I am struggling a bit, I am used to sorting arrays and I am trying to implemet it to sorting the text file. – Jokerah Jun 26 '15 at 17:35
  • @Jokerah: the first thing to do (after correcting the spelling of 'received' -- 'i' before 'e' except after 'c') is to print the data that's to be sorted. Show that data in the question. That will help people to help you. But it means you need a comparator function that will handle the format of the strings properly. For example, it might convert the string to a number using `atoi()` -- it might never need to compare the strings if the lines numbers are always unique. – Jonathan Leffler Jun 26 '15 at 17:43