2

I'm interested in reading a .txt file and save the data in it in a matrix in C.

dist.txt is the following:
Distance    Amsterdam   Antwerp Athens  Barcelona   Berlin
Amsterdam   -   160 3082    1639    649
Antwerp 160 -   2766    1465    723
Athens  3082    2766    -   3312    2552
Barcelona   1639    1465    3312    -   1899
Berlin  649 723 2552    1899    -

In fact it has more cities, but never mind.

I want to read this document and record the distances. I've tried the following code:

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

#define rows 6
#define cols 6

int main()
{
    FILE *nansa;
    char *buffer;
    int ret,row=0,i,j;

    char delims[]=" \t";
    char *result=NULL;

    double **mat=malloc( rows*sizeof(double*) );
    for(i=0; i<rows; i++)
    {
        mat[i]=malloc( cols*sizeof(double) ); 
    }

    if ((nansa=fopen("dist.txt","r"))==NULL)
    {
        fprintf(stdout, "Error\n"); 
        return -1;
    }
    while(!feof(nansa))
    {
        buffer=malloc( sizeof(char)*4096 );
        memset(buffer,0,4096);
        ret=fscanf(nansa, "%4095[^\n]\n", buffer);
        if(ret != EOF) 
        {
            int field=0;
            result=strtok(buffer,delims);
            while(result != NULL)
            {
                if(field>4) break;
                mat[row][field]=atof(result);
                result=strtok(NULL,delims);
                field++;
            }
            ++row;
        }
        free(buffer);
    }
    fclose(nansa);
    for(i=0; i<rows; i++)
    {
        for(j=0; j<cols; j++)
        {
            printf("%g%s", mat[i][j], j<cols-1 ? "\t" : "\n");
            free(mat[i]);
        }
    }
    free(mat);
    return 0;
}

But I don't get what I want... And I don't know how to separate the names and the distances (chars and integers). I would be very grateful if someone could help me!

developer
  • 4,744
  • 7
  • 40
  • 55
S. Proa
  • 137
  • 10
  • 5
    What text or who suggested using `while(!feof(...`? – chux - Reinstate Monica Dec 30 '15 at 15:04
  • 1
    ... see this post: http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong – terence hill Dec 30 '15 at 15:11
  • 1
    `buffer = malloc(4096);` + `memset(buffer, 0, 4096);` + `free(buffer);` all in the same loop? Why not allocate the buffer once, and just `memset` it, and free outside the loop. Or better yet: `buffer[0] = '\0';` and/or use `fgets`? – Elias Van Ootegem Dec 30 '15 at 15:12
  • 2
    I suggest avoiding the incorrect use of `feof` by reading each line with `while(fgets(...) != NULL)` and then using `strtok` to extract the fields from the input string. But watch out when you have a multi-word city like `Los Angeles`. You might be better reconsidering the field delimiter you use, such as a comma or a tab. – Weather Vane Dec 30 '15 at 15:13
  • You could read a line and iterate through the characters until a number is found. – Iharob Al Asimi Dec 30 '15 at 15:16
  • Why do you use a dash as a nul value, wouldn't 0 work well? Or do you have to process the data as it is? – Iharob Al Asimi Dec 30 '15 at 15:30
  • 1
    Posting with "I would be very grateful if someone could help me!", leaving the post for an hour with no replies sees like a one-sided help. – chux - Reinstate Monica Dec 30 '15 at 16:03

6 Answers6

5

Although it is tempting to use fgets to read each line (feof is wrong), the question is only an example with a small number of cities: perhaps there are 10000. So I have made an assumption that the name of any city is less than 64 (for input only). The memory reserved is correct for the name's actual length.

The rows and columns will be the same, so there is no point having different defines: in fact I define only the number of cities. I use separate arrays for the city names (same across as down) and the distances.

To keep it simple, I have done error checking, but aborted without a message. But where it will need to be modified is when the city is a multi word name such as Los Angeles (%s stops at any whitespace). You'll need a different method then, or perhaps use an underscore to break a city_name.

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

#define cities 5

