1 void out3x3(mat3x3 &A)
2 { int i, j;
3 for (i=0; i<3; i++)
4 { if (i==1)
5 cout << "A = | ";
6 else
7 cout << " | ";
8 for (j=0; j<3; j++)
9 cout << A.n[j][i] << " ";
10 cout << "|" << endl;
11 }
12 }
This is a function in a program I'm writing to do matrix manipulations. mat3x3 is a structure for a 3x3 matrix (stored as A.n[3][3]. Instead of 'A' in the output in line 5, I'd like it to output the name of whatever variable I used for the matrix in the calling function.
I only use A, B, and C. I could just write three different functions, but I feel like there should be a better way to do it.
If I say out3x3(B); it will only show A = | |.
I would like this to happen:
out3x3(B);
B = | |
out3x3(C);
C = | |
Thanks for any help.
Names of variables do not exist at run time. They are simply compile time constructs. You would need to do something like change the function to take a std::string argument too:
void out3x3(mat3x3 &A, std::string name)
{
// ...
cout << name << " = | ";
// ...
}
Then call it like so:
out3x3(A, "A");
out3x3(B, "B");
You could then use a macro to make this feel like you're not duplicating the variable name. However, I don't recommend this at all. Instead, I recommend just making your function print out the contents of the matrix (between the |s) and then doing this:
cout << "A = ";
out3x3(A);
The printing of the variable name should be entirely independent of printing out the contents of the matrix. Consider the following analogy:
int x = 5;
cout << x;
This just prints out the value of x, nothing else. If I want to label it, I have to do that manually:
int x = 5;
cout << "x = " << x;
And who knows? Maybe you'll get round to overloading operator<< for your mat3x3 type and soon you'll be doing this:
cout << "A = " << A;
Much prettier.
You could use a macro as a wrapper to call it
#define OUT3X3(mat) \
out3x3(&mat, ##mat);
and change the function prototype to
void out3x3(mat3x3 &A, string name)
The call would be
OUT3X3(A);
Related
I'm trying to convert a for loop to while loop in c++ and do some checking for duplicates in a random number generator for generating lotto numbers so far all the stuff i'm trying seems to make the compiler very unhappy and I could really use a few pointers. It's the for loop in the Harray() function that feeds the Balls[] array
that i want to convert to a while loop.
#include<iostream>
#include<cstdlib> // to call rand and srand.
#include<ctime> // to make rand a bit more random with srand(time(0)) as first call.
#include<iomanip> // to manipulate the output with leading 0 where neccesary.
using namespace std;
// Hrand() function create and return a random number.
int Hrand()
{
int num = rand()%45+1; // make and store a random number change 45 for more or less Balls.
return num; // return the random number.
}
// Harray() function create and fill an array with random numbers and some formatting.
void Harray()
{
int Balls[6]; // change the number in Balls[6] and in the for loop for more or less nrs. a row.
for(int x=0; x<=6; x++) //the loop to fill array with random numbers.
{
int a; // made to pass the Balls[x] data into so i can format output.
int m = Hrand(); // calling the Hrand() function and passing it's value in int m.
Balls[x] = m; // throwing it into the array tought i did this because of an error.
a = Balls[x]; // throwing it into int a because of an type error.
cout<<"["<<setfill('0')<<setw(02)<<a<<"]"; //format output with leading 0 if neccesary.
}
cout<<endl; // start new row on new line.
}
// Main function do the thing if compiler swallows the junk.
int main() // start the program.
{
int h; // int to store user cchoice.
srand(time(0)); // make rand more random.
cout<<"How many rows do you want to generate?"<<endl; // ask how many rows?
cin>>h; // store user input.
for(int i=h; h>0; h--) // produce rows from user input choice.
{
Harray(); // calling Harray function into action.
}
return 0; // return zero keep the comipler happy.
}
I would like to always have six diffrent numbers in a row but i don't see how to get there with the for loops i think the while loop is way to go but am open to any suggestion that will work. I'm just starting with c++ i might have overlooked some options.
int x=0;
while(x<6)
{
int a;format output.
int m = Hrand();value in int m.
Balls[x] = m; because of an error.
a = Balls[x];
cout<<"["<<setfill('0')<<setw(02)<<a<<"]";
x++;
}
Here, I also fixed a bug. Since Balls has 6 elements, the last element will be 5. Thus you want x<6 instead of x<=6. That goes for the for loop too.
One drawback of while loops is that you cannot declare local variables with them.
First of all, you should realize that the difference between a for loop and a while loop is mostly syntactic--anything you can do with one, you can also do with the other.
In this case, given what you've stated as your desired output, what you probably really want is something like this:
std::vector<int> numbers;
std::set<int> dupe_tracker;
while (dupe_tracker.size() < 6) {
int i = Hrand();
if (dupe_tracker.insert(i).second)
numbers.push_back(i);
}
The basic idea here is that dupe_tracker keeps a copy of each number you've generated. So, you generate a number, and insert it into the set. That will fail (and return false in retval.second) if the number is already in the set. So, we only add the number to the result vector if it was not already in the set (i.e., if it's unique).
How convert for-loop to while-loop
#include <iostream>
class T545_t
{
// private data attributes
int j;
public:
int exec()
{
// A for-loop has 3 parameters, authors often fill 2 of them with magic
// numbers. (magic numbers are usually discouraged, but are expected
// in for-loops)
// Here, I create names for these 3 for-loop parameters
const int StartNum = 2;
const int EndNum = 7;
const int StrideNum = 2;
std::cout << std::endl << " ";
for (int i = StartNum; i < EndNum; i += StrideNum ) {
std::cout << i << " " << std::flush;
}
std::cout << std::flush;
// A while-loop must use / provide each of these 3 items also, but
// because of the increased code-layout flexibility (compared to
// for-loop), the use of magic numbers should be discouraged.
std::cout << std::endl << " ";
j = StartNum;
do {
if (j >= EndNum) break;
std::cout << j << " " << std::flush;
j += StrideNum;
} while(true);
std::cout << std::flush;
std::cout << std::endl << " ";
j = StartNum;
while(true) {
if (j >= EndNum) break;
std::cout << j << " " << std::flush;
j += StrideNum;
}
std::cout << std::flush;
std::cout << std::endl << " ";
j = StartNum;
while(j < EndNum) {
std::cout << j << " " << std::flush;
j += StrideNum;
}
std::cout << std::endl;
return 0;
}
}; // class T545_t
int main(int , char** )
{
T545_t t545;
return(t545.exec());
}
Ask me where 'j' is declared?
This code is marked as C++, so in this case, I have declared 'j' in the private data attribute 'section' of this class definition. That is where you'd look for it, right?
If your c++ code does not have class, what's the point?
I'm currently having a problem making a code for a Coordinate system.
In the exercise I'm doing, I want to create a coordinate system with an Ordinate/Abscissa and a defined letter (for example dot A)
I must put information for 25 dots and it must control all dots with the same letter. They should be in a circle with a (0;0) coordinate beginning. If the information given about the 25 dots do not meet the set condition the selected dots must have new reentered information to meet the condition without changing the given values of the previous dots(which meet the expectations). It also should have all the information for dots which have 2 positive coordinates
here's the code I made. I'd be really thankful if someone helped me out.
#include <iostream>
#include <cmath>
#include <stdio.h>
using namespace std;
int main(){
int dotX[23];//tri masiva
int dotY[23];
char dotName[23];
for (int i = 0; i<23; i++){// Cikal za vavejdane na masivite
cout << "Abscisa \t" << i + 1 << endl;
cin >> dotX[i];
cout << "Ordinata \t" << i + 1 << endl;
cin >> dotY[i];
cout << "Ime na tochkata" << endl;
cin >> dotName[i];
if (i >= 1){//IF operatora i cikula za obhozhdane na masiva i presmqtane na distanciite
bool flag = true;
while (flag){
double distance = sqrt(pow(dotY[i] - dotY[i - 1], 2) + pow(dotX[i] - dotX[i - 1], 2));//Formula za presmqtane na razstoqniqta
if (distance <= 6) {
char broi;
broi = broi++;
cout << "abscisa \t" << i + 1 << endl;
cin >> dotX[i];
cout << "ordinata \t" << i + 1 << endl;
cin >> dotY[i];
}
else{
flag = false;
}
}
}
}
float i;
for (float i = 0; i > 10, i++;){
float(dotX < 10);
cout << dotName[i] << endl;
}
}
There are a few big problems with your code.
First of all, the syntax for (float i = 0; i > 10, i++;) is completely wrong. It compiles, but that's just a coincidence. The different command in the for loop control structure should be separated by semicolons (;), not commas (,). The correct code would then be for (float i = 0; i > 10; i++). By the way, you made a typo, I think you meant for (float i = 0; i < 10; i++) (otherwise the for loop never runs since i is initialized to 0 and 0 > 10 is false from the beginning).
Second of all, you're initializing the variable i twice: once with float i; and once in the for loop. That shouldn't compile, although with some compilers it does. There are two options on how to do. The first option is to declare the variable outside of the for loop and just assign it without initializing it in the for loop:
float i;
for(i = 0; i < 10; i++){
//some stuff
}
The second option is to simply declare it in the for loop as you did in the first loop:
for(float i = 0; i < 10; i++){
//some stuff
}
Another mistake that you made is to declare i as a float and then try to access dotName[i]. Whatever you put inside the brackets has to be of type int or something similar (unsigned int, long, etc). Putting a float variable inside those brackets won't compile just like that. If you want to index an array with a float, you need to tell the compiler that you want to convert it to an int like this: dotName[(int)i] or dotName[int(i)]. This is called a cast. However, in your case, I would recommend just declaring i as an int.
Also, float(dotX < 10); is completely wrong, I don't really understand what you're trying to do there. I think you meant to do float(dotX[i] < 10);, but that still doesn't make any sense. What you would be doing there would be converting a bool to a float and then doing nothing with the result. That compiles and isn't wrong, but is completely useless. As I said, I don't understand what you want to do there.
Also, broi = broi++; is correct but useless. broi++; is enough. The ++ operator increments broi by one by itself and then returns the result. What the ++ operator does internally is basically this:
int operator++(int &x){
x = x + 1;
return x;
}
So it already increments the variable automatically without you having to do anything. What you did is the same as doing this:
broi = broi + 1;
broi = broi;
Here, the first line represents the ++ operator and the second line represents the = operator. It's clear that the second line is useless, so you can just remove it. In the same way, in your code, you can remove broi =, leaving simply broi++;.
You also did a few things that aren't recommended, but work just fine since the C++ standard supports them.
First of all, using namespace std; is bad practice. It's recommended to omit it and add std:: in front of cin, cout and endl. If you want to know why using namespace std; is bad practice, it's well explained here. However, I must admit that I personally still use using namespace std; since I think it's simpler.
Second of all, the main function is supposed to return 0, so it's recommended to add return 0; at the end of the main function. The return value of the main function tells what made the program close. The value 0 means that the program closed when it was supposed to. Any other values mean that the program crashed. A complete list of what each return value means is available here. Note that C++ supports omitting return 0; and most compilers add it automatically if it is omitted, but it's still recommended to have it. Also, C doesn't support omitting return 0; and in C it will return whatever happens to be in the memory, making it looked like the program crashed when it ended normally.
Also, #include <stdio.h> is C and although it works in C++, it's not recommended. In C++, it's better to use #include <cstdio>. All standard libraries that end with .h in C can be used in C++ by removing .h and adding a c at the beginning. That's also the case with cmath: in C, it would be #include <math.h> and in C++, it's #include <cmath>.
A good version of your code would therefore be:
#include <iostream>
#include <cmath>
#include <cstdio>
int main(){
int dotX[23]; //tri masiva
int dotY[23];
char dotName[23];
for (int i = 0; i < 23; i++){ // Cikal za vavejdane na masivite
std::cout << "Abscisa \t" << i + 1 << std::endl;
std::cin >> dotX[i];
std::cout << "Ordinata \t" << i + 1 << std::endl;
std::cin >> dotY[i];
std::cout << "Ime na tochkata" << std::endl;
std::cin >> dotName[i];
if (i >= 1){ //IF operatora i cikula za obhozhdane na masiva i presmqtane na distanciite
bool flag = true;
while (flag){
double distance = sqrt(pow(dotY[i] - dotY[i - 1], 2) + pow(dotX[i] - dotX[i - 1], 2)); //Formula za presmqtane na razstoqniqta
if (distance <= 6) {
char broi;
broi++;
std::cout << "abscisa \t" << i + 1 << std::endl;
std::cin >> dotX[i];
std::cout << "ordinata \t" << i + 1 << std::endl;
std::cin >> dotY[i];
}
else{
flag = false;
}
}
}
}
for (int i = 0; i < 10; i++){
float(dotX[i] < 10); //Note that I don't understand what you're trying to do here, so I just changed it to something that compiles
std::cout << dotName[i] << std::endl;
}
}
This question already has answers here:
When I change a parameter inside a function, does it change for the caller, too?
(4 answers)
Closed 7 years ago.
I've been having a problem in c++ where I call a function which assigns some values to things, but those assignments are lost after the function has been completed. Here is my code:
#include <iostream>
#include <string>
using namespace std;
void Input(string a, string b){
cout << "Input a: \n";
cin >> a;
cout << endl;
cout << "Input b: \n";
cin >> b;
cout << endl << "Inputen Strings (still in the called function): \n";
cout << a << " " << b << endl << endl;
};
int main(){
string c = "This didn't";
string d = "work";
Input(c,d);
cout << "Inputen Strings (now in the main function): \n";
cout << c + " " + d << endl;
return 0;
};
So that whenever I run it, (inputting "Hello" and then "World") the program runs as follows:
Input a:
Hello
Input b:
World
Inputen Strings (still in the called function):
Hello World
Inputen Strings (now in the main function):
This didn't work
I don't know why it's only temporarily saving the values. Any help is appreciated!
change your method signature to accept the address of the variables "&"
void Input(string &a, string &b)
without the "&" operator you are just sending copy's of the variable into the function, with the "&" address-of operator you are passing the variables by reference
Pass your strings by reference and that will allow the called function to change them so the variables in the calling function will have the assigned values.
The way you have it passing by value now, you are just sending a copy of the variables so the new values are lost when Input returns.
void Input(string &a, string &b)
{
...
}
I am trying to use a function to sort through a char array full of words. The current issue I am having is that in my sortNames function I am getting the error, "expression must be a modifiable lvalue" at the part below
hold = nameArr[ii];
nameArr[ii] = nameArr[jj];
nameArr[jj] = hold;
I am guessing that its because I am trying to pass values through an array for some reason. I am struggling with understanding references and pointers and the such, and I imagine that is hurting me here as well. Any help with this would be fantastic, thank you in advance.
Here is my current code...
#include <iostream>
#include <string>
using namespace std;
char nameArr[20][15]; // array to store the 20 values
int val = 0; // variable to pass values to the array
int x = 0; // loop counter outside functions
//Function prototypes
void getNames(char (&nameArr)[20][15], int &val);
void sortNames( char(&nameArr)[20][15]);
//getNames Function
void getNames(char (&nameArr)[20][15], int &val)
{
int i = 0; // loop counter
cout << "Awesome, now lets input those names...\n" << endl;
for (i = 0; i < val; i++)
{
cout << "\nNAME " << i+1 << ": " << ' ';
cin >> nameArr[i];
}
cout << "\n\n\nThese are the names that you inserted:\n" << endl;
for (i = 0; i < val; i++)
{
cout << nameArr[i] << "\n" << endl;
}
}
// sortNames function
void sortNames( char(&nameArr)[20][15])
{
int n = 15; // max length of word
int ii = 0; // loop counter
int jj = 0; // other counter
string hold; // holding array
for (int ii = 0 ; ii < n ; ii++)
{
for (int jj = ii + 1; jj < n; jj++)
{
if (nameArr[ii] > nameArr[jj])
{
hold = nameArr[ii];
nameArr[ii] = nameArr[jj];
nameArr[jj] = hold;
}
}
}
}
int main()
{
cout << "NAME SORTER!\n\nPlease enter in the amount of names you wish to enter: " << ' ';
cin >> val;
getNames(nameArr, val);
cout << "\n\n\nAlright, lets sort now..." << endl;
sortNames(nameArr);
cout << "\nHere are the results:\n" << endl;
for (x = 0; x < val; x++)
{
cout << nameArr[x] << "\n" << endl;
}
system("pause");
}
Your main problem here is that you are trying to use an assignment operator on two fixed sized arrays, which isn't legal. Consider the following code:
int a[2] = {0, 0};
int b[2] = {1, 1};
a = b;
This gives the same error you are getting. On the lines you mentioned, you are doing the same thing with char[15] arrays.
To fix your problems, you either need to allocate your char array dynamically/work with the pointers, or a simpler solution would be to just change your char[][] array to a string[] array.
That being said, there are a lot of things you can clean up here:
You have a few variables declared globally that can just be defined in main or lower
You can declare loop counters inside the for loop instead of beforehand, as you do in the sortNames function
In sortNames you are declaring a few variables twice
I'll add a few things to dwcanilla's answer.
You will want to change your function prototypes and headers to something more like this:
void getNames(char ** & arr, int val);
void sortNames(char ** & arr);
What this means is that the function accepts a reference to an array of c-strings; that is, when you work with the array within the function you are modifying the actual array you passed and not just a copy. Also I think you'd be fine just passing the integer by value for getNames.
Second, global variables are generally a bad idea. Since you can pass the array reference directly to your functions you may want to declare nameArr and your other global variables inside main instead.
Third, in getNames you won't be able to use cin to assign your c-strings directly.
EDIT: This is a better way --
getting console input for Cstrings
Finally, the < operator doesn't work on c-strings the way you're using it in your sort function. Use strcmp() instead (and be sure to include the cstring header):
if(strcmp(arr[ii], arr[jj]) > 0)
Excuse me again, I'm not any genius in Programming.
First of all, a summary: array input. Two 3D vectors...ha ha, let's use vectors to calculate MORE vectors. Anyway: dot product is just and plain ridiculous (nine numerals before decimals; I mean, seriously, I didn't ever thought that 1x8+7x5+4x2 could have NINE numerals). Cross product is...even worse.
I made the...uhm...how could I call it? Well, we call it "traza". I'll translate a definition ir order to get understood: a code's "traza" tell us the sequence of instructions of its execution, and how do the variables change after every line of code. You know, the table with variables and number marks referred to code lines where we look if the code is doing something unexpected. Getting to the point: it's everything fine as far as I could see.
Then, I made an unexpectedly "pseudotraza" with a print command and every value from the vectors. Just after input and just before te dot product (in a function). Guess what:
1) it's not my input, in either of them
2) they are not even the same values
3) first values are far away from my input, but the following ones at least were more logic (less difference to the input).
I learned this morning, 12 hours ago, to use arrays/vectors/whatever. I didn't ever have any need to set as 0 as default any value before its input. But it's the only thing I have known to do when things like this happened to me before.
(Someday any of you will be my Programming teacher, you are learning me more than himself...and excuse my awful grammar, English teaching in Spain is just "take some grammar rules and no more than 50 exercises in last High School year...it's all you need to pass the University Entrance Exam!")
#include <iostream>
using namespace std;
#include <stdlib.h>
const int N = 3;
typedef int Vector[N];
void introduirVector (Vector);
float producteEscalar (const Vector, const Vector); /*Input vector and dot product*/
int main (void)
{
Vector v1, v2;
float p_esc;
cout << "Introduim les dades del vector A: "; /* Input */
introduirVector (v1);
cout << "Introduim les dades del vector B: "; /* 2x Input combo */
introduirVector (v2);
cout << v1[0] << "\n" << v1[1] << "\n" << v1[2] << "\n" << v2[0] << "\n" << v2[1] << "\n" << v2[2] << endl; /* "Puseudotraza*/
p_esc= producteEscalar (v1, v2); /*Dot product*/
cout << "El producte escalar: " << p_esc; /*Dot product is...*/
system ("PAUSE");
return 0;
}
/*3x Input combo*/
void introduirVector (Vector)
{
int i;
Vector v;
for (i = 0; i < N; i++)
{
cin >> v[i];
}
return;
}
/* Dot product (why all the Vectors are set as constants but another after this is not set? It's the hint given by the teacher, my (not) beloved teacher...they gave us the main function and the other function's prototypes, but that's all) */
float producteEscalar (const Vector, const Vector)
{
float escalar;
Vector v1, v2;
/* Pseudotrazas for all*/
cout << v1[0] << "\n" << v1[1] << "\n" << v1[2] << "\n" << v2[0] << "\n" << v2[1] << "\n" << v2[2] << endl;
/* Dot product and all that */
escalar = (v1[0]*v2[0])+(v1[1]*v2[1])+(v1[2]*v2[2]);
return escalar;
}
The problem is this:
/*3x Input combo*/
void introduirVector (Vector)
{
int i;
Vector v;
This function takes a Vector as a parameter, but the Vector has no name so it cannot be used inside the function.
Then you declare a new, local Vector v. You read your user's input into this vector.
The function then ends, at which point the vector into which you read user input goes away.
Firstly, you should be using the parameter you were called with, not a local variable. But your second problem is that you are using pass by value. When you call this function, introduirVector (v1); it is not the "v1" you know and love from main that you are working with inside introduirVector, but a local copy of it that ceases to exist when your function returns.
What you need to do is make your function accept a pointer or a reference to the Vector it is being called with:
void introduirVector(Vector& v)
{
for (size_t i = 0; i < 3; ++i) {
cin >> v[i];
}
}
This does not fully solve all of the problems with your code, but it should get you moving forward.
I'm not seeing any input, which would be why you are not receiving any input.
Try using:
string inpt;
int a, b, c;
cin >> inpt;
a = atoi( inpt.c_str());
inpt = "";
cin >> inpt;
b = atoi( inpt.c_str());
// etc...
// Make your vector in this fashion, grabbing each integer separately then loading them
// into a vector