C++ Cascading Stream Insertion (HW Help) - c++

I found this potential solution in previous stack question. My problem is that it's not outputting to the file.
The program terminates without errors and actually does what it's supposed to do as I have verified this with a cout.
The program takes in a 7-digit phone number. Then writes to a file all possible words that can be made with those 7 digits, respecting the letter-number association on a standard telephone.
Program uses two functions: main and wordGenerator and includes iostream, fstream, & cstdlib
main :
int main()
{
int phoneNumber[ 7 ] = { 0 }; // holds phone number
// prompt user to enter phone number
cout << "Enter a phone number (digits 2 through 9) " << "in the form: xxx-xxxx\n";
// loop 8 times: 7 digits plus hyphen;
// hyphen is not placed in phoneNumber
for ( int u = 0, v = 0; u < 8; u++ )
{
int i = cin.get();
// test if i is between 0 and 9
if ( i >= '0' && i <= '9' )
phoneNumber[ v++ ] = i - '0';
} // end for
wordGenerator( phoneNumber ); // form words from phone number
} // end main
wordGenerator :
void wordGenerator( const int * const n )
{
cout << "Some Word Forming Magic is going on!" << endl;
// set output stream and open output file
ofstream outFile("phone.dat");
// letters corresponding to each number
const char * phoneLetters[] = {"___", "___", "ABC", "DEF", "GHI", "JKL", "MNO", "PRS", "TUV", "WXY"};
// terminate if file could not be opened
if ( !outFile )
{
cerr << "File could not be opened! Program Terminating..." << endl;
exit(1);
}
int count = 0; // number of words found
// output all possible combinations
for ( int i1 = 0; i1 <= 2; i1++ )
{
for ( int i2 = 0; i2 <= 2; i2++ )
{
for ( int i3 = 0; i3 <= 2; i3++ )
{
for ( int i4 = 0; i4 <= 2; i4++ )
{
for ( int i5 = 0; i5 <= 2; i5++ )
{
for ( int i6 = 0; i6 <= 2; i6++ )
{
for ( int i7 = 0; i7 <= 2; i7++ )
{
/* I think the next 8 lines is what's not working! */
/* Write a series of cascaded stream insertion operations
to output a set of seven letters to outFile, followed by a space */
outFile
<< phoneLetters[n[0]][i1]
<< phoneLetters[n[1]][i2]
<< phoneLetters[n[2]][i3]
<< phoneLetters[n[3]][i4]
<< phoneLetters[n[4]][i5]
<< phoneLetters[n[5]][i6]
<< phoneLetters[n[6]][i7]
<< " ";
if ( ++count % 9 == 0 ) // form rows
outFile << '\n';
}
}
}
}
}
}
}
//alert user that wordGenerator has completed
cout << "Writing to file..." << endl;
// output phone number
outFile << "\nPhone number is ";
for ( int i = 0; i < 7; i++ )
{
if ( i == 3 )
outFile << '-';
outFile << n[ i ];
} // end for
//print results to screen
cout << count / 9 << " words were created from" << endl;
//close output file
outFile.close();
} // end function wordGenerator
Program runs fine. No errors, except nothing is written to the output file phone.dat

I'm so embarrassed to write this. It turns out that the code has been working all along. The output file is saved into /Users/userName/Library/Developer/Xcode/DerivedData and after running the program that directory disappears.
So in order to combat this you must go to XCode's Preferences, click on "Locations" and change the setting for "Derived Data" from "default" to "relative".
I hope this helps someone else in the future...

Related

C++ code - problems with сode execution time

there is code.
#include "pch.h"
#include <algorithm>
#include <iostream>
#include <vector>
#include <stdlib.h>
using namespace std;
vector<int> SearchInt(vector<int> vec, int num) {
vector<int> temp(2);
sort(begin(vec), end(vec));
int j = 0;
for (int i : vec) {
if (i > num) {
temp[0] = i;
temp[1] = j;
return { temp };
}
//cout << i << " !>= " << num << endl ;
j++;
}
cout << "NO";
exit(0);
}
int main()
{
int n;
cin >> n;
vector<int> nums(n, 0);
vector<int> NewNums(n, 0);
for (int i = 0; i < n; i++) {
cin >> nums[i];
}
if (n != nums.size()) {
cout << "://";
return 0;
}
sort(begin(nums), end(nums));
NewNums[1] = nums[nums.size() - 1];
nums.erase(nums.begin() + nums.size() - 1);
NewNums[0] = nums[nums.size() - 1];
nums.erase(nums.begin() + nums.size() - 1);
for (int j = 2; j <= NewNums.size() - 1; j++) {
NewNums[j] = SearchInt(nums, NewNums[j-1]- NewNums[j-2])[0];
nums.erase(nums.begin() + SearchInt(nums, NewNums[j] - NewNums[j - 1])[1]);
}
if (NewNums[NewNums.size()-1] < NewNums[NewNums.size() - 2] + NewNums[0]) {
cout << "YES" << endl;
for (int i : NewNums) {
cout << i << " ";
}
return 0;
}
else {
cout << "NO";
return 0;
}
}
His task is to check whether it is possible from the given Each number is less than the sum of the two adjacent ones.
(each number is less than both of two adjacent ones)
But there is a problem - with a large number of numbers, the code takes too long. Please help me to optimize it, or just give some advice.
numbers cаn not be null.
time limit: 3.0 s
n <= 500000
You are given n numbers a1, a2,…, an. Is it possible to arrange them in a circle so that each number is strictly less than the sum of its neighbors?
For example, for the array [1,4,5,6,7,8], the left array satisfies the condition, while the right array does not, since 5≥4 + 1 and 8> 1 + 6.
Input data
The first line contains one integer n (3≤n≤105) - the number of numbers.
The second line contains n integers a1, a2,…, an (1≤ai≤109) - the numbers themselves. The given numbers are not necessarily different.
Output
If there is no solution, print "NO" on the first line.
If it exists, print "YES" on the first line. After that, on the second line print n numbers - the elements of the array in the order in which they will stand on the circle. The first and last elements you print are considered neighbors on the circle. If there are multiple solutions, output any of them. You can print a circle starting with any of the numbers.
First I'll only briefly analyze technical shortcomings of your code - without analyzing its meaning. After that I'll write my solution of the problem you defined.
Performance problems of your code are due to some strange decisions:
(1) passing std::vector<int> by value and not by reference to SearchInt function - this implies allocating and copying of the whole array on each function invocation,
(2) call SearchInt two times per loop iteration in function main instead of only one,
(3) sort array within each invocation of SearchInt - it is already sorted before the loop.
To be honest your code feels ridiculously time-consuming. I'm only wondering if that was your intention to make it as slow as you possibly can...
I will not analyze correctness of your code according to problem description. To be honest even after fixing technical shortcomings your code seems to me utterly sub-optimal and quite incomprehensible - so it is just easier to solve the problem from scratch to me.
The answer to the problem as defined is YES if the biggest number is smaller than the sum of the second big and the third big and NO otherwise - this follows from the fact that all numbers are positive (in range 1 - 109 according to newly found problem description). If the answer is YES then to make a circle that satisfies the problem description you just need in a sorted sequence of input numbers switch places of the biggest number and the next big one - that's all.
Here is my code for that (for slightly relaxed input format - I'm not checking if number of items is on a separate line and that all items are on the same line - but all correct inputs will be parsed just fine):
#include <set>
#include <iostream>
int main()
{
std::multiset<unsigned> input_set;
unsigned n;
if( !( std::cin >> n ) )
{
std::cerr << "Input error - failed to read number of items." << std::endl;
return 2;
}
if( n - 3U > 105U - 3U )
{
std::cerr << "Wrong number of items value - " << n << " (must be 3 to 105)" << std::endl;
return 2;
}
for( unsigned j = 0; j < n; ++j )
{
unsigned x;
if( !( std::cin >> x ) )
{
std::cerr << "Input error - failed to read item #" << j << std::endl;
return 2;
}
if( x - 1U > 109U - 1U )
{
std::cerr << "Wrong item #" << j << " value - " << x << " (must be 1 to 109)" << std::endl;
return 2;
}
input_set.insert(x);
}
std::multiset<unsigned>::const_reverse_iterator it = input_set.rbegin();
std::multiset<unsigned>::const_reverse_iterator it0 = it;
std::multiset<unsigned>::const_reverse_iterator it1 = ++it;
if( *it0 >= *it1 + *++it )
{
std::cout << "NO (the biggest number is bigger than the sum of the second big and the third big numbers)" << std::endl;
return 1;
}
std::cout << "YES" << std::endl;
std::cout << "Circle: " << *it1 << ' ' << *it0;
do
{
std::cout << ' ' << *it;
}
while( ++it != input_set.rend() );
std::cout << std::endl;
return 0;
}

Finding a vertical word from a .txt file in C++

I am working on a small project and I am trying to put a set of letters (5 rows, 5 columns) from a .txt file into an array, then finding the vertical word "DOG." Not only do I have to find it, but I have to determine the position of the word also. I am having so much trouble getting it to complete this task.
1) It doesn't matter if I take the word DOG out or not. My code still says it finds the word.
2) It always displays the same position if I move the word DOG to another spot on the puzzle.
3) It just doesn't work...
Can any of you help?
Please keep in mind, this is my 2nd week of C++. I am currently taking an intro college course on this language so no hate. I am only trying to learn. I spent probably a total of 12 hours on this code.
#include <iostream>
#include <fstream>
using namespace std;
int main() {
char puzzle[25];
ifstream fin;
fin.open("words.txt");
int rows {5};
int cols {5};
for (int i=0;i<rows*cols;i++) fin >> puzzle[i];
fin.close();
/***********
This is what I believe the array looks like and the values of each position.
* 0 1 2 3 4
* 5 6 7 8 9
* 10 11 D 13 14
* 15 16 O 18 19
* 20 21 G 23 24
************/
string s = "DOG";
cout << s.size() << endl;
int foundpos {-1};
for (int i=0; i<rows*cols; i++) {
if (puzzle[i]==s[0]) {
foundpos=i;
for (int j=5; j<s.size(); j+5) {
if (puzzle[i+j]!=s[j]) {
foundpos=-1;
break;
}
}
}
if (foundpos>0) {
cout << s << " was found at pos " << foundpos << endl;
cout << s << " found on row " << foundpos << endl;
cout << s << " found on column " << foundpos << endl;
break;
}
}
if (foundpos==-1) cout << s << " not found." << endl;
return 0;
}
===============================================================
Now here is the .txt file.
YRUVG
RTSDC
IFDYU
EPOWE
PWGHT
Your problem is here:
for (int j=5; j<s.size(); j+5) {
if (puzzle[i+j]!=s[j]) {
foundpos=-1;
break;
}
}
Your idea: when you get the first letter of given string, you try to check the next letter of same column is same with the next letter of given string. But, you ran the loop from 5, note that s.size() = 3, so your loop does NOT run. Then, the foundpos is not set to -1. That's why you always see 8 in print log.
Fix:
for (int j=1; j<s.size(); j++) {
if (puzzle[i+j*5]!=s[j]) {
foundpos=-1;
break;
}
}
There were a few other caveats that you would need to address that I was unable to include in the comments. Since you are reading all characters into a single array which you want to represent as a 2D array, you will need to index puzzle[i][j] as puzzle[i + j * STRIDE].
The primary approach is to loop over each character is puzzle checking whether the first character in your search term is the current character. If it is, you check:
Do enough character remain between i and rows*col for the rest of the search term to exist in a column? If not, you can conclude your string is not found;
If enough character remain, set a found = true flag and loop over the remaining characters in your search term (e.g. from j = 1 to term.size()) checking puzzle[i + j * STRIDE] != term[j] if a non-matching term is found, set found = false and break the term loop; and
finally check the found flog. If it has survived as found == true at this point, your search term has been found and you can simply output the indexes for the search term and return.
For example, putting it altogether in a short example, you could do:
#include <iostream>
#include <fstream>
#include <string>
#include <cctype> /* for isspace() */
#define STRIDE 5 /* define const for stride */
int main (int argc, char **argv) {
char puzzle [STRIDE*STRIDE] = {0}, c; /* puzzle and char */
size_t psize = STRIDE*STRIDE, n = 0; /* puzzle size & char count */
std::string fname = argv[1], /* filename */
term = argc > 2 ? argv[2] : "DOG"; /* search term */
std::ifstream f; /* file stream */
if (argc < 2) { /* validate at least filename given as arg */
std::cerr << "error: insufficien input.\n"
<< "usage: " << argv[0] << "infile\n";
return 1;
}
f.open (argv[1]); /* open file */
if (!f.is_open()) { /* validate file open for reading */
perror (("error file open failed " + fname).c_str());
return 1;
}
while (n < psize && f >> c) /* read file into puzzle */
if (!isspace (c))
puzzle[n++] = c;
f.close(); /* close file */
if (n < psize) { /* validate psize characters read */
std::cerr << "error: only " << n << "characters read.\n";
return 1;
}
for (size_t i = 0; i < psize; i++) { /* loop over each char */
if (puzzle[i] == term[0]) { /* if matches 1st in term */
size_t tlen = term.size(), /* get term size */
found = 1; /* set found flag true */
if (i + (tlen - 1) * STRIDE >= psize) /* enough chars left? */
break;
for (size_t j = 1; j < tlen; j++) /* loop 1 to term len */
if (puzzle[i + j * STRIDE] != term[j]) { /* next !found? */
found = 0; /* set found flag false */
break; /* break loop */
}
if (found) { /* if found, output term & indexes, return */
std::cout << "found " << term << " at indexes " << i;
for (size_t j = 1; j < tlen; j++)
std::cout << ", " << i + j * STRIDE;
std::cout << '\n';
return 0;
}
}
}
/* only reachable if not found */
std::cout << "'" << term << "' not found.\n";
return 1;
}
Example Input File
$ cat dat/vertword.txt
YRUVG
RTSDC
IFDYU
EPOWE
PWGHT
Example Use/Output
$ ./bin/verticalfind dat/vertword.txt
found DOG at indexes 12, 17, 22
$ ./bin/verticalfind dat/vertword.txt RIEP
found RIEP at indexes 5, 10, 15, 20
$ ./bin/verticalfind dat/vertword.txt MOP
'MOP' not found.
Look things over and let me know if you have further questions.

Why does starting value affect outcome of Seeded Random?

Trying to figure out why the starting value affects the seeded random in this code. I would expect for it to find the match at the same location for 12 character or more match no matter of the starting value for the seed, but it seems as though I am getting different results depending on the starting value of the seed which to me makes no sense. Anyone who why I am getting these results as shown from 0, 1, 2, and 3 for starting values when all 4 should flag the same values as a match to 12 more more characters.
Poor Key Finder
Search for 12 or more matches
Searching through Key Values of **0** thru 1000000000
WARNING - Program Running Please Wait...
25% Complete
50% Complete
75% Complete
**Greater or Equal to = 12 ===== 923425024**
100% Complete
Completed = 1000000000
Press any key to continue . . .
Poor Key Finder
Search for 12 or more matches
Searching through Key Values of **1** thru 1000000000
WARNING - Program Running Please Wait...
**Greater or Equal to = 12 ===== 204715678**
25% Complete
**Greater or Equal to = 12 ===== 346933630**
50% Complete
75% Complete
100% Complete
Completed = 1000000000
Press any key to continue . . .
Poor Key Finder
Search for 12 or more matches
Searching through Key Values of **2** thru 1000000000
WARNING - Program Running Please Wait...
25% Complete
50% Complete
75% Complete
100% Complete
Completed = 1000000000
Press any key to continue . . .
Poor Key Finder
Search for 12 or more matches
Searching through Key Values of **3** thru 1000000000
WARNING - Program Running Please Wait...
25% Complete
50% Complete
75% Complete
100% Complete
Completed = 1000000000
Press any key to continue . . .
Code:
#include <iostream>
#include <string>
int delay;
long long int counter1 = 0; // Add LL beyond 9 digits
long long int endcount = 0; // while loop end counter
long long int seed1 = 0;
int match2 = 0;
int ST = 0;
int flag = 0;
float progress = 0;
int step1 = 0;
int step2 = 0;
int step3 = 0;
int main()
{
system("color b0");
std::cout << "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n";
std::cout << " Poor Key Finder Version 1.0\n";
std::cout << " Build 01/30/2016\n";
std::cout << "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n\n";
std::cout << " Enter Starting Key Value\n";
std::cin >> counter1;
std::cout << " Enter Ending Key Value\n";
std::cin >> endcount;
std::cout << " Enter Duplicate Character Counter Value\n";
std::cin >> flag;
system("cls");
std::string str =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890!##$%^&*()_-+=?<>:\\/~.,;";
std::string str2=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890!##$%^&*()_-+=?<>:\\/~.,;";
system("#echo. Started on %date% at %time%>>LogKey.txt");
system("color f0");
std::cout << "Poor Key Finder - Search for " << flag
<< " or more matches \n";
std::cout << "Searching through Key Values of " << counter1 << " thru "<<endcount<<"\n\ n";
std::cout << " WARNING - Program Running Please Wait...\n\n";
while (counter1 <= endcount)
{
seed1 = counter1;
srand(seed1);
random_shuffle(str.begin(), str.end()); // Shuffle the string
ST = 0;
match2 = 0;
progress = ((100 * counter1) / endcount);
if (progress == 25)
{
step1++;
if (step1 == 1)
{
std::cout << "25% Complete\n";
}
else
{
}
}
else if (progress == 50)
{
step2++;
if (step2 == 1)
{
std::cout << "50% Complete\n";
}
else
{
}
}
else if (progress == 75)
{
step3++;
if (step3 == 1)
{
std::cout << "75% Complete\n";
}
else
{
}
}
else if (endcount == counter1)
{
std::cout << "100% Complete\n";
}
else
{
}
while (ST <= 85)
{
if (str[ST] == str2[ST])
{
match2++;
}
else
{
}
ST++;
}
if (match2 >= flag)
{
std::cout << "Greater or Equal to = " << flag << " ===== " << seed1
<< "\n";
}
else
{
}
counter1++;
}
std::cout << "Completed = " << endcount << "\n\n\n";
system("#echo. Ended on %date% at %time%>>LogKey.txt");
system("pause");
return 0;
}
I now understand what you are asking! The problem is because you shuffle str on each iteration without resetting it to its initial value each time, so it accumulates randomness from the previous iterations' shuffles.
In other words, you have two "seeds" -- one in the counter which you set each iteration using srand and one you do NOT reset, contained in str's shuffled character order.
To keep each iteration consistent, you need to reset str to the same base value before each shuffle.

