I am trying to write a console program, which gets a number from the input and puts it into an array. The read in lasts as long as the user does not hit the "space" button. I have tried several things, but my program won't compare the input with the ASCII code of "space". Thanks in advance!
#include <iostream>
using namespace std;
int main()
{
int fabcd[25],number_of_items = 0;
cout << "The read in loop lasts while you don't hit space:\n";
while((char)cin.get() != 32)
{
cin >> fabcd[number_of_items];
number_of_items++;
}
return 0;
}
There are several problems with your code. The most fundamental
is that you do two inputs each time through the loop, the first
in the while, and the second using >> in the loop. Note too
that the second will skip any spaces, then convert the input to
an integer. If the input cannot be legally converted to an
integer (e.g. the next character is an 'a'), the input goes
into an error state, and cin.get() will always return EOF.
And of course, if you are entering numbers, you can easily
enter more than 25, and overrun the buffer.
If you just want to enter a sequence of numbers, then:
std::vector<int> fabcd;
int tmp;
while ( std::cin >> tmp ) {
fabcd.push_back( tmp );
}
is all you need. (The numbers must be separated by white
space.) If you want to enter the digits, up until you
encounter a white space, something like the following should
work:
std::vector<int> digits;
int tmp = std::cin.get();
while ( tmp != EOF && ! std::isspace( tmp ) ) {
digits.push_back( tmp /* or tmp - '0' */ );
tmp = std::cin.get();
}
Notice that the results of std::cin.get() are assigned to an
int, not a char. This function returns an int
intentionally, because it must be able to return the out of band
value EOF. There are a couple of variants on this: if you use
std::cin::peek(), instead of std::cin::get(), you'll not
actually extract the character (which you'll have to do in the
loop); and there is also std::get( char& ), which extract the
character into the given char, provided it isn't at EOF.
Using this function, the loop would be:
std::vector<int> digits;
char tmp;
while ( std::get( tmp ) && ! std::isspace( tmp ) ) {
digits.push_back( tmp );
}
(You might also want to use std::isdigit, instead of !
std::ispace to control the loop.)
EDIT:
One last point: the actual numeric code for a space or whatever
depends on the implementation, and is not necessarily 32.
Also, you'll want to handle tabs and newlines similarly. You
should always use the isspace, etc. functions. Or if you
really do want to check for a space, and only a space, compare
with ' ', and not 32.
(char)13 ist the carriage return not the space.
isn't the point that you would do:
((char)cin.Get()) !=' '
The acii code for space is 32. So you should substitute 64 or 13, which is carraiage return to 32:
while((char)cin.get() != 32)
However the problem might be that cin may stop on some characters for example whitespace: You can disable this behaviour by setting: cin.unsetf(ios::skipws);
according to C++, user input check for '\0' stops at spaces?
try this :
#include <iostream>
#include <conio.h >
using namespace std;
int main()
{
int fabcd[25],number_of_items = 0;
cout << "The read in loop lasts while you don't hit space:\n";
while( _kbhit() != 32 )
{
char ch =getche();
if (ch != 32 )
{
cin >> fabcd[number_of_items];
number_of_items++;
}
else
break;
}
cout << "\nnumber of items:"<<number_of_items;
cin.get();
cin.get();
return 0;
}
Here is the answer:
int fabcd[25],number_of_items = 0;
cout << "The read in loop lasts while you don't hit space:\n";
char a;
while((a=cin.get()) != ' ')
{
fabcd[number_of_items]=a;
number_of_items++;
}
return 0;
Related
I'm having trouble with this program. The program is supposed to tell the user the number of lines, words, characters, unique lines, and unique words there are in a given input. So far, words and characters are okay. However, if the user wants to input more than one line, how do I do that? The functions will only output the results of one line at a time, rather than adding the results of both lines together. Also, I can't get the Unique Lines and Unique Words to work properly. I just got into C++ so I don't really have much experience. Can someone please help me?
Problems:
Program reads one line at a time, so when the user inputs multiple times, the program produces the results separately rather than adding it together as one entity.
Unique Lines and Unique Words are not working. Any ideas how to implement it using the library used in the program.
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
#include <string>
using std::string;
#include <set>
using std::set;
// write this function to help you out with the computation.
unsigned long countLines()
{
return 1;
}
unsigned long countWords(const string& s)
{
int nw =1;
for (size_t i = 0; i < s.size(); i++)
{
if (s[i] == ' ') //everytime the function encounters a whitespace, count increases by 1)//
{
nw++;
}
}
return nw;
}
unsigned long countChars(const string& s)
{
int nc = 0;
for (size_t i = 0; i < s.size(); i++)
{
if ( s[i] != ' ') //everytime the function encounters a character other than a whitespace, count increases//
{
nc++;
}
}
return nc;
}
unsigned long countUnLines(const string& s, set<string>& wl)
{
wl.insert(s);
return wl.size();
}
unsigned long countUnWords(const string& s, set<string>& wl)
{
int m1 = 0;
int m2 = 0;
string substring;
for(m2 = 0; m2 <= s.size(); m2++){
if (m2 != ' ' )
substring = s.substr(m1,m2);
wl.insert(substring);
m1 = m2 + 2;}
}
return wl.size();
int unw = 0;
wl.insert(s);
unw++;
return unw;
}
int main()
{
//stores string
string s;
//stores stats
unsigned long Lines = 0;
unsigned long Words = 0;
unsigned long Chars = 0;
unsigned long ULines = 0;
unsigned long UWords = 0;
//delcare sets
set<string> wl;
while(getline(cin,s))
{
Lines += countLines();
Words += countWords(s);
Chars += countChars(s);
ULines += countUnLines(s,wl);
UWords += countUnWords(s);
cout << Lines << endl;
cout << Words<< endl;
cout << Chars << endl;
cout << ULines << endl;
cout << UWords << endl;
Words = 0;
Chars = 0;
ULines = 0;
UWords = 0;
}
return 0;
}
You are resetting your count variables to zero at the end of your getline while loop. This is why you are only getting results for one line. The user can input multiple lines in your program as it is right now you are just resetting the count.
I think you're headed in the right direction. In order to count unique lines and words you're gonna have to store every line and word in a data structure of some kind, I'd suggest an unordered_map. Each element in the map you'll have a counter for # of occurences of each line/word.
I don't want to give the answer away wholesale, but here are some ideas to get you started.
The function getline() can read in an entire line of input. Do this until there's no more input.
You can use a container like std::set (or better, std::unordered_set) to store the lines read in. Not the most efficient, but it keeps track of all your lines, and only stores the unique ones.
Each line can then be broken down into words. Consider using something like std::stringstream for this.
Store the words in a different std::unordered_set.
The number of unique lines (words) is simply the number of lines (words) stored in the containers. Use the .size() method to obtain this.
Doing the total number of lines, words, and characters can be computed as you read the data in, so I won't go into much detail there.
Each item is googleable, and you may choose to implement different parts differently (if you don't want to use a stringstream, you can always iterate over the line read, for example.) This should get you on the right track.
It's pretty easy to get fairly accurate counts, but can be surprisingly difficult to get correct counts for all of this.
The big problem is the character count. If you open the file (as you usually would) in text mode, the number of characters you count may not match what the OS thinks is there. For the obvious examples, under Windows a CR/LF pair will be translated to a single new-line character, so you'll typically count each line as one character shorter than it really is.
Technically, there's no way to deal with that entirely correctly either -- the translation from external to internal representation when a file is opened in text mode is theoretically arbitrary. At least in theory, opening in binary mode doesn't help a lot either; in binary mode, you can have an arbitrary number of NUL characters after the end of the data that was written to the file.
The latter, however, is pretty much theoretical these days (it was allowed primarily because of CP/M, which most people have long forgotten).
To read lines, but retain the line-end delimiters intact, you can use std::cin.get() instead of std::getline(), then read the delimiters separately from the line itself.
That gives us something like this:
#include <iostream>
#include <set>
#include <string>
#include <iterator>
#include <sstream>
#include <fstream>
int main(int argc, char **argv) {
static char line[4096];
unsigned long chars = 0;
unsigned long words = 0;
unsigned long lines = 0;
std::set<std::string> unique_words;
std::ifstream in(argv[1], std::ios::binary);
while (in.get(line, sizeof(line), '\n')) {
++lines;
chars += strlen(line);
std::istringstream buffer(line);
std::string word;
while (buffer >> word) {
++words;
unique_words.insert(word);
}
while (in.peek() == '\n' || in.peek() == '\r') {
++chars;
in.ignore(1);
}
}
std::cout << "words: " << words << "\n"
<< "lines: " << lines << "\n"
<< "chars: " << chars << "\n"
<< "unique words: " << unique_words.size() << "\n";
}
Note that although this does answer that the OP actually asked at least for most typical OSes (Linux, *BSD, MacOS, Windows), it's probably not what he really wants. My guess is that his teacher isn't really asking for this level of care to try to get an accurate character count.
Also note that if you should encounter a line longer than the buffer, this can still give an inaccurate count of lines -- it'll count each buffer-full of data as a separate line, even if it didn't find a line-delimiter. That can be fixed as well, but it adds still more complexity to a program that's almost certainly already more complex than intended.
This may be a total beginner's question, but I have yet to find an answer that works for me.
Currently, I'm writing a program for a class that takes in a user's input (which can be one or more numbers separated by spaces), then determines whether the number is prime, perfect, or neither. If the number is perfect, then it will display the divisors.
Thus far, I've already written the code for the prime, perfect, and listing the divisors. I'm stuck on the input portion of my program. I don't know how to get the input that's separated by spaces to go through my loops one at a time.
This is my current program:
cout<<"Enter a number, or numbers separated by a space, between 1 and 1000."<<endl;
cin>>num;
while (divisor<=num)
if(num%divisor==0)
{
cout<<divisor<<endl;
total=total+divisor;
divisor++;
}
else divisor++;
if(total==num*2)
cout<<"The number you entered is perfect!"<<endl;
else cout<<"The number you entered is not perfect!"<<endl;
if(num==2||num==3||num==5||num==7)
cout<<"The number you entered is prime!"<<endl;
else if(num%2==0||num%3==0||num%5==0||num%7==0)
cout<<"The number you entered is not prime!"<<endl;
else cout<<"The number you entered is prime!"<<endl;
return 0;
It works, but only for a single number. If anyone could help me to get it to be able to read multiple inputs separated by spaces, it'd be greatly appreciated. Also, just a side note, I do not know how many numbers will be entered, so I can't just make a variable for each one. It will be a random amount of numbers.
Thanks!
By default, cin reads from the input discarding any spaces. So, all you have to do is to use a do while loop to read the input more than one time:
do {
cout<<"Enter a number, or numbers separated by a space, between 1 and 1000."<<endl;
cin >> num;
// reset your variables
// your function stuff (calculations)
}
while (true); // or some condition
I would recommend reading in the line into a string, then splitting it based on the spaces. For this, you can use the getline(...) function. The trick is having a dynamic sized data structure to hold the strings once it's split. Probably the easiest to use would be a vector.
#include <string>
#include <vector>
...
string rawInput;
vector<String> numbers;
while( getline( cin, rawInput, ' ' ) )
{
numbers.push_back(rawInput);
}
So say the input looks like this:
Enter a number, or numbers separated by a space, between 1 and 1000.
10 5 20 1 200 7
You will now have a vector, numbers, that contains the elements: {"10","5","20","1","200","7"}.
Note that these are still strings, so not useful in arithmetic. To convert them to integers, we use a combination of the STL function, atoi(...), and because atoi requires a c-string instead of a c++ style string, we use the string class' c_str() member function.
while(!numbers.empty())
{
string temp = numbers.pop_back();//removes the last element from the string
num = atoi( temp.c_str() ); //re-used your 'num' variable from your code
...//do stuff
}
Now there's some problems with this code. Yes, it runs, but it is kind of clunky, and it puts the numbers out in reverse order. Lets re-write it so that it is a little more compact:
#include <string>
...
string rawInput;
cout << "Enter a number, or numbers separated by a space, between 1 and 1000." << endl;
while( getline( cin, rawInput, ' ') )
{
num = atoi( rawInput.c_str() );
...//do your stuff
}
There's still lots of room for improvement with error handling (right now if you enter a non-number the program will crash), and there's infinitely more ways to actually handle the input to get it in a usable number form (the joys of programming!), but that should give you a comprehensive start. :)
Note: I had the reference pages as links, but I cannot post more than two since I have less than 15 posts :/
Edit:
I was a little bit wrong about the atoi behavior; I confused it with Java's string->Integer conversions which throw a Not-A-Number exception when given a string that isn't a number, and then crashes the program if the exception isn't handled. atoi(), on the other hand, returns 0, which is not as helpful because what if 0 is the number they entered? Let's make use of the isdigit(...) function. An important thing to note here is that c++ style strings can be accessed like an array, meaning rawInput[0] is the first character in the string all the way up to rawInput[length - 1].
#include <string>
#include <ctype.h>
...
string rawInput;
cout << "Enter a number, or numbers separated by a space, between 1 and 1000." << endl;
while( getline( cin, rawInput, ' ') )
{
bool isNum = true;
for(int i = 0; i < rawInput.length() && isNum; ++i)
{
isNum = isdigit( rawInput[i]);
}
if(isNum)
{
num = atoi( rawInput.c_str() );
...//do your stuff
}
else
cout << rawInput << " is not a number!" << endl;
}
The boolean (true/false or 1/0 respectively) is used as a flag for the for-loop, which steps through each character in the string and checks to see if it is a 0-9 digit. If any character in the string is not a digit, the loop will break during it's next execution when it gets to the condition "&& isNum" (assuming you've covered loops already). Then after the loop, isNum is used to determine whether to do your stuff, or to print the error message.
You'll want to:
Read in an entire line from the console
Tokenize the line, splitting along spaces.
Place those split pieces into an array or list
Step through that array/list, performing your prime/perfect/etc tests.
What has your class covered along these lines so far?
int main() {
int sum = 0;
cout << "enter number" << endl;
int i = 0;
while (true) {
cin >> i;
sum += i;
//cout << i << endl;
if (cin.peek() == '\n') {
break;
}
}
cout << "result: " << sum << endl;
return 0;
}
I think this code works, you may enter any int numbers and spaces, it will calculate the sum of input ints
std::vector<int> num{};
int buf;
do{
std::cin >> buf;
num.push_back(buf);
}while(std::cin.peek() == ' ');
In C language you can to it using scanf like this:
scanf('%d %d',&a,&b);
This is my code here i am trying to find the biggest length of same length characters at a time like "a a a bb bb bc sa sa a a" so answer is 5 for two characters at a time for 5 times adjacently .
this is my code , my question is that when i am trying to take the input , for my first input it is not going to getline but printf in last lines and then it takes a line and prints output
like if i give
5 it writes 1 then it takes getline , but i want it to take getline first rather than printf, in this way for my 5 input it prints 1 and 4 desired outputs .i want 5 desired can you tell me why..
#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
int main()
{
int a,j;
scanf("%d",&a);
for(j=0;j<a;j++)
{
vector<int> v;
string s;
getline(cin,s);
int i,cnt =0;
for(i=0;i<s.length();i++)
{
if(s[i] != ' ')
{
cnt++;
}
else
{
v.push_back(cnt);
cnt =0;
}
}
v.push_back(cnt);
int k=0;
int ps =0;
int sp=0;
while(k<v.size()-1)
{
if (v[k+1] - v[k] == 0)
{
sp++;
k++;
}
else
if (sp >= ps)
{
ps = sp;
k++;
sp=0;
}
else
{
k++;
sp=0;
}
}
if (sp<ps)
printf("%d",ps+1);
else
printf("%d",sp+1);
}
return 0;
}
You shouldn't be mixing scanf with getline, try to only use one or the other (and getline is a better option).
What is happening is that scanf stops parsing once it has finished reading an int. It does not consume the end of line character you type, or anything else you could have entered after that number. So getline picks up whatever was left on that first line (possibly just the newline char).
A "quick" but dirty fix would be to change your scanf call so that it swallows the whitespace after the int:
scanf("%d ",&a);
// ^ notice the space there
But that's not a real fix. Use getline and a string stream (in <sstream>) to get the first number, and your code will work as you intend it to. You'll find examples of using the istringstream to extract a number in this FAQ: How to convert a number to string and vice versa in C++
You might also be interested in this other question:
Split a string in C++?, the answers demonstrate ways to split a string that are less error-prone than what you're doing here.
How are you entering everything exactly? I think the problem may be that your getline() is reading your last [enter] off of the stream, thus automatically putting an empty string into s. That would result in the 1 you're getting. Try this for your scanf:
scanf("%d\n",&a)
That should absorb the [enter].
I need help with this if statement. Im trying to read each character to see if it is a number. If it is not a digit then say it is not a number if it is continue reading on to the next character. for example if the user inputs 54gr 21 gr42 134 3f3. the only thing that would cout is 21 and 134.
#include <iostream> // libraries
#include <iomanip>
#include <string>
using namespace std;
int main()
{
char string[80];
// char num[80];
// char good[80];
cout << "enter a string "; // prompting user
cin.getline(string,80); // geting line
// int i = 0;
// int j = 0;
int count = 0;
{
while(string[count] != '\0') {
if(string[count] >= '0' && string[count] <= '9' )
cout << count << endl;
}
++ count;
}
}
I would not try to do this character by character. The problem is that you don't now that 5 is really part of a number until you've read to the end of the string of non-space characters to verify that all the contents are legitimately part of a number.
As such, I think you need/want to break the input up into "words", then check whether each complete word can be converted entirely to a number. You can read "words" with just some_stream >> some_string;
Once you have a "word" you check whether you can convert it entirely to a number. Assuming you want integers, you use strtol to (try to) convert it to a number. That will give you a pointer to the first character it couldn't convert as a number. If that's not the end of the string, then that "word" wasn't a number (even if it started with/contained one or more digits).
I am currently learning C++ and I have been asked to make a program which will calculate the interest that would be paid on a deposit of a given size. One of the requirements is that we display an error message when non-integer data is entered.
I however cannot work out how to detect if non-integer data has been entered. If anyone could provide an example of how this problem is solved it would be much appreciated!
You don't have to check yourself. The expression (std::cin >> YourInteger) evaluates to a bool, whcih is true if and only if YourInteger was succesfully read. This leads to the idiom
int YourInteger;
if (std::cin >> YourInteger) {
std::cout << YourInteger << std::endl;
} else {
std::cout << "Not an integer\n";
}
this should be a clear enough starting point.
char* GetInt(char* str, int& n)
{
n = 0;
// skip over all non-digit characters
while(*str && !isdigit(*str) )
++str;
// convert all digits to an integer
while( *str && isdigit(*str) )
{
n = (n * 10) + *str - '0';
++str;
}
return str;
}
You need to find out if the input value contains non numeric characters. That is, anything other than 0-9.
You have to first take input as string and then verify if every digit is indeed numeric.
You can iterate the string and test if each character is a valid digit using the built in function isdigit() defined in <cctype>. You might also want to allow for a single comma if you're working with decimal numbers.