int main(void){

    FILE *nansa;
    char buffer[64];
    char distname[64];                      // just to save work
    char *city[cities];                     // city names
    int *dist[cities];                      // distance array
    int i, j, len, wid = 0;

    if((nansa = fopen("dist.txt","r")) == NULL)
        exit(1);                            // file open fault

    // read the headings
    if(fscanf(nansa, "%63s", buffer) != 1)  // read the word for "distance"
        exit(1);                            // fscanf fault
    strcpy(distname, buffer);

    for(i=0; i<cities; i++) {               // read the city names
        if(fscanf(nansa, "%63s", buffer) != 1)
            exit(1);                        // fscanf fault
        len = strlen(buffer) + 1;
        if (wid < len)
            wid = len;                      // column width
        if((city[i] = malloc(len)) == NULL) // memory for city name
            exit(1);                        // malloc fault
        strcpy(city[i], buffer);
    }

    // read the data
    for(j=0; j<cities; j++) {               // read each table line
        if((dist[j] = malloc(cities * sizeof(int))) == NULL)    // memory for distance chart
            exit(1);                        // malloc fault
        if(fscanf(nansa, "%s", buffer) != 1)   // skip the city name
            exit(1);                        // fscanf fault
        for(i=0; i<cities; i++) {           // read each table line
            if(fscanf(nansa, "%63s", buffer) != 1)  // read the distance
                exit(1);                    // fscanf fault
            dist[j][i] = atoi(buffer);
        }
    }

    fclose(nansa);

    // display the table headings
    printf("%-*s", wid, distname);          // use the terminology in the file
    for(i=0; i<cities; i++)                 // each city name
        printf("%-*s", wid, city[i]);
    printf("\n");

    // display each line
    for(j=0; j<cities; j++) {
        printf("%-*s", wid, city[j]);       // start with city name
        for(i=0; i<cities; i++) {           // each table data
            if(dist[j][i])
                printf("%-*d", wid, dist[j][i]);
            else
                printf("%-*c", wid, '-');
        }
        printf("\n");

    }

    // free the memory
    for(i=0; i<cities; i++) {
        free (city[i]);
        free (dist[i]);
    }
    return 0;
}

Program output:

Distance  Amsterdam Antwerp   Athens    Barcelona Berlin
Amsterdam -         160       3082      1639      649
Antwerp   160       -         2766      1465      723
Athens    3082      2766      -         3312      2552
Barcelona 1639      1465      3312      -         1899
Berlin    649       723       2552      1899      -
Weather Vane
  • 33,872
  • 7
  • 36
  • 56
  • I really don't like your coding style (*for example: lower case macros?*), but your code is very good. One suggestion use the `"%n"` modifier in `scanf()`'s so you avoid `strlen()`. It would improve performance for a very large file. Also, your solution wouldn't work if a city name has a white space in it. But the intent of the program is quite clear. – Iharob Al Asimi Dec 30 '15 at 16:52
  • @iharob I commented above the code about a two-word city name. Any helpful suggestions about my style apart from "really don't like it"? – Weather Vane Dec 30 '15 at 16:54
  • lower case macros - mybad, I usually use upper but copied OP style. – Weather Vane Dec 30 '15 at 16:55
  • Also, you have inconsistent white space usage. – Iharob Al Asimi Dec 30 '15 at 16:56
  • @iharob I previously noticed a difference in your style. I like to have a space each side of an operator, except in `for` statements (I seen you edit them before!) it seems to me to flow better, that's just my style. Also I like a space to separate function arguments. – Weather Vane Dec 30 '15 at 16:58
  • @iharob I've been evovling my coding style since being here. Two aspects: I would always like a space after `if` and `for` and `while` but many don't seem to have it (yes my post does inconsistently have one). The major change was my previous dislike of having the `{` at the right. It makes a code block much harder to eye up than having the `{` and the `}` align vertically, *in line with the code block itself* and not 4 spaces to the left, since the braces are actually part of the code block. But I've changed that to suit the current style. – Weather Vane Dec 30 '15 at 17:06
  • OT, maybe, you can also right justify the printed numbers... ;) – Bob__ Dec 30 '15 at 17:08
  • @Bob__ that would be a simple shange, not really relevant to the question. – Weather Vane Dec 30 '15 at 17:09
  • I know, but you were talking about styles – Bob__ Dec 30 '15 at 17:10
  • Goodness me coding style was commented on. That's the output format not coding style. – Weather Vane Dec 30 '15 at 17:12
  • Actually, formatting of coding style, but it's irrelevant. More on topic, you can find out the number of city counting the numbers ( plus the '-' ) in the second row of the file. – Bob__ Dec 30 '15 at 17:16
  • @ryyker I am sorry, it's not my intention. – Iharob Al Asimi Dec 31 '15 at 00:17
  • Thank you very much!! This code is really helpful!! And for names with a multi word name such as Los Angeles I will simply write LosAngeles in the .txt file. Thank you so much!! :D – S. Proa Dec 31 '15 at 14:34
  • @S.Proa please "accept" whichever answer you feel was the best, thank you. – Weather Vane Dec 31 '15 at 14:39
  • @Weather Vane: Done! Thank you so much! :) – S. Proa Jan 02 '16 at 09:50
