I'm struggling with a class assignment. I've tried writing this several ways, I'm extremely confused.
Assignment:
Read in ten integer values from a from a file, and store them in an
array or vector. The program you will write will read and store the
last ten values read from a temperature gauge. The reading of the
values should be done in a separate function that takes an integer
array as a parameter, and read from a file named tempInput.txt:
example: void readData(int tempArray[]) The file numbers will be on
consecutive lines. Then, from main, you will call another function,
whose signature and return type is thus: bool isDangerous(int
tempArray[]); The function is dangerous will sum the values in the
tempArray and divide by 10 storing the result (average) in another
variable of the appropriate data type. Then, if the temperature is
greater than 100, the function should return true. if it is 100 or
less, it should return false. in main, you should use the function in
a way such that you print: the temp is ok (if return false) or, the
temp is too hot (if > 100)
If I write a function readData(int array[]) then I must already an array to pass as the argument.
But, the entire purpose of this function is to read from file, THEN create the array. Do I need to write a placeholder temp. array?
Do I need to make the array a string then parse to int or double?
My non-working start is:
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
//prototypes
void readTemp();
int main()
{
int allTemp[10];
readTemp();
}
void ReadTemp()
{
ifstream in_File;
int inNumbers[10];
double average;
in_File.open("tempInput.txt");
for(int i = 0; i < 10; ++i)
{
in_File>>inNumbers[i];
average = inNumbers[i++]/i;
}
cout<< average <<endl;
}
Thanks for any tips. I couldn't get the file read in working so I haven't started on the function that will average the data and return bool.
"entire purpose of this function is to read from file, THEN create the array"
No! You have to have an array beforehand. Either it's big enough, to read in all the data from file, or you have to use dynamic memory management.
Better though, you use some appropriate container like std::vector<int> to receive the data while reading from the file.
Related
We are trying to return an array of structures to print the contents in the main. When debugging the code, we get to the line right before the return statement and it shows that it is holding the right contents which is an int and then a string (playerID and name). As soon as the return statement executes the array is returned to the main but only the playerID is held in the array. All of the values for name have been lost. Can someone explain why this would happen and a possible solution? If further clarification is needed please let me know.
#include<iostream>
#include<fstream>
#include<cstring>
#include<string>
#include<math.h>
using namespace std;
struct Player
{
int playerID;
string name;
};
Player *fillPlayers();
int main()
{
Player *myPlayerPointer;
myPlayerPointer = fillPlayers();
return 0;
}
Player * fillPlayers() {
ifstream file1;
Player * fullPlayerPointer = new Player[244];
Player ourPlayers[244];
file1.open("Players.txt");
if (file1.fail()) {
cerr << "file1 did not open";
}
if (file1.is_open()){
while (!file1.eof()){
string size;
getline(file1, size);
for(int i = 0; i < 244; i++){
file1 >> ourPlayers[i].playerID;
file1 >> ourPlayers[i].name;
}
}
file1.close();
}
fullPlayerPointer = &ourPlayers[0];
return fullPlayerPointer;
}
This code looks a lot like C code. In C++ we have fancy RAII containers like std::vector and std::array that will do exactly what you want.
As for the issue, you are not returning an array, instead you are returning a pointer to an int. You should check out What is array decaying?.
http://en.cppreference.com/w/cpp/container/vector
http://en.cppreference.com/w/cpp/container/array (C++ >= 11)
The generally correct answer is use a std::vector as it assists in managing ownership and the lifetime of storage as well as tracking the capacity and resizing itself as needed. But let's take a walk through fillPlayers to explain what is going wrong.
Player * fillPlayers()
{
ifstream file1;
Player * fullPlayerPointer = new Player[244];
Dynamically allocated 244 Players. Dynamic storage has manually controlled lifetime and will remain valid until such time as it is freed. Unfortunately this allocated storage is never used and not put away correctly later with delete[] This allocation will be "leaked". As dire as this sounds, this is the "right" way to allocate the storage, but as we will see, the function uses it incorrectly.
Player ourPlayers[244];
Statically allocated 244 Players as a temporary variable. This variable will only exist inside the innermost set of surrounding curly braces {}. Afterward it will be rendered invalid. This means that references to ourPlayers should not be returned from this function as ourPlayers will be rendered invalid at the return from the function and before the caller can make use of it.
file1.open("Players.txt");
if (file1.fail())
{
cerr << "file1 did not open";
}
Always test before using, so the above is almost right. It is rendered redundant by the next line performing a nearly identical test. This could be a good place to put an else, but the code is more easily read with if (file1.is_open()) followed by an else to print the error message if it is not open.
Why do I say this? Because the programmer's intent with is_open is much easier to discern than with the broader term fail.
if (file1.is_open())
{
while (!file1.eof())
Read Why is iostream::eof inside a loop condition considered wrong? for details on why this is almost always the wrong solution to looping through a file.
{
string size;
getline(file1, size);
Always test a read to ensure it succeeded. In addition, the file size was read and then not converted into an integer to use in the loop that follows.
for (int i = 0; i < 244; i++)
Regardless of how many entries there are in this file 244 will always be read. If the file does not have at least 244 entries, the read will fail and as the reads are not being checked for success, garbage will be stored in the array.
Also note that there is a loop iterating through 244 entries in the file that is surrounded by a loop that will attempt to read again until the EOF flag is set. Most likely you only want one such loop.
{
file1 >> ourPlayers[i].playerID;
file1 >> ourPlayers[i].name;
}
}
file1.close();
}
fullPlayerPointer = &ourPlayers[0];
The pointer to the dynamic allocation made earlier is overwritten by a pointer to the temporary allocation ourPlayers. A reference to long-term storage has been replaced by a reference to storage that is about to go out of scope and become invalid.
It is possible that OP intended this to copy the data in the short term storage to the long term storage, but unfortunately that's not what the compiler was told to do, and it's not really worth doing. It would be much more useful to directly read the file into the long term storage.
return fullPlayerPointer;
Returns from the function and gives an invalid array to the caller.
}
Lot to fix in there.
Here's a very simple approach that fixes all of the above problems but exposes a few more:
Player * fillPlayers()
{
ifstream file1("Players.txt");
Player * players = nullptr;
if (file1.is_open())
{
int size;
if (file1 >> size)
{
players = new Player[size];
int index = 0;
while (file1 >> players[index].playerID >> players[index].name
&& index < size)
{
}
// extra brains needed here to handle premature read failure.
}
file1.close();
}
else
{
cerr << "file1 did not open";
}
return players; // only a pointer to the array was returned. How big the
// array is and how many items are actually in it is lost
}
This is where std::vector really becomes awesome. It knows how big it is and how full it is. An array doesn't.
Now, assuming std::vector is not allowed, and Paul McKenzie has already covered what to do if it isn't, the smart thing to do is make a very simple wrapper around the array to get some modicum of the safety and ease of use vector provides.
class stupidvector
{
Player *players;
size_t capacity; // a typical vector implementation uses a pointer for
// this to make iteration easier
size_t size; // vector uses pointer here, too.
public:
stupidvector();
stupidvector(size_t size);
// correctly copy a stupid vector Rule of Three. In this case, don't
// allow it to be copied.
stupidvector(const stupidvector& src)=delete;
// correctly move a stupid vector Rule of Five
stupidvector(stupidvector && src);
// release storage
~stupidvector();
// add an item to the end
void push(const Player & player);
// how big is it?
size_t getcapacity();
// how full is it?
size_t getsize();
// make it act like an array
Player & operator[](size_t index);
// correctly assign. Rule of Three. again we don't want to copy these,
// but if we did, look at Copy and Swap Idiom for a neat solution
stupidvector& operator=(const stupidvector& src) = delete;
// correctly move
stupidvector& operator=(stupidvector && src);
};
Pay special attention to the Rules of Three and Five
I have been given following assignment
Write a simple telephone directory program; contain two dimensional arrays in which you have hard code names and telephone number. Then declare a simple character array. You have to prompt user to enter any name, which you want to search. This name should be store in this character array, then search this name from the two dimensional array. If number is found against entered name then program should display the number against this name, and if not found then program should display the message that name is not registered.
Here is my code but i could not get the number when i search for the name. I am new to coding so i am having trouble making this code work. Help is appreciated.
#include <iostream>
#include <conio.h>
using namespace std;
int getPhone(int p[5][10],int row, int col, char key[10],char n[5][10]);
int main() {
int i,j;
char search[10];
const int r = 5;
const int c = 10;
int element;
int phone[r][c] =
{
42-5429874,
42-5333156,
42-9824617,
42-9927562,
42-6238175
};
char name[r][c] = {"shazia","zara","sana","ahmad","maha"};
cout<<"\nEnter name to find in directory : ";
cin>>search[r];
element = getPhone(phone,r,c,search,name);
cin.get();
return 0;
}
int getPhone(int p[5][10],int row,int col,char key[10], char n[5][10]) {
int i, j;
for(i=0;i<row;i++)
for(j=0;j<col;j++)
p[5][10] = p[i][j];
if(key[j] = n[5][10])
cout<<"The desired number is: "<<p[i][j]<<endl;
else if(key[j]!=n[5][10])
cout<<"Sorry! This name is not registered.";
return p[i][j];
}
Your code contains several mistakes. Let's examine them.
for(i=0;i<row;i++)
for(j=0;j<col;j++)
p[5][10] = p[i][j];
Here, you make no change on your array, because just the value of p[5][10] is changed. Furthermore, you access an invalid memory zone, because array indexes go from 0 to size - 1 in C++. So last index is p[4][9].
if(key[j] = n[5][10])
In C++, comparing two values needs two =, because only one is an affectation that results the if to be always true. A tip to remember: two values to compare need two =.
else if(key[j]!=n[5][10])
The same than before, you access invalid memory zone. And are you sure that j is valid, e.g less than 10 ? If not, you do double invalid access.
cin>>search[r];
As search is an array of char, you do an input of only a single char there, which I think is not what you want and that can leads to segfault.
int phone[r][c] =
{
42-5429874,
42-5333156,
42-9824617,
42-9927562,
42-6238175
};
Your array is not good, a simple 1-dimension array is enough, not 2-dimensions. Furthermore, 42-54.. does a subtraction, and I think is not what you want.
There are others mistakes. But why not using C++ abstractions, like std::vector, or std::string? Your life would get so much easier. But I guess you have an old teacher that never took time to learn C++ news, or that is not a good teacher.
As a beginner, I suggest you to read C++ Primer and Programming: Principles and Practice Using C++ to introduce you both programming and modern C++.
I have a question regarding a school lab assignment and I was hoping someone could clarify this a little for me. I'm not looking for an answer, just an approach. I've been unable to fully understand the books explanations.
Question: In a program, write a function that accepts three arguments: an array, the size of the array, and a number n.
Assume that the array contains integers. The function should display
all of the numbers in the array that are greater than the number n .
This is what I have right now:
/*
Programmer: Reilly Parker
Program Name: Lab14_LargerThanN.cpp
Date: 10/28/2016
Description: Displays values of a static array that are greater than a user inputted value.
Version: 1.0
*/
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
void arrayFunction(int[], int, int); // Prototype for arrayFunction. int[] = array, int = size, int = n
int main()
{
int n; // Initialize user inputted value "n"
cout << "Enter Value:" << endl;
cin >> n;
const int size = 20; // Constant array size of 20 integers.
int arrayNumbers[size] = {5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24}; // 20 assigned values for the array
arrayFunction(arrayNumbers, size, n); // Call function
return 0;
}
/* Description of code below:
The For statement scans each variable, if the array values are greater than the
variable "n" inputted by the user the output is only those values greater than "n."
*/
void arrayFunction(int arrayN[], int arrayS, int number) // Function Definiton
{
for (int i=0; i<arrayS; i++)
{
if (arrayN[i] > number)
{
cout << arrayN[i] << " ";
cout << endl;
}
}
}
For my whole answer I assume that this:
Question: In a program, write a function that accepts three arguments: an array, the size of the array, and a number n. Assume that the array contains integers. The function should display all of the numbers in the array that are greater than the number n .
is the whole assignment.
void arrayFunction(int[], int, int); is probably the only thing you could write. Note however that int[] is in fact int*.
As others pointed out don't bother with receiving input. Use something along this line: int numbers[] = {2,4,8,5,7,45,8,26,5,94,6,5,8};. It will create static array for you;
You have parameter int n but you never use it.
You are trying to send variable to the function arrayFunction but I can't see definition of this variable!
Use something called rubber duck debugging (google for it :) ). It will really help you.
If you have some more precise question, ask them.
As a side note: there are better ways of sending an array to the function, but your assignment forces you to use this old and not-so-good solution.
Would you use an if else statement? I've edited my original post with the updated code.
You have updated question, then I update my answer.
First and foremost of all: do indent your code properly!!!
If you do that, your code will be much cleaner, much more readable, and it will be much easier understandable not only for us, but primairly for you.
Next thing: do not omit braces even if they are not required in some context. Even experienced programmers only rarely omit them, so as a beginner you should never do so (as for example with your for loop).
Regarding if-else statement the short answer is: it depends.
Sometimes I would use if (note: in your case else is useless). But other times I would use ternary operator: condition ? value_if_true : value_if_false; or even a lambda expression.
In this case you should probably settle for an if, as it will be easier and more intuitive for you.
Aside from the C++ aspect, think about the steps you need to do to figure out if a number is greater than a certain value. Then do that for all the numbers in the array, and print out the number if it's greater than n. Since you have a 'for' loop, it looks like you already know how to do a loop and compare numbers in C++.
Also, it looks like in your arrayFunction you are trying to input values? You can't input a whole array's worth of values in a single statement like you appear to be trying (also, 'values' is not the name of any variable in arrayFunction, so that would not be recognized when you try to compile it).
This question already has answers here:
Passing a 2D array to a C++ function
(18 answers)
Closed 9 years ago.
I wrote a little programm and I can't pass two-dimensional array words[10][max_row_size] to function notify. Please help me if you can. a part of code attached.
#include <iostream>
#include <cstdlib>
#include <fstream>
#include <string.h>
#include <unistd.h>
using namespace std;
#define max_row_size 100
int notify(char words[max_row_size]);
int main(void) {
ifstream dictionary("dictionary.txt");
//ditrionary looks like
//hello-world
//universe-infinity
//filename-clock
string s;
int i=0;
char words[10][max_row_size];
while(!dictionary.eof()){
dictionary>>s;
strcpy(words[i++],s.c_str());
}
notify(words[max_row_size]);
return 0;
}
int notify(char words[max_row_size]){
cout<<words[1];
return 0;
}
It is a full code of my programm, may be it can help you
It is an errors
/home/rem/projects/github/notify_words/notify_words.cpp: В функции «int notify(int, char*)»:
/home/rem/projects/github/notify_words/notify_words.cpp:65:113: предупреждение: format «%s» expects argument of type «char*», but argument 3 has type «int» [-Wformat]
You pass words on its own: char** words is the argument in the function: i.e.
int notify(char** words){...
Easiest way for 2 dimensional array (obviously, you can typedef your array):
int notify(std::array<std::array<char, max_row_size>, 10>& words){
std::cout << words[1];
return 0;
}
Easiest for an array of strings:
int notify(std::array<std::array<std::string>, 10>& words){
std::cout << words[1];
return 0;
}
This way prevents that the array is decayed to a pointer in the function, so the size is still known.
notify(char words[][max_row_size])
to pass the whole array down
then use notify(words); to call the method
But really you should be using standard containers instead of arrays
I'm guessing you want notify to print just one word, so you need to change notify to
int notify(char* word){
cout<<word;
return 0;
}
But also the way you're calling notify will probably not produce the results you're after.
notify(words[max_row_size]);
Will try to get you the 100th word out of 10. Which will probably cause a crash.
You probably want to place notify last in your while loop and call it like this
notify(words[i]);
Also, if you have more than 10 words in your dictionary, you're in trouble. You might want to try a vector instead of an array (because vectors can grow dynamically).
I'm new to C++ and am not sure what's wrong. This is a task I have been given in my programmging course at uni which is meant to take user input of a vector of grades and determine whether the grade is a passing one. When I compile I end up getting an error stating q1.cpp:30:21: error: could not convert ‘y’ from ‘int’ to ‘std::vector’
Not overly sure why. Sorry about the bad formatting.
I've added the code but not sure how to wrap it.
#include <vector>
#include <cstdlib>
#include <iostream>
using namespace std;
int calcNumberOfPasses(vector<int> grades){
int x;
for (int i=0; i<grades.size(); i++){
cin >>grades[i];
}
cin >> x;
}
int main() {
int y;
vector<int> nGrade;
nGrade.push_back(y);
cout << "Enter how many grades you want to enter";
for (int i=0; i<nGrade.size();i++){
cin >> nGrade[i];
}
cin >> y;
if (y>=50){
cout << "this is a passing grade";
}
calcNumberOfPasses(y);
}
The function calcNumberOfPasses is expecting a parameter of type vector<int>, you are passing it a parameter of type int. That much you can work out from the error message.
You are copying an undefined value into the vector on this line:
nGrade.push_back(y); // y hasn't been initialised yet, you probably want to remove this line.
Following that you are looping over the size of the grades vector, which hasn't been initialised yet.
Chances are, you want to do calcNumberOfPasses(nGrades);.
As an aside, you should use a reference to the vector, to avoid copying it.
In summary, I would through all of this code away and start again. No offence!
A vector is a collection -- a grouping of items of some base class. It's conceptually similar to an array. What you are doing is trying to repeatedly load a single variable and then pass that into a function that expects a vector.
Try breaking down the steps of the function you're writing. You are:
Adding a single, uninitialized int to a vector.
Trying to retrieve a number to control the number of grades you want to enter.
Reading a single additional number into y.
Passing that single number into a function that expects an array.
There are numerous things wrong with this function; I think you need to map out what data needs to go where.