0

I am learning C and I want to do this specific task. I know there is a number of similar questions and answers, but still... I will try to be more specific. Lets say, I have a file with following lines:

program01
programs
aprogram
1program
prog
5program

And I want now an array with:

1program
5program
aprogram
prog
program01
programs

So there are ONLY latin small letters and numbers in strings, no spaces. I know how to perform some separate steps, but want to get and feel the whole (and proper) concept, so to say. Probably it could make some sorting decisions on the fly when reading from file first? Manual sort is preferred for my particular case, just for the sake of better learning and possible optimisation. Lets say, maximal length of one line is 256, maximal number of lines is 256. Thanks in advance.

Mikhail V
  • 1,416
  • 1
  • 14
  • 23
  • 3
    _I know how to perform some separate steps_, ok show what you know and where are you stuck, and I will be glad to help, as I'm sure other SO users would. – Iharob Al Asimi Jan 21 '15 at 16:03
  • 2
    1) Read. 2) Sort. Where is the problem? – Eugene Sh. Jan 21 '15 at 16:05
  • I think you should start with one of the similar questions and adapt it for your own use, after all, they are all basically the same question, but hitting different problems. – Weather Vane Jan 21 '15 at 16:25
  • 1) `char buffer[256][256 + 2]` 2) call `fgets()` up to 256 times. 3) `qsort()`. 4) Print the lines. – chux - Reinstate Monica Jan 21 '15 at 16:57
  • @iharob (and other) nice that you are glad to help, So I know that `char*` is just a byte array and I can compare each char just like an int. Would be easy to compare two strings. But I just found it hard to understand some sorting examples due to my lack of C syntax knowledge, especially pointer arithmetic. – Mikhail V Jan 21 '15 at 22:01

3 Answers3

3

Check the below code:

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

int main(void) {
    char a[256][256];
    int i=0,j=0,k=0,n;

    while(i<256 && fgets(a[i],256,stdin) != NULL)
    {
        n = strlen(a[i]);
        if(n >0 && a[i][n-1] == '\n')
        a[i][n -1] = '\0';
        i++;
    }

    for(j=0;j<i;j++)
    {
        char max[256];
        strcpy(max,a[j]);
        for(k=j+1;k<i;k++)
        {
            if(strcmp(a[k],max) < 0)
            {
                char tmp[256];
                strcpy(tmp,a[k]);
                strcpy(a[k],max);
                strcpy(max,tmp);
            }
        }
        strcpy(a[j],max);
    }

    for(j=0;j<i;j++)
    {
        printf("%s\n",a[j]);
    }
    return 0;
}
Gopi
  • 19,784
  • 4
  • 24
  • 36
  • Comments I made [here](http://stackoverflow.com/a/28072988/2410359) mostly apply here too. Should a line _not_ fit `if(strlen(a[i]) < 255)`, IMO, better to complain than proceed. Else the split line will be sorted into maybe 2 locations. Suggest insuring `i` does not exceed 255/6. – chux - Reinstate Monica Jan 21 '15 at 17:28
2
The following cleanly compiles
however, I have not tested it

you might want to modify it to get the file name from 
the command line

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

#define MAX_ROWS (256)
#define MAX_COLUMNS (256)
#define FILE_NAME "myInputFile"

// prototypes
void bubbleSortWordsArray( int wordCount );
void printWordsArray( int wordCount );

static char words[MAX_ROWS][MAX_COLUMNS] = {{'\0','\0'}};

int main(void)
{
    FILE *fp = NULL;

    if( NULL == (fp = fopen( FILE_NAME, "r") ) )
    {
        perror( "fopen failed" );
        exit( EXIT_FAILURE );
    }

    // implied else, fopen successful

    // read each line from file into entry in words array
    int i = 0;
    while( fgets(words[i], MAX_COLUMNS, fp ) )
    {
        // remove trailing newline from string
        words[i][strlen(words[i])-1] = '\0';
        i++;
    }

     // 'i' contains number of valid entries in words[][]
    // sort the array of strings
    bubbleSortWordsArray(i);

    printWordsArray(i);

    return(0);
} // end function: main


void bubbleSortWordsArray( int wordCount )
{
    int c;  // outer index through rows
    int d;  // inner index through rows
    char swap[MAX_COLUMNS] = {'\0'};

    for (c = 0 ; c < ( wordCount - 1 ); c++)
    {
        for (d = 0 ; d <  (wordCount - c - 1); d++)
        {
            if(  0 > strcmp( words[d], words[d+1] ) )
            { // then words need to be swapped
                strcpy( swap, words[d]  );
                strcpy( words[d], words[d+1]);
                strcpy( words[d+1], swap );
            } // end if compare/swap
        } // end for
    } // end for each row
} // end function: bubbleSortWordsArray


void printWordsArray( int wordCount )
{
    int i; // loop index

    printf( "\n" ); // start on new output line
    for( i=0; i<wordCount; i++ )
    {
        printf( "%s\n", words[i] );
    }
} // end function: printWordsArray
user3629249
  • 16,402
  • 1
  • 16
  • 17
  • Minor thoughts: 1) Max line _length_ is 256, this usual requires additional buffer space for the `'\n'` and `'\0'`, 2) `words[i][strlen(words[i])-1]` is a problem in rare situations when the line begins with an embedded `'\0'` 3) interesting that code rolled its own sort rather than calling`qsort()`. 4) Initializing `words` is not needed - but not bad either. – chux - Reinstate Monica Jan 21 '15 at 17:22
  • @chux Also for eg if the buf size is `5` and the input is `1234` then `a[i][strlen(a[i]) -1] = '\0'` should not be done right so I have the check in my code for the same – Gopi Jan 21 '15 at 17:24
-2

Make a 2D char array try to read it by using fscanf function(sorry i cant remember the syntax). fscan will read your whole line till '\n' but there should not be space and store each string in a row. then sort it by comparaing the first index of each string

  • 1
    Better to use `fgets()`. – Weather Vane Jan 21 '15 at 16:29
  • using fgets can be a problem because it picks '\n' with it and can skip some further string. so you have to flush the '\n'. – Parul Setia Jan 21 '15 at 16:31
  • That is not a problem, it is a task. As for "can skip further string" would you prefer to break your buffer? – Weather Vane Jan 21 '15 at 16:32
  • 1
    "fscan will read your whole line till '\n'" --> no. There is no single `fscanf()` call that will "read your whole line till '\n". Even `fscanf("%[^n]")` fails if the line begins with `'\n'`. Use `fgets()`. – chux - Reinstate Monica Jan 21 '15 at 16:53
  • FILE *fp; char a[5][25]; int i=0; fp=fopen("abc.txt","r"); while(!feof(fp)){ fscanf(fp,"%s",a[i]); printf("%s\n",a[i]); i++; } it will read whole line but dont append '\n' and fgets can append with it '\n' – Parul Setia Jan 21 '15 at 17:45
  • `feof()` returns a nonzero value if there was an attempt to read past the end of a file. So `while(!feof(fp))` is incorrect. *"For example, if a file contains 10 bytes and you read 10 bytes from the file, feof will return 0 because, even though the file pointer is at the end of the file, you have not attempted to read beyond the end. Only after you try to read an 11th byte will feof return a nonzero value."* https://msdn.microsoft.com/en-us/library/xssktc6e.aspx – Weather Vane Jan 21 '15 at 18:36