3

This seems to be one of the questions that invite a lot of fresh solutions that are rewritten from scratch. Here's one that allows any number of cities up to a certain maximum and that enforces matching city names.

The core is a home-brew function getcell that is similar to scanf("%s", ...), but that emits a special return value when one or more new-line characters were read. This allows to get theb rows and columns right without having to read the whole line, which may be very long.

Because the function reads from the file directly and because both whitespace and tokens must be looked at, the first non-matching character is consumed. To avoid this, ungetc is used, but never more than once. I don't think that this is especially good style, but I've left it as is. (That style is effortless when you work with strings and pointers, but not with files.)

The code to read the distances checks consistency between rows and cols and cities aggressivly, but skips the checks for file I/O and allocation in order not to clutter the code more.

The city names must be single words (LeMans or Los_Angeles) and are stored in a separate, fixed-size array. (That fixed size is the reason why there is a max. number of cities.) The distances are stored in a dynamically allocated array of doubles.

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

#define MAX_CITY 256        // Max. number of cities
#define MAX_NAME 24         // Buffer allocated for a name
#define NEWLINE -2          // Special token: end of line was read

/*
 *      Short-cut acro for string comparison
 */
#define is(a, b) (strcmp(a, b) == 0)

/*
 *      Quick-and-dirty exit macro with message
 */
#define die(...) exit((printf(__VA_ARGS__), putchar('\n'), 1))



/*
 *      Read a cell of at most (max - 1) characters and return its length.
 *      When the end of input is read, return the special value EOF; when
 *      one ore more new-line characters are read, return the special
 *      value NEWLINE. On EOF and NEWLINE, the contents of buf are
 *      undefined.
 */
int getcell(FILE *f, char *buf, size_t max)
{
    size_t len = 0;
    int nl = 0;
    int c;

    /*
     *      Skip leading whitespace and account for newlines
     */
    for (;;) {
        c = fgetc(f);

        if (c == EOF) {
            if (nl) break;
            return EOF;
        }
        if (!isspace(c)) break;
        if (c == '\n') nl++;
    }

    ungetc(c, f);
    if (nl) return NEWLINE;

    /*
     *      Store the token proper
     */
    for (;;) {
        c = fgetc(f);

        if (c == EOF || isspace(c)) break;
        if (len + 1 < max) buf[len++] = c;
    }

    ungetc(c, f);
    buf[len] = '\0';

    return len;
}

