This is a part of the program which I am required to make in Turbo C++;
Here, if I give input of id as "PLAYNOW" and pass as "PASSWORD", variable p is storing the value 0 but i isn't storing. id variable is storing some junk number at the end of PLAYNOW and I am not able to figure out why. Please help. Please ignore any header files not added and the way I have taken input of password.
Thank you!
#include<conio.h>
#include<iostream.h>
#include<string.h>
#include<process.h>
int main()
{
char id[7],pass[8];
cout<<"Enter id: ";
cin.getline(id,7);
cout<<"Enter pass: ";
cin.getline(pass);
char idc={"PLAYNOW"};
char passc={"PASSWORD"};
int i=strcmp(id,idc);
int p=strcmp(pass,passc);
if(i==0&&p==o)
cout<<"Welcome. ";
else
exit(0);
getch();
return 0;
}
One problem in OP's code is the insufficient amount of memory allocated for the variables. For example, with those lines:
char id[7];
cin.getline(id,7);
The function getline can read and store from the input stream up to 6 chars in the null terminated char array id, but then the program has to compare that string to PLAYNOW, which is 7 chars long.
This leads to next problem, when getline leaves unread chars in the stream, the failbit is set, preventing any further readings.
To fix those, even with the old standard, OP can do something like this:
const int ssize = 32; // enough space to store id or password
const int ssmax = 1024;
// big value... ^^ try std::numeric_limits<std::streamsize>::max() instead
char id[ssize],
pass[ssize];
cout << "Enter id: ";
cin.getline(id, ssize); // extract (ssize - 1) chars from input
if ( cin.fail() ) {
cin.clear(); // if user entered more then ssize chars
cin.ignore(ssmax, '\n'); // clear the stream
}
The same for pass (OP didn't pass 8 to the second getline, too).
Then, the declarations of the strings which contain the expected ID and password are wrong. Use those:
char idc[] = "PLAYNOW";
char passc[] = "PASSWORD";
The last lines could be rewritten too:
if ( strcmp(id, idc) != 0 || strcmp(pass, passc) != 0 )
exit(0);
cout << "Welcome. ";
cin.get();
return 0; // end of main()
BTW, I'm quite sure that std::strings belonged to C++98, so this should work too:
#include <iostream>
#include <string>
int main() {
std::string id, pass;
std::cout << "Enter id: ";
std::getline(std::cin, id);
std::cout << "Enter pass: ";
std::getline(std::cin, pass);
std::string idc("PLAYNOW");
std::string passc("PASSWORD");
if ( idc != id || passc != pass )
exit(0);
std::cout << "Welcome. ";
return 0;
}
if id and pass are "PLAYNOW" and "PASSWORD", id has length is 8 , and pass has length is 9 (NULL character at end of string).
I changed as below and result print in cmd is Welcome.
char id[8],pass[9];
...
cin.getline(id,8);
char idc[] = "PLAYNOW" ;
char passc[] = "PASSWORD" ;
...
cin.getline(pass,9);
...
if(i==0&&p==0)
Well, beyond numerous mistakes that I simply can't begin to list, I see that you are reading from a char stream without giving the stream size. Try:
cin.getline(pass, 8);
I would seriously consider using a compiler that is a bit newer, and focusing more on readability and convention, as it's clear that there are better ways to do what is ultimately being done here. Especially with the line I pointed out, this is very ad hoc. What if the string is longer/shorter than 8 characters?
Related
I'm making a c++ program using string(data type) and char array. Now, the data type is printing words alright. But, I'm having some trouble with the char array. Here's the code:
#include<iostream>
#include<string.h>
using namespace std;
int main(){
char str[200];
string str1;
cout<<"Enter a string:\t";
getline(cin,str1);
cout<<str1 <<endl;
cout<<"enter second string:\t";
cin>>str;
cin.get(str,200);
cout<<str;
}
code output
As, you can see in the output, the data type string is printing the words fine. But, the char array is missing the first word. Am I doing something wrong? or does the char array work in different way? Please explain. Thanks.
While you have already discovered that cin >> str; isn't required as you are simply writing again to str with cin.getline (str, sizeof str), there are a number of additional issues you should address:
1. Unless your compiler is ancient, you should #include <string>, not the C-header string.h;
2. Don't use magic-numbers in your code. If you need a constant, e.g. for the maximum number of characters in str, #define a constant or use a global enum to do the same, e.g.
#define MAXC 200 /* if you need a constant, #define one (or more) */
...
char str[MAXC]; /* don't use 'magic-number', use a constant */
That way when, and if you change the number of characters in str in the future, you don't have to pick through your entire code and change every occurrence of the magic-number, e.g. cin.get(str,200);.
3. Validate EVERY user input. Otherwise a failed input can set an error-bit on your input stream and additional attempts to read from a stream with an error-bit set can result in undefined behavior. You could do:
if (!getline(cin,str1)) { /* VALIDATE every input */
cerr << "error: input failure - str1.\n";
return 1;
}
and
if (cin.get (str, sizeof str))
cout << str << endl;
(note: there are no further attempted reads after cin.get (str, sizeof str) so guarding your use of str is sufficient)
4. Always output a newline after your final line output to ensure your program is POSIX compliant. Otherwise on many OS's you will mess up the users prompt if writing to stdout or you will create a non-POSIX compliant output file if redirecting the output to a file, e.g.
my cat has none01:22 wizard:~/dev/src-cpp/tmp/debug>
Putting it altogether, you could do something like:
#include <iostream>
#include <string> /* depending on your compiler */
#define MAXC 200 /* if you need a constant, #define one (or more) */
using namespace std;
int main (void) {
char str[MAXC]; /* don't use 'magic-number', use a constant */
string str1;
cout << "enter a string: ";
if (!getline(cin,str1)) { /* VALIDATE every input */
cerr << "error: input failure - str1.\n";
return 1;
}
cout << str1 << endl;
cout << "enter second string: ";
// cin >> str; /* not needed */
if (cin.get (str, sizeof str))
cout << str << endl;
}
Example Use/Output
$ ./bin/cin.get_getline
enter a string: my dog has fleas
my dog has fleas
enter second string: my cat has none
my cat has none
cout<<"enter second string:\t";
cin>>str;
cin.get(str,200);
here first you are trying to read the second word twice into same variable. comment one of them and try to print the content of str.
#include<iostream>
#include<string.h>
using namespace std;
int main(){
char str[200];
string str1;
cout<<"Enter a string:\t";
getline(cin,str1);
cout<<str1 <<endl;
cout<<"enter second string:\t";
// cin>>str;
cin.get(str,200);
cout<<str<<endl;
}
Suppose i have written:
...
char c;
while(condition){
cin>>c;
//do stuff
...
}
...
If 2 characters are give in cin, the next cin will take the second character without me giving any. So, i tried this:
...
char c;
while(condition){
cin<<c
//do stuff
...
cin.ignore("999 \n");
}
...
In this case the program will work keeping only the first input but, is there a way to check how many characters the user inputs in cin in order to print an appropriate message?
for example, if the input is ab it will print something like "Please type only one character".
Read a std::string and validate:
while(condition){
std::string s;
std::cin >> s;
if (s.length() != 1){
// oops - make sure s[0] is not taken
}
c = s[0];
// do stuff
}
I think what you want is std::cin.rdbuf()->in_avail() which will tell you how many chars are still in std::cin buffer. If you are going to read just 1 char, and enter 1 char, the result would be 1, because of unread \n. So keep this in mind when calculating.
#include <iostream>
int main()
{
char c;
std::cin >> c;
std::cout << "cin still contains " << std::cin.rdbuf()->in_avail() << " chars" << std::endl;
}
I am a beginner in c++ and I want to enter a string as character by character into an array , so that I can implement a reverse function .. However unlike C when the enter is hit a '\n' is not insterted in the stream.. how can I stop data from being entered ?
my code is :
#include<iostream>
#include<array>
#define SIZE 100
using namespace std;
char *reverse(char *s)
{
array<char, SIZE>b;
int c=0;
for(int i =(SIZE-1);i>=0;i--){
b[i] = s[c];
c++;
}
return s;
}
int main()
{
cout<<"Please insert a string"<<endl;
char a[SIZE];
int i=0;
do{
cin>>a[i];
i++;
}while(a[i-1]!= '\0');
reverse(a);
return 0;
}
When you read character by character, it really reads characters, and newline is considered a white-space character.
Also the array will never be terminated as a C-style string, that's not how reading characters work. That means your loop condition is wrong.
To begin with I suggest you start using std::string for your strings. You can still read character by character. To continue you need to actually check what characters you read, and end reading once you read a newline.
Lastly, your reverse function does not work. First of all the loop itself is wrong, secondly you return the pointer to the original string, not the "reversed" array.
To help you with the reading it could be done something like
std::string str;
while (true)
{
char ch;
std::cin >> ch;
if (ch == '\n')
{
break; // End loop
}
str += ch; // Append character to string
}
Do note that not much of this is really needed as shown in the answer by Stack Danny. Even my code above could be simplified while still reading one character at a time.
Since you tagged your question as C++ (and not C) why not actually solve it with the modern C++ headers (that do exactly what you want, are tested, save and work really fast (rather than own functions))?
#include <string>
#include <algorithm>
#include <iostream>
int main(){
std::string str;
std::cout << "Enter a string: ";
std::getline(std::cin, str);
std::reverse(str.begin(), str.end());
std::cout << str << std::endl;
return 0;
}
output:
Enter a string: Hello Test 4321
1234 tseT olleH
I created a program that the user enters a string. But i need to count how many letters are in the string. The problem is im not allowed to use the strlen()function. So i found some methods but they use pointers but im not allowed to use that yet as we havent learned it. Whats the best way to do this in a simple method? I also tried chars but i dont have luck with that either.
#include <iostream>
using namespace std;
string long;
string short;
int main()
{
cout << "Enter long string";
cin >> long;
cout << "Enter short string";
cin >> short;
return 0;
}
I need to get the length of long and short and print it.
I am trying to use it without doing strlen as asked in some previous questions.
Do you mean something like this?
//random string given
int length = 1;
while(some_string[length - 1] != '\0')
length++;
Or if you don't want to count the \0 character:
int length = 0;
while(some_string[length] != '\0')
length++;
You can count from the beginning and see until you reach the end character \0.
std::string foo = "hello";
int length = 0;
while (foo[++length] != '\0');
std::cout << length;
If you use standard cpp string object I think the best way to get length of your string is to use method:
long.size();
It gives you number of characters in string without end string character '\0'. To use it you must include string library :
#include <string>
If you decide to use char table you can try method from cin:
char long_[20];
cout << "Enter long string\n";
int l = cin.getline(long_,20).gcount();
cout << l << endl;
gcount()
Ok, I'm trying to get good at using pointers so I'm trying to write a input validation for the user input to make sure that anything that isn't a number is handled correctly. When I use isdigit() isn't working for me. I still get an exception when I enter a alphabet. Any suggestions? Thanks. Check this out:
#include<iostream>
#include<algorithm>
#include<string>
#include<cctype>
using namespace std;
void EnterNumbers(int * , int);
int main()
{
int input = 0;
int *myArray;
cout << "Please enter the number of test scores\n\n";
cin >> input;
//Allocate Array
myArray = new int[input];
EnterNumbers(myArray,input);
delete[] myArray;
return 0;
}
void EnterNumbers(int *arr, int input)
{
for(int count = 0; count < input; count++)
{
cout << "\n\n Enter Grade Number " << count + 1 << "\t";
cin >> arr[count];
if(!isdigit(arr[count]))
{
cout << "Not a number";
}
}
}
If you test if (!(cin >> arr[count])) ... instead - isdigit(arr[digit]) tests if the value of arr[digit] is the ASCII code of a digit [or possibly matches Japanese, Chinese or Arabic (that is, as an Arabic script typeface, not that it's a 0-9 like our "Arabic" ones) digit]. So if you type in 48 to 57, it will say it's OK, but if you type 6 or 345, it's complaining that it is not a digit...
Once you have discovered a non-digit, you will also need to either exit or clean out the input buffer from "garbage". cin.ignore(1000, '\n'); will read up to the next newline or a 1000 characters, whichever happens first. Could get annoying if someone has typed in a million digits, but otherwise, should solve the problem.
You will of course also need a loop to read the number again, until a valid number is entered.
The way I do this kind of input validation is that I use std::getline(std::cin, str) to get the whole line of input and then I parse it using the following code:
std::istringstream iss(str);
std::string word;
// Read a single "word" out of the input line.
if (! (iss >> word))
return false;
// Following extraction of a character should fail
// because there should only be a single "word".
char ch;
if (iss >> ch)
return false;
// Try to interpret the "word" as a number.
// Seek back to the start of stream.
iss.clear ();
iss.seekg (0);
assert (iss);
// Extract value.
long lval;
iss >> lval;
// The extraction should be successful and
// following extraction of a characters should fail.
result = !! iss && ! (iss >> ch);
// When the extraction was a success then result is true.
return result;
isdigit() applies to char not to int as you're trying. The cin >> arr[count]; statement already ensures an integer numeric digits format is given in the input. Check cin.good() (!cin respectively) for possible input parsing errors.