Using CheckSum with C++ for 13 Digit ISBN

I am trying to calculate the final digit of a 13 digit ISBN using the first 12 digits using C++. I feel like my code should be correct but I have a feeling the formula I'm using may be wrong.
The formula is:
10 - (d0 + d1 * 3 + d2 + d3 * 3 + d4 + d5 * 3 + d6 + d7 * 3 + d8 + d9 * 3 + d10 + d11 * 3) % 10
Here's what I have:
#include <cstring>
#include <iostream>
int main() {
int weightedSum = 0;
int checksum = 0;
int i; //for loop decrement
int mul = 3;
const int LENGTH = 12;
char ISBNinput[LENGTH];
std::cout << "Enter first 12 digits of ISBN: "; //ask user for input
std::cin >> ISBNinput; //stores input into ISBNinput
std::cout << std::endl;
for (i = 0; i < strlen(ISBNinput); i++) {
weightedSum += (ISBNinput[i] % 12) * mul;
if (mul == 3) {
mul = 1;
} else {
mul = 3;
}
}//close for loop
checksum = weightedSum % 10; //calculates checksum from weightedSum
std::cout << checksum << std::endl; //prints checksum with new line for format
return 0;
}
For example:
978007063546 should return 3
and
978032133487 should return 9
Thank you for any help.
Here's how I go about this.
First, let's decide how we're going to test this. I'll assume that we've written the function, and that it gives the correct output. So I pick up a couple of books off my desk, and test that it works for them:
#include <iostream>
int main()
{
std::cout << "Book 1 - expect 3, got " << checksum("978032114653") << std::endl;
std::cout << "Book 2 - expect 0, got " << checksum("978020163361") << std::endl;
}
Of course, when we try to compile that, we get an error. So create the function, before main():
char checksum(const char *s)
{
return '1';
}
Now it compiles, but the result is always 1, but now we can start to fill in the body. Let's start with some smaller examples, that we can calculate by hand; add these at the beginning of main():
std::cout << "1 digit - expect 4, got " << checksum("6") << std::endl;
Now let's get this one working - this gives us conversion from character to digit and back, at least:
char checksum(const char *s)
{
int digit = *s - '0';
return '0' + 10 - digit;
}
Let's try 2 digits:
std::cout << "1 digit - expect 6, got " << checksum("11") << std::endl;
And now our test fails again. So add some more processing, to make this pass (and not break the single-digit test):
char checksum(const char *s)
{
int sum = 0;
int digit = *s - '0';
sum += digit;
++s;
if (*s) {
digit = *s - '0';
sum += 3 * digit;
}
return '0' + (10 - sum)%10;
}
We're probably ready to make this into a loop now. Once that's passed, we no longer need the short tests, and I have:
#include <iostream>
char checksum(const char *s)
{
int sum = 0;
for (int mul = 1; *s; ++s) {
int digit = *s - '0';
sum += mul * digit;
mul = 4 - mul;
}
return '0' + (1000 - sum)%10;
}
int test(const char *name, char expected, const char *input)
{
char actual = checksum(input);
if (actual == expected) {
std::cout << "PASS: " << name << ": "
<< input << " => " << actual
<< std::endl;
return 0;
} else {
std::cout << "FAIL: " << name << ": "
<< input << " => " << actual
<< " - expected " << expected
<< std::endl;
return 1;
}
}
int main()
{
int failures = 0;
failures += test("Book 1", '3', "978032114653");
failures += test("Book 2", '0', "978020163361");
return failures > 0;
}
I factored out the actual checking into a function here, so we can keep count of failures, and exit with the appropriate status, but everything else is as I described above.
You'll want to add a few more test cases - in particular, make sure the function correctly returns the extreme values 0 and 9 when it should.
There is one clear bug in your code: you are not allocating enough space in for ISBNinput. You should make it one character longer:
const int LENGTH = 13;
The reason for this is that that character-array strings are terminated with an extra null character. You might be lucky and the next byte in memory could sometimes happen to be a null byte, in which case the program would still work sometimes.
If you run the program with valgrind or a similar memory checker you are likely to see an error as the program access memory beyond what was allocated on the stack.
Also I think there is another bug. I think that mul should be initialized to 1.
By the way, this code is very fragile, depending on you entering no more than 12 characters, all of which are assumed to be digits. It might be OK as a quick hack for a proof-of-concept, but should not be used in any real program.