int main()
{
    FILE *f = fopen("dist.txt", "r");
    int nrow = -1;
    int ncol = -1;

    char city[MAX_CITY][MAX_NAME];
    int ncity = 0;

    double *data;           // contiguous data block
    double **dist;          // Pointers into that block

    for (;;) {
        char buf[MAX_NAME];
        int len = getcell(f, buf, sizeof(buf));

        if (len == EOF) break;

        if (len == NEWLINE) {
            if (nrow >= 0 && ncol < ncity) {
                die("Insufficient data for %s.", city[nrow]);
            }

            nrow++;
            ncol = -1;

            continue;
        }

        if (nrow < 0) {
            if (ncol < 0) {
                if (!is(buf, "Distance")) die("Wrong file format");
            } else {
                if (ncol >= MAX_CITY) {
                    die("Can have at most %d cities", MAX_CITY);
                }
                strcpy(city[ncity++], buf);
            }

            ncol++;
            continue;
        }

        if (ncol < 0) {
            if (nrow > ncity) {
                die("Too many rows, expected only %d.", ncity);
            }

            if (!is(buf, city[nrow])) {
                die("Expected '%s' in row %d.", city[nrow], nrow);
            }

            if (nrow == 0) {
                // First-touch allocation
                data = malloc(ncity * ncity * sizeof(*data));
                dist = malloc(ncity * sizeof(*dist));

                for (int i = 0; i < ncity; i++) {
                    dist[i] = &data[i * ncity];
                }
            }
        } else {
            if (nrow == ncol) {
                if (!is(buf, "-")) {
                    die("Distance of %s to itself isn't '-'.", city[nrow]);
                }

                dist[nrow][ncol] = 0.0;
            } else {
                double d = strtod(buf, NULL);

                if (ncol >= ncity) {
                    die("Too many columns for %s.", city[nrow]);
                }
                dist[nrow][ncol] = d;
            }
        }

        ncol++;
    }

    if (nrow < ncity) die("Got only %d rows, expected %d.", nrow, ncity);

    /*
     *      Print distance matrix
     */

    printf("Distance");
    for (ncol = 0; ncol < ncity; ncol++) {
        printf(", %s", city[ncol]);
    }
    puts("");

    for (nrow = 0; nrow < ncity; nrow++) {
        printf("%s", city[nrow]);

        for (ncol = 0; ncol < ncity; ncol++) {
            printf(", %g", dist[nrow][ncol]);
        }
        puts("");
    }

    free(dist);
    free(data);

    return 0;
}
M Oehm
  • 28,726
  • 3
  • 31
  • 42
  • nice approach. Especially like how you broke apart the monolithic `main()` with the `getcell()` function. – ryyker Dec 31 '15 at 22:27
2

The solution I think, is to ignore the header line completely and extract city names from the rows then after the first digit or - is found start scanning for values with strtod(). This solution that I just wrote is far from complete. It requires more structure (the use of functions would help), and sanity check (for example the number for columns in each row is not necessarily the same). But I think it will take you in the right direction.

Why to ignore the header line? Because it's not clear what character separates a city name from another and cities often contain white spaces in their name, for example "Los Angeles" does. This approach will work regardless of the separator and whether city names contain spaces or not.

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

int main()
{
    char *pointer;
    FILE *nansa;
    char buffer[1024];
    char **cities;
    double **distances;
    size_t rows;
    nansa = fopen("dist.txt", "r");
    if (nansa == NULL)
        return -1;
    if (fgets(buffer, sizeof(buffer), nansa) == NULL)
        return -1; // Skip the header line.
    rows = 0;
    distances = NULL;
    cities = NULL;
    while (fgets(buffer, sizeof(buffer), nansa) != NULL)
    {
        char next;
        double value;
        void *aux;
        ptrdiff_t length;
        size_t column;

        pointer = buffer;
        next = *pointer;        
        while ((isdigit((unsigned char) next) == 0) && (next != '-'))
            next = *pointer++;            
        aux = realloc(cities, (rows + 1) * sizeof(*cities));
        if (aux == NULL)
            return -1; // allocation error ABORT
        length = pointer - buffer - 1;
        cities = aux;
        cities[rows] = malloc(length + 1);
        if (cities[rows] == NULL)
            return -1; // allocation error ABORT                        
        memcpy(cities[rows], buffer, length);
        // Remove trailing spaces
        while ((length > 0) && (isspace((unsigned char) cities[rows][length - 1]) != 0))
            --length;
        cities[rows][length] = '\0';
        if (isspace(next) == 0)
            pointer--;
        aux = realloc(distances, (rows + 1) * sizeof(*distances));
        if (aux == NULL)
            return -1;
        distances = aux;
        column = 0;
        distances[rows] = NULL;
        while ((*pointer != '\0') && (*pointer != '\n')) 
        {
            char *endptr;
            aux = realloc(distances[rows], (column + 1) * sizeof(**distances));
            if (aux == NULL)
                return -1;
            distances[rows] = aux;
            value = strtod(pointer, &endptr);
            if (*endptr == '-')
                distances[rows][column] = -1.0;
            else
                distances[rows][column] = value;
            while ((*endptr != '\0') && (isspace((unsigned char) *(endptr + 1)) != 0))
                ++endptr;
            pointer = ++endptr;
            column += 1;
        }
        rows += 1;
    }

    fprintf(stdout, "%-15s|", "Distance");
    for (size_t i = 0 ; i < rows ; ++i)
        fprintf(stdout, " %-14s|", cities[i]);
    fputc('\n', stdout);
    for (size_t i = 0 ; i < rows ; ++i)
    {
        fprintf(stdout, "%-15s|", cities[i]);
        for (size_t j = 0 ; j < rows ; ++j)
        {
            if (distances[i][j] < 0.0) // Invalid distance
                fprintf(stdout, "%15s|", "-");
            else
                fprintf(stdout, "%15.2f|", distances[i][j]);
        }
        free(distances[i]);
        free(cities[i]);
        fputc('\n', stdout);
    }
    free(distances);
    free(cities);

    fclose(nansa);
    return 0;
}
Mogsdad
  • 44,709
  • 21
  • 151
  • 275
Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97
1

