简体   繁体   中英

C Simple File integers count program implementation problems

I did this program which finds the occurance of a specific number, in a given file.

Here is my full program:

#include <string.h>
#define SIZE 100

int main(void) {
   int count=0;
   char *pch=NULL;
   char line[SIZE];
   char target[SIZE]={"20"};
   FILE *fp=fopen("countNumber.txt","r");
   if(!fp) {
      printf("Error unable to open the file\n");
      return 0;
   }
   while(fgets(line, SIZE, fp)){          //gets each line of the file
      pch=&line[0];                       //sets the pointer address to the first char in line
      while((pch=strstr(pch,target)) != NULL) {  //searches for all occurrences of target in line
         //printf("%s\n",pch++); getchar();
         count++;
      }
   }

   fclose(fp);
   printf("target string %s was found %d times\n",target, count);
   return 0;
}

My plan:

I was thinking of doing something tricky with this. Is my approach correct?

The usual way to do this is:

  • read in all the numbers and put them in an array (it helps to know ahead of time how many numbers so you can size the array properly; otherwise you have to first count them, then read them in)

  • sort them in ascending order

  • to find the 90th percentile, find the element that follows sortedElement[floor(N * 0.9)]

Sorting is a bit advanced. There are simple (to understand and implement) algorithms that work well with small data sets. One such algorithm is the "bubble sort". You start at one end, and compare two numbers. The larger one "bubbles" up, compare again, keep going. After one lap your biggest number is at the top. Now repeat, starting at the bottom, but stopping one sooner. If you only need the 90th percentile (rather than a fully sorted array), you only have to do this a few times (1/10 of N times) - because when you have the 10% biggest numbers in order, the lowest of these is your answer.

It sounds to me, based on the excellent wording of the question, that you are up to the challenge of writing this code yourself; if you're not, leave a comment!

EDIT here is the code:

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

int main(void) {
  FILE* fp;
  char* chBuf=NULL; // where line will be stored
  int* myArray;
  int ii, jj;
  int lineCount;
  int numCount;
  size_t byteCount; // used for reading in the line

  if((fp = fopen("numbers.txt", "r")) == NULL) {
    printf("Unable to open file\n");
    return -1;
  }

  // got here because file is openened.
  // Let's find out how many lines there are
  lineCount = 0;
  while(getline(&chBuf, &byteCount, fp)>0) lineCount++;
  printf("There are %d lines in the file\n", lineCount);

  // now "rewind" to the beginning, and read one line at a time:
  fseek(fp, 0, SEEK_SET);

  // create space for the numbers:
  myArray = malloc(lineCount * sizeof(int));
  numCount = 0;

  // read numbers in - this time, convert them to integers:
  while(getline(&chBuf, &byteCount, fp) > 0) {
    myArray[numCount] = atoi(chBuf);
    // take this line out - just there to show it is working:
    printf("converted number %d: it is %d\n", numCount, myArray[numCount]);
    numCount++;
  }
  fclose(fp);

  // now we have to sort. Since data was sorted low to high,
  // I will sort high to low just to show it works:

  for(ii = 0; ii < numCount - 1; ii++) {
    for(jj = ii + 1; jj < numCount; jj++) {
      if(myArray[ii] < myArray[jj]) {
        int temp = myArray[ii];
        myArray[ii] = myArray[jj];
        myArray[jj] = temp;
      }
    }
    printf("sorted element %d: %d\n", ii, myArray[ii]);
  }
  // we never "sort" the last number... it bubbled to the end:
  printf("sorted element %d: %d\n", ii, myArray[ii]);

  // now find 10% of the number of elements (rounded down)
  // and we will have the number that is bigger than 90% of the numbers in the file
  int index90 = 0.1 * numCount - 1; // automatically gets truncated;
                                    // offset by 1 since index starts at 0
  printf("The first number bigger than 90%% is element %d: it is %d\n", \
    index90, myArray[index90]);
}

There are several "tricks" in here that are worth pointing out to a novice programmer:

  1. Check that the file is opened successfully, and take action if not
  2. Use getline (actually a gcc extension - I don't know if you have it) to safely read a line: it will make sure that there is enough space in the buffer. Your method is valid for your file - mine is "generally safer".
  3. Use malloc to allocate enough space for the array of numbers
  4. I sort "all the numbers" even though I really only need to sort the first 10% to solve the problem. You can improve performance (for this instance) by changing the upper limit of ii in the outer sort loop.
  5. I use the fact that assigning a floating point number to an int will automatically truncate it in my calculation of the index of the number I want.

Enjoy!

You need to have a way to separate the numbers in the file. Anyway in your code you could take 200 as another 20.

Regarding your plan, if you can put all your numbers in memory you will have to order them. One way is to use a heap to represent a binary tree with the data ordered. Once you have the data ordered you can get the 10% higher and from that, the minimum. Everything in O(log n) but the file read and amount of inserts in the heap, which will be O(n).

there are a few thing you need to consider: - the first thing you need to do is convert the numbers you read from the file to integers (please see atoi function for this). - second, make sure you allocate enough memory to hold all your numbers(100 might not be enough) - make sure you use the correct data type( int should be fine )

Once you read all your numbers in memory you can do whatever you want with them: sort them, find min, max..etc

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM