I am writing a program that must print numbers at first which was entered at last.
So here is my code:
#include <iostream>
using namespace std;
void recursive()
{
long long n;
if((cin>>n)&&(!cin.eof())) // Dont work because enter is ignored in cmd window os
recursive();
cout<<n<<endl;
return;
}
int main()
{
recursive();
return 0;
}
Any idea how to stop function when nothing is input? Or how to solve problem in another way?
Thanks
As your program is right now it will read the long long's until cin's operator void* indicates that the value read was not compatible (but still prints the n , filled with garbage,that it failed to read), as you notice it ignores the blank lines.
If I understand correctly, what you want is that when the user inputs a blank line the program should output the numbers read, a simple way to do this would be to read the input as a string, then check the string's length, and use a stringstream to convert it to the appropriate type.
#include <iostream>
#include <sstream>
#include <string>
void recursive()
{
std::string input;
long long n;
if ( std::getline(std::cin,input) && input.length() > 0 )
{
std::istringstream ss(input);
if (ss >> n)
{
recursive();
std::cout << n << std::endl;
}
}
}
int main ()
{
recursive();
return 0;
}
edit
Here's another way, if your input comes in the form 46 798 4163 4654 32132, it uses std::cin.peek() that returns the next character in the input without extracting it, the result of peek() is compared to '\n' to test if the user pressed enter, and if that's the case it prints the number it just read without waiting for the next number
#include <iostream>
#include <sstream>
#include <string>
void recursive_in_a_line ()
{
long long n;
if (std::cin >> n)
{
if (std::cin.peek() != '\n')
{
recursive();
}
std::cout<< n << std::endl;
}
}
int main ()
{
recursive_in_a_line();
return 0;
}
Do you have to implement the program in a recursive way?
An alternative solution that does not use recursion would be to read the numbers in a while loop and add them to a container (a list or a vector), then display the content of the container.
Related
enter image description here
i have used code ( if (!(cin >> arr[i])) ) to check if input from user is different with type int (like string, char) to stop reading into array (arr1), and then i can't use it twice with the second array (arr2), it didn't read input and go straight to cin.clear and return... Can you help me? Thank you very much from it^^
enter image description here
It seems you mean the following
#include <limits>
//...
if ( not ( std::cin >> arr[i] ) )
{
//...
std::cin.clear();
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
}
Below is the complete working example in 2 ways. The program given read as many integers as the user enters on the console. For example the user can enter 30 or 300 inputs some which may be integer types and other may be of some other types like string. The array/vector will add only integer type input inside itself as you require.
Solution 1: Using built in array
#include <iostream>
#include <sstream>
#include <string>
int main()
{
std::string line;
//in case of using array, size must be fixed and predetermined
int arr[4] = {0}; //all elements are initialzed to zero. Also you can choose array size according to your needs
int i = 0;//this variable will be used to add element into the array
int count = 0;
getline(std::cin, line);
std::istringstream s(line);
//take input(from s to i) and then checks stream's eof flag status
while(s >> i || !s.eof()) {
//check if either failbit or badbit is set
if(s.fail())
{
//clear the error state to allow further operations on s
s.clear();
std::string temp;
s >> temp;
continue;
}
else
{
arr[count] = i;
++count;
if(count>=4)
{
break;//break the loop so that you don't go beyond array size
}
}
}
//print out the elements of the array
for(int i: arr)
{
std::cout<<"elem: "<<i<<std::endl;
}
return 0;
}
Solution 1 can be checked here.
Solution 2: Using std::vector
#include <iostream>
#include <vector>
#include <sstream>
#include <string>
int main()
{
std::string line;
std::vector<int> vec;
int i = 0;//this variable will be used to add element into the array
getline(std::cin, line);
std::istringstream s(line);
//take input(from s to i) and then checks stream's eof flag status
while(s >> i || !s.eof())
{
//check if either failbit or badbit is set
if(s.fail())
{
//clear the error state to allow further operations on s
s.clear();
std::string temp;
s >> temp;
continue;
}
else
{
vec.push_back(i);
}
}
//print out the elements of the array
for(int i: vec)
{
std::cout<<"elem: "<<i<<std::endl;
}
return 0;
}
Solution 2 can be checked here.
Important Note
The advantage of using std::vector over built in array(in this case) is that you don't have know the size of the vector beforehand. That is std::vector's size is not fixed as opposed to built in arrays. So it is preferable because you don't know how many input the user is going to enter. std::vector can handle this accordingly and add only valid(integer type) input. But when using built in arrays you must know/specify the size of the array beforehand. This in turn means you must know beforehand how many integers the user is going to enter, which is not practical.
So, I have a file that contains a pattern of a string then an int alternating line by line.
Something like this:
John McClane
30
James Bond
150
Indiana Jones
50
In this example, I would set John McClane to a string variable and then 30 to an integer variable. My issue is dealing with two types. I want to use getline(), but that only works with strings.
Is there an efficient or "right" way of doing this?
There are a number of approaches you could try.
Get string input, and convert to an integer if valid
Convert every second string to an integer
Try to read an integer when you expect one (just using cin >> in;). If you want a robust program, you can check validity with cin.good()
I don't know if there is a "right" way of doing this per say, but it's not a very taxing operation, so whatever you choose should be fine.
You could make a variable like this
string ibuf;
Then convert it to an integer doing this
getline(cin, ibuf);
(Whatever your int variable is) = strtol(ibuf.c_str(), NULL, 10);
One thing about C++ is that there are a large number of ways to accomplish any one task. One way to get integers from strings is to use a stringstream. There is a tutorial on stringstreams here
As for your problem with reading the alternating file, consider the following pseudocode:
boolean isInt = false;
while(fileIsNotOver) {
//getline
if(isInt) {
//use stringstream to get int here
} else {
//do whatever with the name here
}
isInt = !isInt;
}
I don't know if this fully works as i didn't tested it however it just compiles fine and answer should be something like this i think.
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
using namespace std;
int main()
{
int counter = 0;
int number;
string test_string;
ifstream myfile ("example.txt");
if (myfile.is_open())
{
while ( getline (myfile,test_string) )
{
cout << test_string << '\n';
++counter;
if(counter % 2 == 0 ){
number = atoi(test_string.c_str());
cout << number << '\n';
}else{
cout << test_string << '\n';
}
}
myfile.close();
}
else cout << "Unable to open file";
return 0;
}
You can try like this to read a string then an int alternating line by line.
#include<iostream>
#include<string>
#include<cstdio>
using namespace std;
int main()
{
string name;
int number;
freopen("input.txt", "r", stdin);
while (getline(cin, name))
{
cin >> number;
/*
process the input here
...
...
*/
getline(cin, name); // just to read the new line and/or spaces after the integer
//getchar(); //you can use getchar() instead of getline(cin, name) if there is no spaces after the integer
}
return 0;
}
Thanks !!!
I'm writing a program that will guess words taken from a big text file. One step is taking user input to determine the length of the string.
edit: added full code, made some changes
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int i(0),n(0),counter(0),limit(0);
char words[60000][30];
int initarray() {
int length(0);
string line;
char temp;
ifstream wordlist ("text.txt");
if (wordlist.is_open())
{
while (wordlist.good())
{
getline (wordlist,line);
length=line.length();
for (n=0;n!=length;n++)
{
temp=line.at(n);
words[i][n]=temp;
}
i++;
counter++;
}
}
else
{
cout<<"file not opened";
}
wordlist.close();
return 0;
}
int selectlength()
{
int length;
bool shorter(false),longer(false);
cout <<"length of word"<<endl;
cin >> length
limit=counter;
counter=0;
for (i=0;i<limit;i++){
for (n=0;n!=length;n++){
if (words[i][n]=='\0')
{
shorter=true;
break;
}
}
if (words[i][length+1] != '\0')
{
longer=true;
}
if (longer==true || shorter==true)
{
i--;
}
}
return 0;
}
int printresults(){
for (i=0;i!=counter;i++){
for (n=0;n<=20;n++){
cout << words[i][n];
}
cout <<endl;
}
return 0;
}
int main() {
initarray();
selectlength();
printresults();
return 0;
}
but my problem is happens whenever the program, which compiles fine, gets to the "cin" part to read user input for the length. When I enter in any number and hit enter, nothing happens. The program is still running, and just keeps taking input indefinately. Any help? Could it have anything to do with my using ifstream earlier in the prigram, albeit in a different function?
You've got an infinite loop in selectlength(). The outer for loop doesn't terminate because you're decrementing i (the loop counter) inside the loop (not a good idea, perhaps find a better way).
I think you're not terminating on the last line in the input file. longer and shorter will both be true and limit will never be reached. Put in a test for this in the loop:
if (words[i][0] == '\0')
break;
That will at least stop the infinite loop and allow you to relook at your logic (it's not clear what longer and shorter will be used for.
A few general comments:
Putting trace statements inside the problem area can help you identify a problem.
You'll learn more about C++ if instead of the char words[x][y] you use std::vector<std::string> words;
A boolean inside an if statement is easier to read like this: if (longer || shorter) than how you have it.
You're always returning 0 - rather make the function void.
You're also setting the global counter to 0 inside selectlength() but you still need it later in printresults() so you'll get no output.
I'm trying to store the input that user enters through console. so I need to include the "enter" and any white space.
But cin stops giving me input after the first space.
Is there a way to read whole lines until CTRL+Z is pressed, or something?
is there a way like readLines till CTRL+Z is pressed or something ??
Yes, precisely like this, using the free std::getline function (not the istream method of the same name!):
string line;
while (getline(cin, line)) {
// do something with the line
}
This will read lines (including whitespace, but without ending newline) from the input until either the end of input is reached or cin signals an error.
#include <iostream>
#include <string>
using namespace std;
int main()
string s;
while( getline( cin, s ) ) {
// do something with s
}
}
For my program, I wrote the following bit of code that reads every single character of input until ctrl+x is pressed. Here's the code:
char a;
string b;
while (a != 24)
{
cin.get(a);
b=b+a;
}
cout << b;
For Ctrl+z, enter this:
char a;
string b;
while (a != 26)
{
cin.get(a);
b=b+a;
}
cout << b;
I can't confirm that the ctr+z solution works, as I'm on a UNIX machine, and ctrl+z kills the program. It may or may not work for windows, however; You'd have to see for yourself.
#include <string>
#include <iostream>
int main()
{
std::cout << "enter your name: ";
std::string name;
std::getline(std::cin, name);
return 0;
}
You can use the getline function in c++
#include<iostream>
using namespace std;
int main()
{
char msg[100];
cin.getline(msg,100);
return 0;
}
Hello i'm trying to use a do-while loop to check the input and repeat the prompt until the user types in a correct integer. So that's my code:
#include <iostream>
#include <stdio.h>
#include <ctype.h>
int main ()
{
int a;
do
{
printf("Please type in your number: ");
}while(scanf_s("%d", &a) == 0);
std::cin.get();
std::cin.get();
return 0;
}
Well it seems to work. When I type in a number the program runs correctly. But when I type in a letter an infinite loop starts. Sincerly I don't know where the problem is.
Again, I suggest reading a line into a string and then trying to parse that string according to your needs. If the parse fails, simply prompt the user again. You can bury the messy details in a function template:
#include <iostream>
#include <sstream>
#include <string>
template <typename T>
T read(std::string prompt)
{
for (; ;)
{
std::cout << prompt;
std::string line;
getline(std::cin, line);
std::istringstream ss(line);
T x;
if ((ss >> x) && (ss >> std::ws).eof()) return x;
}
}
int main ()
{
int a = read<int>("Please type in your number: ");
std::cout << "You entered " << a << '\n';
}
Here's what's going on -- I'll go through step by step. Starting from the do:
output: Please type in your number:
call to scanf Scanf finds that stdin is empty, and therefore waits for a line to be typed in.
input : letter (note that the input buffer now contains "letter")
scanf attempts to parse the string as an integer. Parsing fails before it consumes any characters. Therefore the buffer still contains "letter"
scanf returns EOF (error)
output: Please type in your number:
call to scanf -- scanf sees that there's already waiting input in stdin
scanf attempts to parse the buffer as an integer.....
This will go on forever because scanf will never consume the characters from the buffer. You can solve the problem by correctly checking for an error return code from scanf.
First of all never ever use scanf as its one hell of a dangerous function.
If you want to stick with C you should use fgets to read the input from the user to a buffer and then atoi to convert the input from the user to an integer.
Note: fgets always adds the 'enter' in to the buffer so you want to strip it off before converting the content of the buffer.
this could be easily done as follow:
_buffer[strlen(_buffer)-1] = '\0';
I have modified my code so that it works now. But sincerly it just works for numbers and letters. I want it to work with every char. For example "!?%". I have already tried to change the "isalnum" by "isascii" but that does not work.
#include <stdio.h>
#include <ctype.h>
int main ()
{
int a;
int b = 1;
char c ;
do
{
printf("Please type in a number: ");
if (scanf("%d", &a) == 0)
{
printf("Your input is not correct\n");
do
{
c = getchar();
}
while (isalnum(c));
ungetc(c, stdin);
}
else
{
printf("Thank you! ");
b--;
}
}
while(b != 0);
getchar();
getchar();
return 0;
}
# ordo
Blockquote
I have modified my code so that it works now. But sincerly it just works for numbers and letters. I want it to work with every char. For example "!?%". I have already tried to change the "isalnum" by "isascii" but that does not work.
Blockquote
You can use
if(userInput>='!'&& userInput<= '~') // refer ASCII chart between !and ~.
{ exit=0; }
http://www.cdrummond.qc.ca/cegep/informat/professeurs/alain/images/ASCII1.GIF
int main ()
{
int a;
char userInput,exit=1;
do
{
printf("Please type in your number: ");
userInput=getch();
if(userInput=='1') // suppose the correct input is 1.
{ exit=0; }
}while(exit);
std::cin.get();
std::cin.get();
return 0;
}
If the input is between 0 and 9...
if(userInput>='0'&& userInput<= '9') // suppose the correct input is 1.
{ exit=0; }
Note that we have to use ' ' signs
You can use getchar() function
do
{
printf("Please type in your number: ");
}while((getchar() - '0') == 0);