Making a console progress bar? (Windows)

So I have a function (or rather, I'll turn it into a function later) to make a random % progress in a console window; like this:
#include <iostream>
#include <time.h>
#include <cmath>
#include <windows.h>
using namespace std;
int main()
{
srand(time(0));
int x = 0;
for(int i = 0; i<100; i++){
int r = rand() % 1000;
x++;
cout << "\r" << x << "% completed." << flush;
if(i < 43){
Sleep(r/6);
}else if(i > 43 && i < 74){
Sleep(r/8);
}else if(i < 98){
Sleep(r/5);
}else if(i > 97 && i != 99){
Sleep(2000);
}
}
cout << endl << endl << "Operation completed successfully.\n" << flush;
return 0;
}
The thing is, I want the output to be like this:
1% completed
|
(later...)
25% completed
|||||||||||||||||||||||||
How can I do that?
Thanks in advance!
Printing character '\r' is useful. It puts the cursor at the beginning of the line.
Since you can not access to previous line anymore, you can have something like this:
25% completed: ||||||||||||||||||
After each iteration:
int X;
...
std::cout << "\r" << percent << "% completed: ";
std::cout << std::string(X, '|');
std::cout.flush();
Also, you can use: Portable text based console manipulator
I think this looks better:
#include <iostream>
#include <iomanip>
#include <time.h>
#include <cmath>
#include <windows.h>
#include <string>
using namespace std;
string printProg(int);
int main()
{
srand(time(0));
int x = 0;
cout << "Working ..." << endl;
for(int i = 0; i<100; i++){
int r = rand() % 1000;
x++;
cout << "\r" << setw(-20) << printProg(x) << " " << x << "% completed." << flush;
if(i < 43){
Sleep(r/6);
}else if(i > 43 && i < 74){
Sleep(r/8);
}else if(i < 98){
Sleep(r/5);
}else if(i > 97 && i != 99){
Sleep(1000);
}
}
cout << endl << endl << "Operation completed successfully.\n" << flush;
return 0;
}
string printProg(int x){
string s;
s="[";
for (int i=1;i<=(100/2);i++){
if (i<=(x/2) || x==100)
s+="=";
else if (i==(x/2))
s+=">";
else
s+=" ";
}
s+="]";
return s;
}
Use graphics.h or use more advanced WinBGI library. Download it and place the library files and the graphics.h file in appropriate locations in your project. Then just use the function named gotoxy(int x, int y) where x and y are in character places(not pixels) Consider your console window in the 4th quadrant of a Cartesian 2D axes system. But x and y starts typically from 1 upto n(depending on the size of the console window). You just have to clear the screen each time progress happens like this
system("cls");
as cls is the command for this in case of windows. Otherwise for linux/Mac use
system("clear");
Now this function is in stdlib.h header. After that you can easily update the progress bar and write anywhere in it.
But the progress bar you are using is discontinuous. There is more efficient way is to use
# Print iterations progress
def printProgressBar (iteration, total, prefix = '', suffix = '', decimals = 1, length = 100, fill = '█'):
"""
Call in a loop to create terminal progress bar
#params:
iteration - Required : current iteration (Int)
total - Required : total iterations (Int)
prefix - Optional : prefix string (Str)
suffix - Optional : suffix string (Str)
decimals - Optional : positive number of decimals in percent complete (Int)
length - Optional : character length of bar (Int)
fill - Optional : bar fill character (Str)
"""
percent = ("{0:." + str(decimals) + "f}").format(100 * (iteration / float(total)))
filledLength = int(length * iteration // total)
bar = fill * filledLength + '-' * (length - filledLength)
print('\r%s |%s| %s%% %s' % (prefix, bar, percent, suffix), end = '\r')
# Print New Line on Complete
if iteration == total:
print()
#
# Sample Usage
#
from time import sleep
# A List of Items
items = list(range(0, 57))
l = len(items)
# Initial call to print 0% progress
printProgressBar(0, l, prefix = 'Progress:', suffix = 'Complete', length = 50)
for i, item in enumerate(items):
# Do stuff...
sleep(0.1)
# Update Progress Bar
printProgressBar(i + 1, l, prefix = 'Progress:', suffix = 'Complete', length = 50)
# Sample Output
Progress: |█████████████████████████████████████████████-----| 90.0% Complete