Question

Here is my code:

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

int individualAverage(int data[][20],int j)
{
    int k,average=0;
    for(k=0;k<10;k++)
    {
        average += data[k][j];
    }
    return average;
}

int main()
{
    int var,indAvg=0;
    int i=0,j,k;
    char *experiments[20];
    int data[10][20];
    char str[100],str2[100];
    char *ptr, *token;
    int no_line=1;


    while(fgets(str,100,stdin) != NULL && (strcmp(str,"*** END ***") && strcmp(str,"*** END ***\n")))
    {
        if(no_line % 2 == 0)
        {
            k=0;
            token = strtok (str," ");
            while (token != NULL)
            {
                sscanf (token, "%d", &var);
                data[k++][i] = var;
                token = strtok (NULL," ");
            }
            i++;
        }
        else
        {
            ptr = strdup(str);
            experiments[i] = ptr;
        }
        no_line++;
    }

    fgets(str,100,stdin);
    token = strtok(str," ");
    while(token != NULL && (strcmp(token,"4") && strcmp(token,"4")))
    {
        sscanf (token, "%d", &var);
        printf("DATA SET ANALYSIS\n1.\tShow all the data\n2.\tCalculate the average for an experiment\n3.\tCalculate the average across all experiments\n4.\tQuit\nSelection: %d\n\n",var);
        switch(var)
        {
        case 1 :
            for(j=0;j<i;j++)
            {
                printf("%s",experiments[j]);
                for(k=0;k<10;k++)
                {
                    printf("%d ",data[k][j]);
                }
                printf("\n");
            }
            printf("\n");
            break;
        case 2 :
            printf("What experiment would you like to use?\n");
            token = strtok (NULL," ");
            sscanf (token, "%s", &str);
            for(j=0;j<i;j++)
            {
                if(strcmp(experiments[j],str) == 0)
                {
                    indAvg = individualAverage(data,j); 
                    printf("Experiment: %s",experiments[j]);
                    printf("The individual average of the experiment is %d\n",indAvg);
                    break;
                }
            }
        }
        token = strtok(NULL," ");
    }
}

OK, so I have a method that takes lines of redirection input. The lines come in pairs. First line is the name of an experiment, and the second line has the 10 values separated by spaces for that experiment. After these pairs, there is an ending line "*** END ***"

After this line, there is one last line holding the instructions of what to do with the data.

I'm currently having a problem where I've used fgets() to store the strings of the first pairs of lines into a variable which I declared as char *experiments[20];

Each of strings that this array is pointing to will have '\n' at the end of the string because of fgets()

Back to the last line of instructions. You have values 1-4. Right now I'm looking at instruction 2. It tells the average of an experiment. So after 2 on the last line, there must be the name of one of the experiments. I've used:

char str[100];
int var;
char *token;
token = strtok(str, " ");
sscanf (token, "%d", &var);

to get the first value on the line into var (pretend it's 2). So after that would be a string. Say it's Test 1, I'll use

token = strtok (NULL," ");
sscanf (token, "%s", &str);

to get the value into str, and then I'll compare it to experiments for all possible indexes.
HOWEVER, because fgets() gives '\n' at the end of the lines, all of the experiments strings will have '\n' at the end while str will just have the name of the experiment WITHOUT '\n' therefore they will never be equal even if '\n' is the only difference between the strings.

Any solutions?

Was it helpful?

Solution

Since you know that there may be a \n at the end of the string, you could check for it, and remove it if it's there:

size_t len = strlen(str);
if (len != 0 && str[len-1] == '\n') {
    str[len-1] = '\0';
}

This would terminate the line at \n, so your strcmp would succeed. An alternative is to use strncmp, and pass the length of the target string. This runs the risk of false positives when there's a longer suffix that \n, though.

You could also read your data like this:

fscanf(f, "%99[^\n]", str);

OTHER TIPS

You can make your own version of fgets that doesn't store the new-line character when it encounters one, and call it myfgets. Something like this would replicate fgets's behaviour, I think, produced with respect to the description given in MSDN:

char * myfgets( char * str, int n, FILE * stream ) {
    if ( n <= 0 ) return NULL;  // won't accept less than or equal to zero length

    int currentPos = 0;
    while ( n-- > 0 ) {
        int currentChar = fgetc( stream );
        if ( currentChar == EOF ) return NULL;
        if ( currentChar == '\n' ) break;
                    // if these two lines were in reversed order, 
                    // it would behave same as the original fgets
        str[currentPos++] = currentChar;
    }
    return str;
}

But of course the other solution is simpler, hehe...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top