At first, you have a incorrect free you can look below:

for(i=0; i<rows; i++)
{
    for(j=0; j<cols; j++)
    {
        printf("%g%s", mat[i][j], j<cols-1 ? "\t" : "\n");
        /*free(mat[i]); this will be executed several time and the program will crash*/ 
    }
    free(mat[i]);
}
free(mat);

I have update your code for displaying all desired data:

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

#define rows 6
#define cols 6

int main()
{
    FILE *nansa;
    char *buffer;
    int ret,row=0,i,j,len=0,maxlen=0;

    char delims[]=" \t";
    char *result=NULL;

    double **mat=malloc( rows*sizeof(double*) );
    for(i=0; i<rows; i++)
    {
        mat[i]=malloc( cols*sizeof(double) ); 
    }

    char **cities = (char **)malloc( rows*sizeof(char *) );
    for(i=0; i<rows; i++)
    {
        cities[i]=(char *)malloc(sizeof(char)*4095); 
    }

    if ((nansa=fopen("dist.txt","r"))==NULL)
    {
        fprintf(stdout, "Error\n"); 
        return -1;
    }
    while(!feof(nansa))
    {
        buffer=malloc( sizeof(char)*4096 );
        memset(buffer,0,4096);
        ret=fscanf(nansa, "%4095[^\n]\n", buffer);
        if(ret != EOF) 
        {
            int field=0;
            result=strtok(buffer,delims);
            while(result != NULL)
            {
                if(field>5) break;
                if(field == 0)
                {
                    strcpy(cities[row], result);
                    len = strlen(result);
                    if(len>maxlen)
                        maxlen=len;
                }
                mat[row][field]=atof(result);
                result=strtok(NULL,delims);
                field++;
            }
            ++row;
        }
        free(buffer);
    }
    fclose(nansa);
    for(i=0; i<cols; i++)
    {
        printf("%-*s%s", maxlen, cities[i], (i<cols-1) ? " " : "\n");
    }
    for(i=1; i<rows; i++)
    {
        printf("%-*s ", maxlen, cities[i]);
        for(j=1; j<cols; j++)
        {
            printf("%-*g%s", maxlen, mat[i][j], (j<cols-1) ? " " : "\n");
        }
    }
    for(i=0; i<rows; i++)
    {
        free(cities[i]);
        free(mat[i]);
    }
    free(mat);
    return 0;
}

And the result will be like this:

Distance  Amsterdam Antwerp   Athens    Barcelona Berlin   
Amsterdam 0         160       3082      1639      649      
Antwerp   160       0         2766      1465      723      
Athens    3082      2766      0         3312      2552     
Barcelona 1639      1465      3312      0         1899     
Berlin    649       723       2552      1899      0        
developer
  • 4,744
  • 7
  • 40
  • 55
1

...And I don't know how to separate the names and the distances (chars and integers)...

Focusing only on file reading, data parsing and data storage...

Identifying features of your text file is an important step in helping you decide the approach you will take in parsing your data into variables.

Your text file can be broken into the following:

  • The first row is a header
  • Each additional row contains data (cities and distances)
  • cities are in first column only (non numeric (string) only)
  • remaining columns contain distances (numeric and non-numeric)

