Question

I'm back! I'm looking for some help piping a file from the command line (bash) into a C program, everything works except when I try to tokenize the value every second line, it works for the 2nd, but not the 4th, 6th etc. Here is my code :

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


int numExperiments = 0;



void sendToArray(int data[20][10], char *experiments[20]){
    char line[100];
    char line2[100];


    char *temp1;
    int temp;
    int i=0, c=0;
    while(c<20 && strcmp(line, "*** END ***")!=0){
    fflush(stdin);
        scanf("%[^\n]", line);
    scanf("%*c");
        scanf("%[^\n]", line2);
    scanf("%*c");
    temp1=strtok(line2, " ");
        while(i<10 && temp1 !=NULL){

        sscanf(temp1, "%d", &temp);
        data[c][i]=temp;
            temp1=strtok(NULL, " ");
i++;
} 

        experiments[c]=strdup(line);
        c++;

    }
    numExperiments = c-1;

}

void displayAll(int data[20][10], char *experiments[20]){
    int i=0,c=0;

    for(i=0; i<numExperiments; i++){
    printf("\n");
    printf("%s", experiments[i]);
    printf("\n");
        for(c=0;c<10;c++){
            printf("%d ", data[i][c]);

        }
    }
}
void individualAverage(char *name, char *experiments[20], int data[20][10]){
    int i=0, c=0;
    float dataRes=0;
    while( strcmp( name , experiments[i] )!=0 && i<20){
        i++;
    }
    printf("%s\n", experiments[i]);
    for(c=0;c<10;c++){
        dataRes = dataRes+ data[i][c];
    }
    printf("\nAverage is: %f", (dataRes/10));

}

void allAverage(char *experiments[20], int data[20][10]){
    int i=0,a=0;
    float totalAvg=0;
    for(i=0;i<numExperiments;i++){
        for(a=0;a<10;a++)
            totalAvg = totalAvg + data[i][a];
    }
    totalAvg = totalAvg/numExperiments;
    printf("The total average is: %f \n", totalAvg);
}


int main(int argc, const char * argv[])
{
    char *experiments[20];
    int data[20][10];

    int b=0;
    char name[100];
    sendToArray(data, experiments);
    fflush(stdin);
    while(b==0){
        int input=0;
        printf("\n\n");
        printf("Data set analysis\n");
        printf("1. Show all the data\n");
        printf("2. Calculate the average for an experiment\n");
        printf("3. Calculate the average across all experiments\n");
        printf("4. QUIT\n");
        printf("Selection: ");
    fflush(stdin);
freopen("/dev/tty", "r", stdin);
        scanf("%d", &input);

        switch (input) {
            case 1:

                    displayAll(data, experiments);

                break;
            case 2:
 fflush(stdin);               
                    printf("\n");                  
 printf("Enter the name of the experiment: ");
                    scanf("%s", name);
                    individualAverage(name, experiments, data);




                break;
            case 3:

                    allAverage(experiments, data);

                break;
            case 4:b=1;;
                break;

            default:
                printf("Oops, something went wrong!\n");
                break;
        }
    }
    return 0;

}

Also, the individual average function gives me a core dump. Can anyone see why?

The output of dislayAll is:

Experiment One
3 10 8 7 3 2 9 7 5 6 
Experiement Two
0 3 2090266759 1011 -1216787076 -1218461544 -1074571312 -1216447140 -1218499016 1074266160 
Control Group
78514226 1815496840 0 0 1 2342 -1216565784 -1216567208 -1216559671 -1218461352
Was it helpful?

Solution

Okay, I'm not entirely sure what is happening in the program. Something that looks a little bit interesting to me is your reopening stdin. Bash will handle the pipe.

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

/* Remove newline characters from end of string */
void strip(char* str)
{
  int len;
  if (str == NULL)
    {
      return;
    }
  len = strlen(str);
  if (str[len - 1] == '\n')
    {
      str[len - 1] = '\0';
    }
  len = strlen(str);
  if (str[len - 1] == '\r')
    {
      str[len - 1] = '\0';
    }
}

int main()
{
    char* line = NULL;
    size_t len = 0;
    int line_num = 0;
    while (getline(&line, &len, stdin) != -1)
    {
        strip(line);
        if (line_num % 2 == 0)
            printf("[%d]: %s\n", line_num, line);
        line_num++;
    }
    return 0;
}

The program above reads in words piped in from a file by bash. I used the following file to test it. You will only see "print line" on the output and I called it words.txt

print line
hello world
print line
not this one
print line
secret

Then to execute, just use cat words.txt | ./a.out

All the data will get streamed in through stdin right into the program. I hope this helps.

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