C++ Input from user before Output to file - c++

I have this code that should get minimal value and maximal value from user before writing random numbers to a file but it writes to the file and skips the waiting for user input. How to wait and get the user input before writing to file and use the input from the user to write to the file.
Solution: It works except that I have run the following command: g++ randomNumbers.cpp and expected the program to run right after but I forgot to run it manually by running the output file.
#include <iostream>
#include <fstream>
#include <string>
const bool CREATE_FILE = true;
void getMinMax(int&,int&);
void writeFile(std::ofstream&, int&, int&);
int main(){
if (CREATE_FILE){
int min;
int max;
std::ofstream outfile;
getMinMax(min, max);
writeFile(outfile, min, max);
}
}
void getMinMax(int& min,int& max){
std::cout << "Enter min: ";
std::cin >> min;
std::cout << "Enter max: ";
std::cin >> max;
}
void writeFile(std::ofstream& file, int& min, int& max){
file.open("numbers.txt", std::fstream::out);
for (int i = 1; i <= 10; i++){
file << min + (rand() % (int)(max - min + 1));
}
file.close();
}

I don't see any problem with this program. It does what is expected, using Visual Studio 2015 Express. The only bug I see is this:
file << min + (rand() % (int)(max - min + 1));
This appends numbers to the file one after the other, without any separating whitespace. The result for me was the text file containing:
208131917161201920
I'd replace that line with:
file << min + (rand() % (max - min + 1)) << ' ';
By itself, I cannot see how this code does not work on your machine. Try using a different compiler or state the explicit results of the program on your end (e.g. does "numbers.txt" ever get created, and if so, what is inside it if anything?). If this is merely a segment of a larger file, then std::cin is likely reading leftover garbage from the input buffer. Try adding this in the body of getMinMax before requesting user input:
std::cin.ignore(MAX_INT);
std::cin.clear();
And not that this is relevant, but it's not necessary to manually close a file at the end of a function in C++. When std::fstream goes out of scope, its destructor will the close the file automagically. Furthermore, pass ints by value instead of by reference if your function doesn't intend to change them. From the style of your code, I'm guessing you're used to programming in C and are trying to make a switch; it helps to start writing idiomatic C++ code early
EDIT: Try rewriting the getMinMax method as:
#include <sstream>
void getMinMax(int& Min, int& Max)
{
using namespace std;
cin.ignore(MAX_INT);
cin.clear();
string temp;
cout << "Enter min: "
getline(cin, temp);
stringstream(temp) >> Min;
cout << "Enter max: "
getline(cin, temp);
stringstream(temp) >> Max;
//printf("(Min, Max) = (%i, %i)\n", Min, Max); //For debugging
}
This is a verbose but somewhat safer version of what you posted. If this doesn't work, then I don't know what to tell you. If it does work, then my guess is that the input stream was polluted somehow.

I suggest the following:
Fix the missing include: i.e. add include <stdlib.h> to your file.
Open a terminal and navigate to the directory where your randomNrs.cpp file (or whatever you named it) lives.
Compile it: You said you are using g++, so you just run g++ randomNrs.cpp -o randomNrs in that directory - the -o flag will let you name your binary something else than the default a.out. In this example it would be named randomNrs.
Run it: Then run your executable from within that directory by typing ./randomNrs
These where the steps I went through in order to run your program. I'm on RHEL but it should be the same on OS X I think.

Related

warning: 'totalTemp' may be used uninitialized in this function and cout not printing to console