While the data is all stored in a text file, and initially read as strings, you express you would like to store them as strings and numbers. The city names are strings and the distances as integers. But the distances section also contains non-numeric data: "-".

storing multiple data types can be done using a struct. The following code illustrates how you can parse then store the numbers and strings separately using a struct.

Note: The following example is intended to illustrate how you might separate the names and the distances from the text file. Error checking/handling is minimal.

As opposed to printing data out, I will leave an image showing a memory segment of how the data was stored, using an array of struct. (supporting your request to save the data in it in a matrix in C).

enum {
    AM,
    AN,
    AT,
    BA,
    BE,
    MAX_CITY
};

typedef struct {//create a way to store both strings and numeric data
    char city[20];
    int dist[MAX_CITY];
}DIST;

DIST dist[MAX_CITY];//array (matrix) of struct DIST for storing results.

int main(void)
{
    int i;
    FILE *fp = {0};
    char *tok = {0};
    char line[260];
    fp = fopen(".\\dist.txt", "r");
    if(fp)
    {
        i = 0;
        fgets(line, 260, fp); //consume first line - header information
        while(fgets(line, 260, fp))
        {
            tok = strtok(line, " \t\n");
            if(tok)
            {
                strcpy(dist[i].city, tok);//get city    
            }
            tok = strtok(NULL, " \t\n");
            if(tok)
            {
                if(strstr(tok, "-")) dist[i].dist[0] = 0;
                else dist[i].dist[0] = atoi(tok);//get city 1 dist  
            }
            tok = strtok(NULL, " \t\n");
            if(tok)
            {
                if(strstr(tok, "-")) dist[i].dist[1] = 0;
                else dist[i].dist[1] = atoi(tok);//get city 2 dist  
            }
            tok = strtok(NULL, " \t\n");
            if(tok)
            {
                if(strstr(tok, "-")) dist[i].dist[2] = 0;
                else dist[i].dist[2] = atoi(tok);//get city 3 dist  
            }
            tok = strtok(NULL, " \t\n");
            if(tok)
            {
                if(strstr(tok, "-")) dist[i].dist[3] = 0;
                else dist[i].dist[3] = atoi(tok);//get city 4 dist  
            }
            tok = strtok(NULL, " \t\n");
            if(tok)
            {
                if(strstr(tok, "-")) dist[i].dist[4] = 0;
                else dist[i].dist[4] = atoi(tok);//get city 5 dist  
            }
            i++;
        }
        fclose(fp);
    }

    return 0;
}

Snippet of results (contents of struct after execution)

enter image description here

Community
  • 1
  • 1
ryyker
  • 22,849
  • 3
  • 43
  • 87
  • Well, the program can read the first line of the file to determine how many city are there, then allocate the right space in memory and read each distance in a nested loop (I'm not the down voter BTW). – Bob__ Dec 30 '15 at 16:04
  • Yes, I suppose there are a million ways to improve. The stated intent is limited to addressing the question about separating strings and numbers. allocating memory and additional looping would have clouded that simple part. Thanks. – ryyker Dec 30 '15 at 16:08
  • It would be nice to take advantage of the simmetry of matrix of distances too ( I could do that in c++ more easily) – Bob__ Dec 30 '15 at 16:09
  • 1
    @Bob__ - Regarding using C++ to take advantage of symmetry, I appreciate that, and I am sure you could. But 2 things: First, the OP has tagged this post as C, so I felt constrained to keep it in C. Second, the focus of this answer is clearly stated. I hope it helps the OP to understand parsing differing data types into a C array. (or as OP said a matrix). Some of the other answers have addressed the answer to this post more broadly, and do an excellent job presenting many other techniques. Thanks for your comment! – ryyker Dec 30 '15 at 19:00
-2

See the usage of strtok()!!

You can separate them with strtok(). You get everything as string, but then you make the distances to int with: - '0'

Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97
Dimos
  • 7
  • 1
  • Because you don't provide **how** to use it. The question is concerned with parsing through several lines of text. This is akin to saying that if you wanted to solve a mathematical equation, you are to use say Pythagorean's theorem... but you don't mention **how to use it**. Take a look at the other answers in the post and compare the quality of the answers with your answer.... do you feel that you sufficiently solved the problem with your answer? – rayryeng Mar 15 '16 at 16:25