Write the definition of a function named copy that reads all the
strings remaining to be read in standard input and displays them, one
on a line with no other spacing, onto standard output. Do not use loops of any kind (for, while, etc.).
I've tried something like:
void copy()
{
string x;
getline(cin, x);
cout << x << "\n";
if(cin){
copy();
}
else{
return;
}
}
But I may not be understanding entirely what "all the string remaining to be read in standard input" means. Can someone help me out?
Recursion is the right idea to satisfy teacher's strange limitations however look into std::getline and the operators and methods of std::cin for correct usage if you'd like to store the input in variables etc. Currently the value read is being stored in the temporary string named x for each scope of the function call on stack.
Edit: There is nothing particularly wrong with what you have although you technically don't need the else case as the stack will unwind after last call to copy(); and since it's a void function no return is necessary.
void copy()
{
{ // create a scope...
string x;
if (getline(cin, x))
cout << x << "\n"; // don't output 'x' when getline fails!
} // let x go out of scope - less baggage during recursion...
if(cin)
copy();
}
The question's a bit vague...
...reads all the strings remaining to be read in standard input and displays them, one on a line with no other spacing, onto standard output.
Is a "string" necessary the same as a line? One reason I suspect not is because if it is, the question's even less interesting (and you didn't think it possible!) - a reasonable answer:
std::cout << std::cin.rdbuf();
Another reason is "no spacing"... perhaps that's referring to leading and trailing space on each line, or maybe the intention was that each space separated value be considered a string, in which case you'd need:
void copy()
{
{
string x;
if (cin >> x);
cout << x << "\n";
}
if (cin)
copy();
}
Anybody's guess which is wanted....
Related
I am attempting to recreate some "R" scripts in C++, just for the fun of it. Have used C decades ago but not recently. Now what I have is a bit of code where I am reading data from a binary file and placing the data into a structure (or class) with an unknown number of array structures (for the file reading side). Not knowing exactly how many arrays are needed, I define the number after reading another binary file which contains that data. So, I have two options; one to enter new data (which saves that plus the number of arrays to two files); another to read saved data back in (which provides the number of needed array structures). Having done either option via 'IF' conditionals, I need the new or recovered data to perform math on outside those conditionals. This is where things go wrong. The data is not available. The simple example recreates the problem and I have not stumbled upon the solution yet. I am not familiar enough with C++ to find what is most likely something simple to fix. The 'closed' function's first line outside the 'if' conditionals does work as expected, but that's not the data I need, and I don't want that line in the program.
#include <iostream>
using namespace std;
void closed(void);
class traverse {
public:
int sta;
};
int main()
{
closed();
return 0;
}
void closed(void)
{
traverse stations[1]; // removes 'stations was not declared' error on line 35.
cout << "Enter 1 or 2\nSelect: ";
int selType;
cin >> selType;
if (selType == 2) {
cout << selType << " selected\n";
traverse stations[1];
stations[0].sta = 2; //need this member value available outside conditional.
cout << "Value is " << stations[0].sta << " inside." << endl;
} else {
cout << selType << " selected\n";
traverse stations[1];
stations[0].sta = 1; //need this member value available outside conditional.
cout << "Value is " << stations[0].sta << " inside." << endl;
}
cout << "Value is " << stations[0].sta << " outside." << endl;
}
I originally used a 'struct' but decided to try a 'class' to discover the differences. But, the same problem persists with both, so I don't think it is anything with the definitions, but perhaps with different declarations. Any ideas would be greatly appreciated. Thanks.
If you need it to live longer than the scope of the if, then declare it in the outer scope where you need it to continue living.
After you added this line to deal with the warning:
traverse stations[1]; // removes 'stations was not declared' error on line 35.
You left the declaration of stations inside the if. That hides the outer name, and will receive the data, then go out of scope when the brace-enclosed block exits. To put data into the outer stations don't hide it.
If you need this data to live longer than the function call itself, you'll need to pass in an object to be written into, or allocate and return one to the caller. Perhaps a vector? I don't like (or recommend) to pass raw arrays because they decay to pointers and lose the bounds encoding from their type. That makes it too easy to go out of bounds without being very careful. There are smart pointer wrappers you could use, or a span class, etc., to help do it more sensibly.
I know that for reading from console we can use
int number;
cin >> number;
//A line of code where we use int number
But is it possible to read a number from console without any variables. Are there any methods that return a number from console?
But is it possible to read a number from console without any variables.
Read a number without using any variable – sounds like a puzzle.
Here we go:
#include <iostream>
int main()
{
return !std::cin.operator>>(*new int());
}
This program returns
0 … on success (input was a number)
1 … on error (input was not a number).
Output:
Test 123:
Error: 0
Test abc:
Error: 1
Live Demo on coliru
Note:
I somehow had to provide a temporary LValue to the stream input operator.
I had no better idea than *new int() though I know this makes a memory leak.
In this simple program, this won't hurt as the OS will make the clean-up for me.
Are there any methods that return a number from console?
This part was really unclear to me.
If I had this problem on my own I would make a helper function
int readNum(std::istream &in)
{
int number; in >> number; return number;
}
which I could use then in the main() function without any variable
int main()
{
std::cout << "Number: " << readNum(std::cin) << '\n';
}
but readNum() had again to use a variable to store the result of formatted input.
It's hard to use formatted input stream operators without any variable if the result of input should be accessed again (at least, in C++ with std library only).
The getchar() function allows you to ignore one character instead of using a variable to save the value.
So I have a general question about the do/while loop. I'm learning C++ and I know that you can write something like that:
do{
....
} while(a<10 && cout<<"message");
The point is, that i know this is possible in c++, but do we really do that? I mean, the "cout" thing inside the while?
Your while loop is equivalent to
do {
...
cout << "message";
while(a < 10 && cout);
because cout << ... returns cout again.
Then, the question is, what does it mean to write statements like
while( cout );
or
if (cout) ...
The cout object has a conversion to boolean which is used here. It's implementation is checking !fail(), so
if (cout) ...
is equivalent to
if (!cout.fail()) ...
and
do { ... }
while(cout);
is equivalent to
do { ... }
while(!cout.fail());
Finally, fail returns true if the stream failed to produce output.
The fact is some people do this (i.e. run a function as part of the condition evaluation). It makes sense in a shell script, but if you're not using a shell script, it's sometimes not clear what the return value is for some functions. I couldn't tell you what cout<<"message" returns offhand, but I do know that if you write it inside the loop body, it would do what I want, and it would 'throw away' the return value if I don't use it.
To write cleaner code that others including your future-self can understand, I would only evaluate conditions which obviously return true/false as opposed to "0/not-0", or "0/1" which may different in different languages.
Bottom line is, let the compiler make things more efficient for you, and code for other people, not for the compiler.
If you want to perform the output after testing the condition, you would need to either do that or add another condition test inside the loop and maintain both of them, which is a bug waiting to happen.
do {
if (a < 10)
cout << "message";
} while (a < 10);
It's rare to see cout << by itself in any condition though, as you can usually assume that it will succeed unless your machine is on fire.
On the other hand the extraction operator, >>, usually belongs inside a condition;
while (cin >> x)
is idiomatic C++.
To make this as quick and concise as possible, this is my code:
char* aiMove = getAIMove();
cout << aiMove;
cout << "\n" << numMoves << ": " << aiMove << "\n\n";
return aiMove;
And this is my output:
a0 a1
0: �����������������������7
So, the first line calls getAIMove() and assigns the return value (char*) to aiMove.
The second line prints aiMove (a0 a1).
The third line takes numMoves and aiMove into cout and prints it, but it's printing some strange value instead.
The 4th line returns aiMove, which I've inspected to be the strange value printed.
Why has the value of aiMove changed? It seems to only happen when I pass an integer value into cout (in this case, numMoves).
Please help!
Thanks,
Patrick :)
edit: another thing that I forgot to mention is that this strange behaviour only happens when this block of code gets executed for the first time, every following time it gets run during the program it prints fine.
This is a clear indication that getAIMove returned a pointer to memory that the system felt free to reuse. A subsequent allocation, from either the stack or the heap, overwrote the returned pointer.
There are lots of ways this can happen, this is probably the most common:
char *GetAIMove()
{
char buf[128];
strcpy(buf, "a0");
strcat(buf, " ");
strcat(buf, "a1");
return buf; // oops, buf won't exist after we return
}
Oops. This code returns a pointer to a buffer that ceases to exist as soon as it returns. A typical fix for this issue would be return strdup(buf);. Just remember that the caller of the function needs to free the string when it's done with it.
Here's another way:
std::string GetAIMove()
{
// ...
return foo;
}
char* aiMov e= GetAIMove();
// aiMove points to the contents of the returned string, no longer in scope.
The fix for this is std::string aiMove = GetAIMove. Now aiMove keeps the string in scope.
But the best fix is to use a string class specifically designed to hold strings all the way through:
std::string GetAIMove()
{
std::string foo;
foo = "a1";
foo += " ";
foo += "a2";
return foo;
}
std::string aiMove = GetAIMove();
Note that while this code appears to involve a lot of copying, in practice, modern compilers will make it efficient. So don't feel bad about keeping your code simple, logical, and easy to understand and maintain.
No, cout doesn't change the contents of the parameter.
You're probably doing something wrong beforehand and running into undefined behavior.
Im creating an infix problem solver and it crashes in the final while loop to finish the last part a of the equations.
I call a final while loop in main to solve whats left on the stack and it hangs there and if i pop the last element from the stack it will leave the loop and return the wrong answer.
//
//
//
//
//
#include <iostream>
#include<stack>
#include<string>
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <sstream>
using namespace std;
#define size 30
int count=0;
int count2=0;
int total=0;
stack< string > prob;
char equ[size];
char temp[10];
string oper;
string k;
char t[10];
int j=0;
char y;
int solve(int f,int s, char o)
{
cout<<"f="<<f<<endl;
cout<<"s="<<s<<endl;
cout<<"o="<<o<<endl;
int a;
if (o== '*')//checks the operand stack for operator
{
cout << f << "*" << s << endl;
a= f*s;
}
if (o == '/')//checks the operand stack for operator
{
cout << f << "/" << s << endl;
if(s==0)
{
cout<<"Cant divide by 0"<<endl;
}
else
a= f/s;
}
if (o == '+')//checks the operand stack for operator
{
cout << f << "+" << s << endl;
a= f+s;
}
if (o == '-')//checks the operand stack for operator
{
cout << f << "-" << s << endl;
a= f-s;
}
return a;
}
int covnum()
{
int l,c;
k=prob.top();
for(int i=0;k[i]!='\n';i++)t[i]=k[i];
return l=atoi(t);
}
char covchar()
{
k=prob.top();
for(int i=0;k[i]!='\n';i++)t[i]=k[i];
return t[0];
}
void tostring(int a)
{
stringstream out;
out << a;
oper = out.str();
}
void charstack(char op)
{
oper=op;
prob.push(oper);
}
void numstack(char n[])
{
oper=n;
prob.push(oper);
}
void setprob()
{
int f,s;
char o;
char t;
int a;
int i;
t=covchar();
if(ispunct(t))
{
if(t=='(')
{
prob.pop();
}
if(t==')')
{
prob.pop();
}
else if(t=='+'||'-')
{
y=t;
prob.pop();
}
else if(t=='/'||'*')
{
y=t;
prob.pop();
}
}
cout<<"y="<<y<<endl;
i=covnum();
cout<<"i="<<i<<endl;
s=i;
prob.pop();
t=covchar();
cout<<"t="<<t<<endl;
if(ispunct(t))
{
o=t;
prob.pop();
}
i=covnum();
cout<<"i="<<i<<endl;
f=i;
prob.pop();
t=covchar();
if (t=='('||')')
{
prob.pop();
}
a=solve(f,s, o);
tostring(a);
prob.push(oper);
cout<<"A="<<prob.top()<<endl;
}
void postfix()
{
int a=0;
char k;
for(int i=0;equ[i]!='\0';i++)
{
if(isdigit(equ[i]))//checks array for number
{
temp[count]=equ[i];
count++;
}
if(ispunct(equ[i]))//checks array for operator
{
if(count>0)//if the int input is done convert it to a string and push to stack
{
numstack(temp);
count=0;//resets the counter
}
if(equ[i]==')')//if char equals the ')' then set up and solve that bracket
{
setprob();
i++;//pushes i to the next thing in the array
total++;
}
while(equ[i]==')')//if char equals the ')' then set up and solve that bracket
{
i++;
}
if(isdigit(equ[i]))//checks array for number
{
temp[count]=equ[i];
count++;
}
if(ispunct(equ[i]))
{
if(equ[i]==')')//if char equals the ')' then set up and solve that bracket
{
i++;
}
charstack(equ[i]);
}
if(isdigit(equ[i]))//checks array for number
{
temp[count]=equ[i];
count++;
}
}
}
}
int main()
{
int a=0;
char o;
int c=0;
cout<<"Enter Equation: ";
cin>>equ;
postfix();
while(!prob.empty())
{
setprob();
a=covnum();
cout<<a<<" <=="<<endl;
prob.pop();
cout<<prob.top()<<"<top before c"<<endl;
c=covnum();
a=solve(c,a,y);
}
cout<<"Final Awnser"<<a<<endl;
system ("PAUSE");
return 0;
}
Hope this isn't too harsh but it appears like the code is riddled with various problems. I'm not going to attempt to address all of them but, for starters, your immediate crashes deal with accessing aggregates out of bounds.
Example:
for(int i=0;k[i]!='\n';i++)
k is an instance of std::string. std::string isn't null-terminated. It keeps track of the string's length, so you should be do something like this instead:
for(int i=0;i<k.size();i++)
Those are the more simple kind of errors, but I also see some errors in the overall logic. For example, your tokenizer (postfix function) does not handle the case where the last part of the expression is an operand. I'm not sure if that's an allowed condition, but it's something an infix solver should handle (and I recommend renaming this function to something like tokenize as it's really confusing to have a function called 'postfix' for an infix solver).
Most of all, my advice to you is to make some general changes to your approach.
Learn the debugger. Can't stress this enough. You should be testing your code as you're writing it and using the debugger to trace through it and make sure that state variables are correctly set.
Don't use any global variables to solve this problem. It might be tempting to avoid passing things around everywhere, but you're going to make it harder to do #1 and you're also limiting the generality of your solution. That small time you saved by not passing variables is easily going to cost you much more time if you get things wrong. You can also look into making a class which stores some of these things as member variables which you can avoid passing in the class methods, but especially for temporary states like 'equ' which you don't even need after you tokenize it, just pass it into the necessary tokenize function and do away with it.
initialize your variables as soon as you can (ideally when they are first defined). I see a lot of obsolete C-style practices where you're declaring all your variables at the top of a scope. Try to limit the scope in which you use variables, and that'll make your code safer and easier to get correct. It ties in with avoiding globals (#2).
Prefer alternatives to macros when you can, and when you can't, use BIG_UGLY_NAMES for them to distinguish them from everything else. Using #define to create a preprocessor definition for 'size' actually prevents the code above using the string's 'size' method from working. That can and should be a simple integral constant or, better yet, you can simply use std::string for 'equ' (aside from making it not a file scope global).
Prefer standard C++ library headers when you can. <ctype.h> should be <cctype>, <stdlib.h> should be <cstdlib>, and <stdio.h> should be <stdio>. Mixing non-standard headers with .h extension and standard headers in the same compilation unit can cause problems in some compilers and you'll also miss out on some important things like namespace scoping and function overloading.
Finally, take your time with the solution and put some care and love into it. I realize that it's homework and you're under a deadline, but you'll be facing even tougher deadlines in the real world where this kind of coding just won't be acceptable. Name your identifiers properly, format your code legibly, document what your functions do (not just how each line of code works which is something you actually shouldn't be doing so much later as you understand the language better). Some coding TLC will take you a long way. Really think about how to design solutions to a problem (if we're taking a procedural approach, decompose the problem into procedures as general units of work and not a mere chopped up version of your overall logic). #2 will help with this.
** Example: rather than a function named 'postfix' which works with some global input string and manipulates some global stack and partially evaluates the expression, make it accept an input string and return* the individual tokens. Now it's a general function you can reuse anywhere and you also reduced it to a much easier problem to solve and test. Document it and name it that way as well, focusing on the usage and what it accepts and returns. For instance:
// Tokenize an input string. Returns the individual tokens as
// a collection of strings.
std::vector<std::string> tokenize(const std::string& input);
This is purely an example and it may or may not be the best one for this particular problem, but if you take a proper approach to designing procedures, the end result is that you should have built yourself a library of well-tested, reusable code that you can use again and again to make all your future projects that much easier. You'll also make it easier to decompose complex problems into a number of simpler problems to solve which will make everything easier and the whole coding and testing process much smoother.
I see a number of things which all likely contribute to the issue of it not working:
There are no error or bounds checking. I realize that this is homework and as such may have specific requirements/specifications which eliminate the need for some checks, but you still need some to ensure you are correctly parsing the input. What if you exceed the array size of equ/tmp/t? What if your stack is empty when you try to pop/top it?
There are a few if statements that look like else if (t == '+' || '-') which most likely doesn't do what you want them to. This expression is actually always true since '-' is non-zero and is converted to a true value. You probably want else if (t == '+' || t == '-').
As far as I can tell you seem to skip parsing or adding '(' to the stack which should make it impossible for you to actually evaluate the expression properly.
You have a while loop in the middle of postfix() which skips multiple ')' but doesn't do anything.
Your code is very hard to follow. Properly naming variables and functions and eliminating most of the globals (you don't actually need most of them) would help a great deal as would proper indentation and add a few spaces in expressions.
There are other minor issues not particularily worth mentioning. For example the covchar() and covnum() functions are much more complex than needed.
I've written a few postfix parsers over the years and I can't really follow what you are trying to do, which isn't to say the way you're trying is impossible but I would suggest re-examining at the base logic needed to parse the expression, particularly nested levels of brackets.