#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.
Related
I'm currently learning c++. I got stuck in this little problem with the exception.
A program asks users to enter 5 integers in an array. I need the program to manage an exception that requests the input of an element again if it already exists.
Here is my code, I figured out the global structure, but the problem is if you enter 0 the program will throw out an exception "already exists", that's not the result I wanted. I know where this comes from, T[j] was not defined in for loop, but I don't know how to deal with it. Could anyone help me to improve it, please? other solutions are also welcomed.
#include<iostream>
#include <vector>
#include<cstdlib>
using namespace std;
int main(){
int i=0,j=0;
int temp;
vector<int>T(5);
do{
try{
cout<<"user input "<<(i+1)<<":";
cin>>temp;
//T[j]= 'a000000000000000000'; //I tried to define T[j], that's maximum I can do
for(j=0;j<=i;j++){
if(T[i]==T[j])
throw(0);
}
T[i]=temp;
i++;
}
catch(const int){
cout<<"Error: value already exists, try again"<<endl;
}
} while(i<sizeof(T)/sizeof(int));
for(i=0;i<sizeof(T)/sizeof(int);i++){
cout<<T[i]<<endl;
}
return 0;
}
This line creates a vector which contains 5 ints. All ints in the vector are zero:
vector<int>T(5);
This line runs a loop. Since i is zero, it runs the loop one time, where j is equal to zero, because j<=i is true, because both of them are zero.
for(j=0;j<=i;j++){
This line checks whether T[i] equals T[j], which it does, because i and j are both zero, and T[0] equals T[0].
if(T[i]==T[j])
This line throws an exception.
throw(0);
Did you spot the bug yet? Maybe you don't want to run the loop where j is equal to i. Maybe you want to loop while j<i instead of j<=i. So if i is 5, j goes from 0 to 4 instead of 0 to 5, and if i is 0, the loop does not run at all.
Also, as Mark Ransom pointed out, this is wrong:
sizeof(T)/sizeof(int)
It should be
T.size()
sizeof(T)/sizeof(int) would work for an array, but not for a vector. You want T.size() instead.
If there isn't a requirement for the numbers to be output in the same order as they were input, a std::set (or std::unordered_set) would work well
#include <iostream>
#include <set>
int main()
{
constexpr int NUMBERS_TO_READ{5};
std::set<int> numbers;
int i = 0;
do
{
int temp;
std::cout << "user input " << (i+1) << std::endl;
std::cin >> temp;
if (numbers.find(temp) != numbers.end())
{
//temp is already in the set
std::cout << "Value " << temp << " already exists, try again!" << std::endl;
}
else
{
//temp isn't in the set. add it.
numbers.insert(temp);
i++;
}
}
while (i < NUMBERS_TO_READ);
for (const auto num : numbers) std::cout << num << std::endl;
}
I'm trying to write a code that will take a number that the user inputted and create an inverted triangle like:
8 6 4 2 0 on the first line,
6 4 2 0 on the second line,
4 2 0 on the third line,
2 0 on the fourth line,
0 on the last line.
My nested for loops worked in a previous code that was in the main not in a function, but I decided I wanted to create a function that when called would run through the loops. However, something in my code isn't right since now I don't get an inverted triangle. I just get 0 and I think that's because my return is 0. I'm not sure if I'm writing my function incorrectly or if it's something else.
Please help. Thank you
#include <iostream>
using namespace std;
int row(int num)
{
int number;
int decreasedNumber;
for(int i = number; i >= 0; i -= 2)
{
decreasedNumber = i;
for(int j = decreasedNumber; decreasedNumber >= 0; decreasedNumber -=2)
{
cout << decreasedNumber << " ";
}
cout << endl;
}
return 0;
}
int main()
{
int number;
//Prompting the user to enter a number and collect that input
cout << "Enter a number: " << endl;
cin >> number;
cout << row(number);
return 0;
}
You are accepting num as a parameter to row, but never using it. Also, you are using number, but never initializing it. Instead, it seems you want number to be the parameter to the function, instead of a local variable.
Here's a demo.
Also, the variable j is never used in the loop, so you should just remove it.
Also, please don't use using namespace std;, it's a bad habit that you should avoid.
You are using number as the initial value of i.
number is uninitialized and its value is indeterminate.
Instead of number, you should use the argument num as the initial value of i.
So I'm trying to write a program that reads unknown inputs from a data file that has a sentinel 0 or I guess an termination point for the loop.
Number of integers per line before 0 (int count).
Number of all integers in data file (int totalcount).
Number of lines in data file (int lines).
Two examples of unknown inputs from a data file:
Example One:
1 2 3 0 4 5 6 7 0
Example Two:
0 9 11 -11
1 1 0 0 2
0
Here is my program (without "count" because that is where my problem lies):
int main()
{
//Declaring variables.
int input, lines, count, totalcount, datafile;
lines = 0;
count = 0;
totalcount = 0;
//Loop runs as long as data file has an integer to take in.
while(cin >> datafile)
{
//If datafile is not 0, loop runs until datafile is 0.
while(datafile != 0)
{
//Counts all integers in the file except 0.
totalcount += 1;
cin >> datafile;
}
//Counts how many lines there are in a data file using sentinel 0 (not "/n").
if(datafile == 0)
lines += 1;
//Outputs.
cout << lines << setw(11) << count << setw(11) << totalcount << endl;
}
return 0;
}
Please do not worry about technicality, efficiency, or anything else besides the logic/concept itself as I'm just trying to find the missing link in my knowledge to complete this assignment.
With that said, my expected outputs are as formatted:
"Line #" "Counts of integers per line" "Total counts of all integers in data file"
Using example one with my current code, I would have outputs (spacing is not exact and '.' is for blanks):
1......0......3
2......0......7
Correct expected outputs:
1......3......3
2......4......7
I would like any hints or explanation of how I can count the integers per line (before sentinel 0) and assign that value to "int count" without the value persisting to the next line.
I'm a student in an introductory C++ class so please show me a basic way of how I may go about this first and then any other advanced options as necessary for future applications.
Code of Conduct Personal Statement:
By participating, you are providing necessary knowledge for assignment completion, not completing the assignment itself. The example used is generated by me intended for concept demonstration purposes and is only a small part of the final assignment.
10/23/2016 9:56PM Update 1:
Currently attempting to use a "temp" variable to substract from "totalcount". I will update my code if attempt is successful.
totalcount is sum of counts. This is my suggestion
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
//Declaring variables.
int input, lines, count, totalcount, datafile;
lines = 0;
count = 0;
totalcount = 0;
//Loop runs as long as data file has an integer to take in.
while(cin >> datafile)
{
// Add count to totalcount and reset count each time reach 0
if (datafile == 0) {
totalcount += count;
lines += 1;
cout << lines << setw(11) << count << setw(11) << totalcount << endl;
count = 0;
}
//otherwise increase count
else {
count++;
}
}
return 0;
}
I'm trying to create an array, write array to the file and than display it. It seems to be working but i get just part of the output (first 3 elements) or i get values over boundaries.
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
int arr[20];
int i;
for (i = 0; i < 5; i++)
{
cout << "Enter the value to the array: " << endl;
cin >> arr[i];
}
ofstream fl("numbers.txt");
if (!fl)
{
cout << "file could not be open for writing ! " <<endl;
}
for (i = 0; i < arr[i]; i++)
{
fl<<arr[i]<<endl;
}
fl.close();
ifstream file("numbers.txt");
if(!file)
{
cout << "Error reading from file ! " << endl;
}
while (!file.eof())
{
std::string inp;
getline(file,inp);
cout << inp << endl;
}
file.close();
return 0;
}
The terminating condition in the for loop is incorrect:
for(i=0;i<arr[i];i++)
If the user enters the following 5 ints:
1 0 4 5 6
the for loop will terminate at the second int, the 0, as 1 < 0 (which is what i<arr[i] would equate to) is false. The code has the potential to access beyond the bounds of the array, for input:
10 11 12 13 14
the for loop will iterate beyond the first 5 elements and start processing unitialised values in the array arr as it has not been initialised:
int arr[20];
which could result in out of bounds access on the array if the elements in arr happen to always be greater than i.
A simple fix:
for(i=0;i<5;i++)
Other points:
always check the result of I/O operations to ensure variables contain valid values:
if (!(cin >> arr[i]))
{
// Failed to read an int.
break;
}
the for loop must store the number of ints read into the arr, so the remainder of the code only processes values provided by the user. An alternative to using an array, with a fixed size, and a variable to indicate the number of populated elements is to use a std::vector<int> that would contain only valid ints (and can be queried for its size() or iterated using iterators).
while (!file.eof()) is not correct as the end of file flag will set only once a read attempted to read beyond the end of the file. Check the result of I/O operations immediately:
while (std::getline(file, inp))
{
}
its like hmjd said
for(i=0;i<arr[i];i++)
looks wrong
it should look like this
int size;
size=sizeof(your array);
for(i=0;i<size;i++)
Try this:
//for(i=0;i<arr[i];i++)
for(i=0;i<5;i++)
[EDITED]
I would initialize the array with 0 like this: int arr[20] = {0}; In this case you can use for example:
while ((arr[i] != 0 || i < sizeof(arr))
i<array[i]
It is wrong beacuse it comapres with the content of the array ,it does not check the size of array .
I am newbie to programming and I am trying to pass an array into a function and add all the elements together and return the sum. The problem is that I am getting a garbage value for the sum. I have researched on how to pass arrays to functions and I do not know if I'm supposed to use a pointer to pass arrays. I am not good with pointers anyways.
Here is my code
#include <cmath>
#include <cstdlib>
using namespace std;
float mean(int);
int sum(int ARRZO[5]);
int total;
int main()
{
int ARRZ[5];
char *inname = "example.txt";
ifstream infile(inname);
if (!infile) {
cout << "There was a problem opening file " << inname << " for reading." << endl;
return 0;
}
cout << "Opened " << inname << " for reading." << endl;
for(int i=0; i<11; i++)
{
while (infile >> ARRZ[i])
{
cout << "Value from file is " << ARRZ[i] << endl;
}
}
total=sum(ARRZ);
cout<<"the sum of the elements in the array is"<<total<<endl;
system("PAUSE");
return 0;
}
int sum(int ARRZO[])
{
int sumz=0;
for (int i=0; i<5; i++)
{
sumz+=ARRZO[i];
cout<<ARRZO[i];
}
cout<<sumz<<endl;
return sumz;
}
You are actually reading all the values from the file in ARRZ[0] because of the inner loop. By the time you get to i=1, you are at the end of the file, and not reading anything.
Remove one loop, and increment i when you have read successfully a value.
I'm not sure what you think this pair of nested loops is supposed to do:
for(int i=0; i<11; i++)
{
while (infile >> ARRZ[i])
{
cout << "Value from file is " << ARRZ[i] << endl;
}
}
But (as #aliexisdm pointed out) the inner loop reads the entire content of the file. What he didn't (at least directly) point out is that you're reading every one of those values into the first element of your array. Then you're getting back to the outer loop, incrementing i, and trying to read the file again -- but since the stream's failbit has been set, all your subsequent attempts at reading are guaranteed to fail.
After that, you add up the 5 items in the array, but since you haven't read anything into 4 of them (and never initialized its contents) you end up with the last item you read from the file + 4 garbage values, giving still further garbage as the result (well, usually anyway -- you really have undefined behavior, so the program could crash and burn instead, but with most current computers, you'll just get some meaningless number).
I, however, would advise changing the program a bit more than just removing one loop and incrementing in the loop that's left. Instead, I'd remove all the (explicit) loops, and make some attempt at making real use of what the standard library provides.
You can read the numbers from the file in one fell swoop:
std::ifstream infile(inname);
std::vector<int> ARRZ ((std::istream_iterator<int>(infile)),
std::istream_iterator<int>());
Then you can sum them all with std::accumulate:
int sum = std::accumulate(ARRZ.begin(), ARRZ.end(), 0);
Finally, you can print out the result:
cout << "The sum of the elements in the array is: " << sum << "\n";
Since, however, you only read the values from the file to add them together, you don't really need to store them at all. You could just add them together and print out the result:
cout << "The sum of the elements in the file is: "
<< std::accumulate(std::istream_iterator<int>(infile),
std::istream_iterator<int>(), 0);
The whole job reduced to one step...