Trying to write a program displaying the average temperature in 24 hours, by the user typing in the temperature each hour. However, I'm just getting this error in code blocks:
warning: 'totalTemp' may be used uninitialized in this function [-Wmaybe-uninitialized]|.
and the console is just black when ran and not displaying anything.
#include <iostream>
using namespace std;
int main(void)
{
int i = 0;
while(i <= 24);
int newTemp;
int totalTemp;
{
cout << "Input temperature for the hour " << i << ":";
cin >> newTemp;
totalTemp = totalTemp + newTemp;
i++;
cout << "The average temperature for the day is " << totalTemp/24 << " degrees";
}
return (0);
}
How do I initialize it? and what is making my code not appear in the console when I'm trying to use cout?
How do I initialize it?
int totalTemp = 0;
and what is making my code not appear in the console when I'm trying to use cout?
while(i <= 24);
This is an infinite loop with an empty body. Infinite loops without observable side effects are undefined behavior. The compiler is allowed to produce the same output for your code as it would for int main() {}. You probably want while( i<=24) { .... Or rather use a for loop when the number of iterations is fixed.
Moreover, totalTemp/24 is using integer arithmetics. Maybe thats what you want, but more likely you want totalTemp/24.0. And also very likely you want to print the average outside of the loop instead of printing it in every iteration.

g++ printed undesired 00000, why?

Below is my code;
int main(){
ifstream infile;
infile.open(fin);
ofstream outfile;
outfile.open(fout);
char c;
int input_order = 0;
string comp_str = "";
vector <string> pfx_str;
srand(time(NULL));
if (infile.fail())
{
cout << "cannot open file!" << endl;
return 0;
}
while (!infile.fail())
{
cout << input_order << endl;
c = infile.get();
if (c == '\n')
{
if (strcmp(comp_str.c_str(), "") != 0)
{
pfx_str.push_back(comp_str);
}
int num = rand() % pfx_str.size();
while (num == 0)
{
num = rand() % pfx_str.size();
}
for (int i = 0; i < num; i++)
{
outfile << "/" << pfx_str.at(i);
}
outfile << "\n";
input_order++;
pfx_str.clear();
}
else if (c == '/')
{
if (comp_str != "")
{
pfx_str.push_back(comp_str);
}
comp_str = "";
}
else
{
comp_str = comp_str + c;
}
}
infile.close();
outfile.close();
return 0;
}
For small set which consist of 10k inputs, it works.
However, for big set such as using 1600k inputs, it prints out 00000, and does not work. What makes it happened? and how to make it correctly working?
(Previously, I used this code for 1600k input and it works correctly....)
In compile, I used g++ -std=gnu++0x .....
I googled this issue but could not find out the right answer.. And also I could not figure out what this issue comes from....
Thanks,
+
This code is for randomly cutting the input.
This is the example of 1 input set; (to show the input pattern)
/aa/ab/bc/aaa/
Here, I consider 'aa', 'ab', 'bc', and 'aaa' as one component.
And I want randomly cut this input as components unit.
this is the brief step of the code;
1. generate the random number(except 0)
2. ex) I use the above input and the random number is 2.
then I cut this input and only '2' components is left, which is /aa/ab/
(repeat this procedure for each inputs in input text file
=> this input; /aa/ab/bc/aaa/
(inside, it generate random number 2)
output to be printed in output file; /aa/ab/
There is nothing wrong with your code.
I updated your code so that it compiles with g++:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
int main(){
ifstream infile;
infile.open("fin.txt"); // substituted a real file name in here to test
ofstream outfile;
outfile.open("fout.txt"); // ditto here
...the rest is the same as what you put above.
named it test.cpp, and compiled it with:
g++ -lm test.cpp -o test.exe
I wrote a Ruby script to make the input file according to the test set you specified in the comments:
#!/usr/bin/env ruby
File.open( 'fin.txt', 'w') do |f|
1600000.times do
f << "/aa/ab/bc/aaa/\n"
end
end
I then ran the compiled program test.exe, and you totally owe me a beer for watching your line numbers go that high. This is time spent from my life for you that I will never get back. 😂
and got an expected fout.txt with
/aa
/aa/ab
/aa
/aa/ab
/aa/ab/bc
/aa/ab/bc
/aa/ab
/aa/ab/bc
/aa/ab
etc.
My guess is that your system's constraints are causing a system fault. I ran this on a typical desktop machine with a ton of memory, etc. If you're running it on an embedded system, it may not have similar resources. At this point, I was tempted to test on a Raspberry Pi, but I'm burning too much time on this already. Just know that there is nothing wrong with your code.
In the future, try to figure out what your coding problem is. Stack Overflow is super forgiving if you've really tried and can't figure out the solution, but you need to show what you've tried and what happened as a result. For problems that started out like this, where you think that you're trying to figure out an algorithmic problem, always give the data set and the unexpected result that occurred.
Good luck!

beginner C++ importing file, finding sum and average

I'm new to C++ and not sure where to start importing a txt file with 100 numbers, then to make a code to find the sum and average of up to 100 numbers
Can anybody help?
Actually, you already have given the answer yourself. First, find out how to read a file. Then, find out how to convert the text in the file to numbers (you will have to decide what kind of number, like integers, floats or complex). Then, summing up the numbers and computing the average are the next two steps.
Just take one step at a time and make sure you always only try small tasks that you can comprehend in isolation. Even when writing something bigger, it often pays to create a simple test example for one small task first. Also, creating a small test example is a prerequisite to posting at Stack Overflow, see the guidelines for further info.
I hope, this example will help you:
#include <iostream>
#include <fstream>
#include <string>
#include <stdlib.h>
using namespace std;
/* file.txt
2
3
4
6
*/
int main()
{
string line;
ifstream file("file.txt"); // reading from file: http://www.cplusplus.com/doc/tutorial/files/
if (file.is_open())
{
int sum = 0;
while (getline(file, line))
{
int num = atoi(line.c_str()); // convertion from string into int with 'atoi': http://www.cplusplus.com/reference/cstdlib/atoi/
sum += num;
}
file.close();
cout << "Sum is " << sum << endl; // Sum is 15
}
else
{
cout << "Unable to open file" << endl;
}
return 0;
}

Output from array is wrong

#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <fstream>
using namespace std;
void make_array(ifstream &num, int (&array)[50]);
int main(){
ifstream file; // variable controlling the file
char filename[100]; /// to handle calling the file name;
int array[50];
cout << "Please enter the name of the file you wish to process:";
cin >> filename;
cout << "\n";
file.open(filename);
if(file.fail()){
cout << "The file failed to open.\n";
exit(1);
}
else{
cout << "File Opened Successfully.\n";
}
make_array(file, array);
file.close();
return(0);
}
void make_array(ifstream &num, int (&array)[50]){
int i = 0; // counter variable
while(!num.eof() && i < 50){
num >> array[i];
i = i + 1;
}
for(i; i>=0; i--){
cout << array[i] << "\n";
}
}
Alright, so this it my code so far. When I output the contents of the array, I get two really large negative numbers before the expected output. For example, if the file had 1 2 3 4 in it, my program is outputting -6438230 -293948 1 2 3 4.
Can somebody please tell me why I am getting these ridiculous values?
Your code outputs the array backwards, and also it increments i twice after it has finished reading all the values. This is why you see two garbage values at the start. I suspect you are misreporting your output and you actually saw -6438230 -293948 4 3 2 1.
You end up with the extra increments because your use of eof() is wrong. This is an amazingly common error for some reason. See here for further info. Write your loop like this instead:
while ( i < 50 && num >> array[i] )
++i;
Now i holds the number of valid items in the list. Assuming you do actually want to output them backwards:
while ( i-- > 0 )
cout << array[i] << "\n";
To output them forwards you'll need two variables (one to store the total number of items in the array, and one to do the iteration)
The check !num.eof() only tells you that the last thing you read was not eof. So, if your file was 1 2 3 4, the check will only kick in after the 5th num>>array[i] call. However, for that i, array[i] will be populated with a meaningless value. The only correct way to deal with eofs is to check for validity on every call to operator>>. In other words, the right condition is simply num>>array[i]. This works by exploiting this conversion to bool since C++11 and to void* pre-C++11.

Error in outputting to a file in C++ that I can't find

Not as in "can't find the answer on stackoverflow", but as in "can't see what I'm doing wrong", big difference!
Anywho, the code is attached below. What it does is fairly basic, it takes in a user created text file, and spits out one that has been encrypted. In this case, the user tells it how many junk characters to put between each real character. (IE: if I wanted to encrypt the word "Hello" with 1 junk character, it would look like "9H(eal~l.o")
My problem is that for some reason, it isn't reading the input file correctly. I'm using the same setup to read in the file as I had done previously on decrypting, yet this time it's reading garbage characters, and when I tell it to output to file, it prints it on the screen instead, and it seems like nothing is being put in the output file (though it is being created, so that means I've done something correctly, point for me!
code:
string start;
char choice;
char letter;
int x;
int y;
int z;
char c;
string filename;
while(start == "enc")
{
x = 1;
y = 1;
cout << "How many garbage characters would you like between each correct character?: " ;
cin >> z;
cout << endl << "Please insert the name of the document you wish to encrypt, make sure you enter the name, and the file type (ie: filename.txt): " ;
cin >> filename;
ifstream infile(filename.c_str());
ofstream outfile("encrypted.txt", ios::out);
while(!infile.eof())
{
infile.get(letter);
while ((x - y) != z)
{
outfile << putchar(33 + rand() % 94);
x++;
}
while((x - y) == z)
{
outfile << letter;
y = 1;
x = 1;
}
}
outfile.close();
cout << endl << "Encryption complete...please return to directory of program, a new file named encrypted.txt will be there." << endl;
infile.close();
cout << "Do you wish to try again? Please press y then enter if yes (case sensitive).";
cin >> choice;
What I pasted above the start of the while loop are the declaration variables, this is part of a much larger code that not only will encrypt, but decrypt as well, I left the decryption part out as it works perfectly, it's this part I'm having an issue with.
Thanks in advance for the assist!
EDIT:: I'm using visual C++ express 2008, and it shoots back that there are no errors at all, nor any warnings.
IMPORTANT EDIT
It turns out it is outputting to the file! However, it is outputting numbers instead of ascii characters, and it is also outputting the garbage character for the letter it should be. When it goes back to the "infile.get(letter)", it doesn't get a new character. So right now it seems to be the issues are 2 fold:
1) Printing numbers instead of ascii characters.
2) Using garbage instead of the actual character it should be getting.
Question Answered
Found out the second part in the "Important Edit" ...it turns out if you name something test.txt...that means it is actually called test.txt.txt when you type it into a C++ program. Just goes to show it's the tiny, minute, simple details that cause any program to go pooey.
Thank you to George Shore. Your comment about the input file being in the wrong place is what gave me the idea to try the actual items name.
Thank you to everyone who helped with the answer!
Further to the previous answers, I believe it's because the file you wish to encrypt is not being found by the original code. Is it safe to assume that you're running the code from the IDE? If so, then the file that is to be encrypted has to be in the same directory as the source.
Also:
outfile << putchar(33 + rand() % 94);
seems to be the source of your garbage to the screen; the 'putchar' function echoes to the screen whilst returning the integer value of that character. What is then going to happen is that number will be output to the file, as opposed to the character.
Changing that block to something like:
while ((x - y) != z)
{
c = (33 + rand() % 94);
outfile << c;
x++;
}
should enable the code to run as you want it to.
Rather than doing this:
while (!infile.eof())
{
infile.get(letter);
if (infile.good())
{
Do this:
while (infile.get(letter))
{
This is the standard pattern for reading a file.
It gets a character and the resulting infile (that is returned by get) is then checked to see if it is still good by converting it to bool.
The line:
outfile << putchar(33 + rand() % 94);
Should probably be:
outfile << static_cast<char>(33 + rant() % 94);
putchar() prints to the standard output. But the return value (same as the input) goes to the outfile. To stop this just convert the value to char and send to outfile.
Is the use of 'y' necessary? It seems confusing and unnecessary to me. If I were implementing this, then I'd expect to use just 'x' and 'z'.
I'm also not sure about the 'while (!infile.eof())' condition; Pascal determines EOF ahead of time, but C++ can only tell you about EOF after attempting to read a character. However, this would only affect the end of the file, not the main body of the loop.
while (!infile.eof())
{
infile.get(letter);
if (infile.good())
{
for (int i = 0; i < z; i++)
outfile << putchar(33 + rand() % 94);
outfile << letter;
}
}
(Uncompiled code!).
Also, do not use this for security - it may help a little, but it certainly won't conceal the information from the determined.