Read/Append to same file (listing primes)

Amatuer c++ coder here. I was bored and was writing a program to check for prime numbers (yes I know this has been done 1000's of times). The part I want to add I have no clue how to write, and have tried researching it to only realize I have no clue how to call/write std::io stuff.

Right now it stores all numbers in an array arr[] and eventually prints them to the file "primelog.txt" with one number per line. What I would like to have it do is have the program check against the numbers already stored in "primelog.txt" (rather than storing them in an array) and then append any new primes to the end. This has a lot of reading and writing to the same file, which is the part I have no idea how to write. Any help would be appreciated.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <iostream>
#include <fstream>
#include <cmath>
#include <algorithm>
#include <list>

using namespace std;

int main () {
	
    int arr[100000];    //initialize array to size [SIZE]
    long number = 3;    //number to check starting with 3 (2 is already stored in array)
    long arraypos = 0;  //array position number
    arr[0]=2;           //stores the first prime number, 2, in the first array position, 0.
    long int sqroot;    //sqroot of number rounded up to nearest integer
    ofstream myFile;    //output stream call name
    int total = 1;      //total number of primes (count set to 1 because 2 is already stored)

myFile.open("primelog.txt", fstream::app);  //opens file "primelog.txt" and sets output stream to append
myFile<<arr[arraypos]<<endl;                 //prints first array value, 2, to txt file and moves cursor to next line

while(number<1000000) //while loop to continue through until done
{
 bool prime = true;           //checks if number is prime.  Assumes prime until proven composite
 sqroot = sqrt(number)+1;     //integer of the sqroot of a number rounded up 1 (*+1 may not be necessary*)
 for(int i=0; i<arraypos && arr[i]<=sqroot; i++) //checks number for divisibilty of every number stored in array, up until the nearest value of the sqroot
 {
 	if(number % arr[i]==0) //checks for divisibility, if found, prime sets to "false".
 	{
	prime = false;
 	}
 }
 if(prime == true)                  
 {
 	arraypos++;                     //move to next array position
 	arr[arraypos]=number;           //store number in new array position
        myFile<<arr[arraypos]<<endl;    //print to file
 	total++;                        //add one to total prime count
 }
 number++;                          //go to next number
}
cout<<"Total number of primes = "<<total<<endl;  //prints to console the total number of primes
system("pause");                                 //pauses system before program ends
}
First of all you better forget about arrays - use vectors instead.
Before adding a number to the vector you can use the std::find algorithm to check if the number is in the vector already. At the beginning of the program you read the numbers from the file into the vector, at the end you write your vector to the file.

A simple start:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <cstdio>

using namespace std;

using IntVector = vector<int>;
// or
// typedef vector<int> IntVector

void add_number(IntVector& primes, int num)
{
  auto pos = find(primes.begin(), primes.end(), num);
  if (pos != primes.end())
    primes.push_back(num);
}

int main()
{
  vector<int> primes;
  ifstream src("primes.txt");
  if (!src)
  {
    perror("Error opening file");
    return errno;
  }
  int tmp;
  while (src >> tmp)
  {
    add_number(primes, tmp);
  }
  // TO DO
  // generate primes and add to vector
  // save vector to file

}
As a beginner I would recommend to code slowly and detect vulnerabilities among your code. That's how you ensure "code security". You can also use a app to do that. I know one called Checkmarx if you want to try.
Good luck!
Last edited on
Thanks for responding. However, I don't want to check if a number is already stored in the list, so I don't think the std::find is going to help.

Instead I want it to read each value already stored in the file, check if the current number it's checking is divisible by any number already in the list of found primes. So read one number, check it, read the next number, check it, etc. If none of them divide the current number, append the new number to the end of the file.

My program works fine checking up to the first 5,000,000 numbers (it has stored around 370,000 numbers by then). Anything higher gives me an error, which I assume is because the memory is overloaded with storing the values, I assumed by using a file instead of a vector or array I could find more by using more hdd space and not memory.
Last edited on
370,000 numbers is not much unless you run it on a machine with very low RAM.
Keeping all the numbers in memory is much more efficient then searching the file for each prime number.
Try this code and see if you run out of memory.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <cstdlib>
#include <cstdio>

using namespace std;

int main()
{
  try
  {
    vector<int> primes(10'000'000);
    return 0;
  }
  catch (const bad_alloc& ba)
  {
    cerr << "Out of memory..." << "\n";
  }
  catch (const exception& ex)
  {
    cerr << "Exception: " << ex.what() << "\n\n";
  }
  catch (...)
  {
    cerr << "Unknown Exception\n\n";
  }
  return errno;
}

hmm compiler error:
line 14 - expected `)' before '\x303030'
Seems you have older compiler but it doesn't matter.
Just replace line 14 with vector<int> primes(10000000);
Seems to run fine. Not sure why I was getting an error when I set number above 5,000,000 and have allocated over 1,000,000 to the array. I'm running bloodshed DEVc++ 4.9.9.2. I'll switch to vectors I guess.

Thanks.
However, I don't want to check if a number is already stored in the list, so I don't think the std::find is going to help.


The thing is, you have a beginners algorithm which is very inefficient. How long does your program take to do 1,000,000 primes? If it's more than 2 seconds it's too much.

Research on wiki Sieves of Eratosthenes, or more advanced Atkins Sieve.

There is an expert member here who wrote prime number code with basically 3 lines of code.

There is a type std::size_t which is the largest unsigned type the system has, typically unsigned long long, so you could use this to do a larger range before overflowing the type.

I'm running bloodshed DEVc++ 4.9.9.2.

Relevant: http://www.cplusplus.com/articles/36vU7k9E/
Topic archived. No new replies allowed.