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;
}
Related
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
#include <iostream>
#include <string>
using namespace std;
int main()
{
int num;
cin >> num;
string s;
getline(cin, s);
cout << s << " " << num << endl;
return 0;
}
In this code if I input 3 and press enter, then s takes an empty string.
1) If it is taking the first character as a newline, then is there a possible solution of taking line as input after taking an integer as input?
2) If my input is 4567artyu then how it is deciding whether 7 has to go into the s or num ?
I recommend that you always read complete lines of input from your users. It will cause the least confusion.
Ask for input.
Use std::getline to read a line of input.
If you don't want a string but, say, an integer, use std::stoi or (more general) boost::lexical_cast to safely convert the input to your desired target type. This is where you catch poor inputs and complain at the user.
I don't think that many users, if prompted for a number, would expect that entering 42bananas would be accepted as 42 and the bananas part be “remembered” for later. It will most likely be a typo and the user will be happy to be asked to correct it.
For taking line as input after taking integer as input you can consider removing the stray '\n' character from the stream.
#include <iostream>
#include <string>
using namespace std;
int main()
{
int num;
cin >> num;
getchar();
string s;
getline(cin, s);
cout << s << " " << num << endl;
return 0;
}
This will do the trick.
For second question, it reads 4567 as integer, it will continue to read it as integer until limit of int is reached and if limit is reached it will not consider anything after that. Then it will put the maximum value of int in the variable num and null int the string s. If limit is not reached, then string will remain in the input stream as it is, and will be fetched by variable s.
Try using cin.clear before you accept string
I have following Simple program to print string in C++, But this program only reads characters before space, not reading full string.
#include<iostream>
using namespace std;
int main()
{
char str[90];
cout << "Enter a string:";
cin >> str;
cout << str;
system("pause");
}
This is by design: cin "breaks" lines on whitespace characters, such as spaces and tabs.
Moreover, you are limiting the input to 90 characters, which is not good either: typing more than 90 characters with no spaces in between would overflow the buffer.
Here is a way to fix it:
std::string str;
std::cout << "Enter a string: ";
std::getline(std::cin, str);
Unlike character arrays, std::string objects can grow dynamically, so they would accommodate any number of characters the user chooses to enter.
You need to add two headers in order for this to compile:
#include <string>
#include <iostream>
>> reads a single word. You want getline to read a whole line:
cin.getline(str, sizeof str);
Now the problem is that the line will be truncated if it's too long. To fix that, use a string rather than a fixed-size buffer:
string str;
getline(cin, str);
i want to extract number string values of a char array. Actually I want to extract numbers embeded in file names for some file management. For example if there is a file name as file21 then i want the decimal number 21 from this file name.
How can i extract these values?
I tried the following but it results in an unexpected value. I think it is as a result of the implicit typecasting from the char to int while doing the arthimetic operation.
char * fname;
cout<<"enter file name";
cin>>fname;
int filenum=fname[4]%10+fname[5];
cout<<"file number is"<<filenum;
NOTE:
The filenamse are strictly in the format fileXX, XX being numbers between 01 and 99
You need to subtract '0' to get the decimal value of a digit character:
int filenum=(fname[4]-'0')*10+(fname[5]-'0');
Better yet, you should use atoi:
int filenum = atoi(fname+4);
You're getting undefined behavior because you're never allocating memory for the char* you read into:
char * fname = new char[16]; //should be enough for your filename format
or better yet
char fname[16];
Also, what do you expect:
fname[4]%10+fname[5];
to do? Magically concatenate the numbers?
First, you convert the first char to an int, multiply it by 10, convert the second char to an int and add to the first one. A simple google search for char to int would get you there.
How can i extract these values?
There are an infinite number of ways. One way is to use std::istringstream:
#include <string>
#include <sstream>
#include <iostream>
int main () {
std::string fname;
std::cout << "Enter file name: ";
std::getline(std::cin, fname);
int filenum;
std::istringstream stream(fname.substr(4,2));
if(stream >> filenum)
std::cout << "file number is " << filenum << "\n";
else
std::cout << "Merde\n";
}
Here is the simplest code:
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main()
{
int filenum;
string fname;
cout<<"enter file name";
cin>>fname;
string str2 = fname.substr(4,2);
istringstream(str2) >> filenum;
cout<<"file number is"<<filenum;
return 0;
}
If your input is that much defined, the simplest solution is scanf:
int main()
{
int theNumber = 0;
scanf("file%d.txt", &theNumber);
printf("your number is %d", theNumber);
}
Check it out in action, reading from char* instead of stdio: http://codepad.org/JFqS70yI
scanf (and sscanf) also throws in checking for proper input format: returns number of fields read successfully. In this case if return value is any other than 1, the input was wrong.
#include <iostream>
using namespace std;
void main(){
char name[20];
cin>>name; // when I input "This is"
cout<<name<<endl; // output was "This"
}
How to do that when I input "This is" , output too will be "This is" , not only "This" ?
You could use
cin.get( name, 20 );
or
cin.getline(name, 20);
Depending on whether you want the new line character in your string.
EDIT:
If you want to further simplify your code you could use a string instead of a char array, you wouldn't have to worry about the user exceeding your buffer size then ie.
string name;
getline(cin, name);
cout << name << endl;
EDIT 2:
As David Heffernan also pointed out in a comment I should explain why it's not working for you as expected. The extraction operator (operator >>) ends when a whitespace character -- a space in your case -- is reached. The operator also terminates when a null-character or the end of file is reached.