input operation - c++

Consider this problem
User will enter input to one dimensional array(char test[100]) in sequence of
letter/space/index/space/letter....
like this
a 1 s 1 e 3 r 4 r 3 t 3 until an 'enter'is hit.
Index can be repeated as well as letter.
So above sequence should mean test[1]=a ,test[1]=s and so on.
To build this problem what I have thought is that I should test whether character entered is newline(enter) or not.
but i don't understand how to do that
can you suggest some code for this

Scrap the entire idea; your question is wrong. The user does not enter a char[100]. Rather, the user enters a string. And suddenly it's very easy:
#include <string>
#include <iostream>
int main()
{
std::string user_input;
std::getline(std::cin, user_input);
// done: now use user_input
}
Now you can iterate over the string, tokenize it, or whatever. For example:
std::istringstream iss(user_input);
char c;
int n;
while (iss >> c >> n)
{
std::cout << "We have a pair (" << c << ", " << n << ")\n";
}

Related

Question when Judging the Type Entered by the User

I met some problems when judging whether the user entered the right type of number.
I want to design a program that only applicable to enter int type number. When the user enter another type (such as, double, char type), the system will output an error. However, when the user enter an illegal type of value, the system firstly output an enter instruction, then output the error sentence.
The code of this part are as follows:
for (int i = 0; i < nStudents; ++i) {
std::cout << "Please input the score of Student " << (i + 1) << ": ";
std::cin >> nArray[i];
if (!std::cin.good()) {
std::cout << std::endl << "The data type is not applicable. Please input integers!" << std::endl;
return 0;
}
}
When I enter an illegal value, the results are:
Please input the number of the students: 3
Please input the score of Student 1: 1.2
Please input the score of Student 2:
The data type is not applicable. Please input integers!
Could you please provide me a solution of this? Thanks!
Using the integer stream operator for this is much too simplistic. If input fails for any reason then you have to reset the error state, ignore some characters and continue reading.
What's more is that if something like a decimal point is encountered, that's just fine provided something that looked like an integer came before it. Of course, the next call will fail because you try to read an integer but the next character in the stream is '.'.
This is what's happening in your case, and you're not even attempting to recover from the error.
In general, when you are requesting user input, the user is expected to press Enter after typing a value. So you can use line-based input for this. For that, you use std::string with std::getline. Once you have a line of input as a string, you can parse the required values from that string easily.
Here is a simple program that uses std::stoi to convert a line of input to an integer. However, since "1.2" will still correctly parse as the integer value 1, some additional logic is added that allows only whitespace for any remaining characters.
#include <cctype>
#include <iostream>
#include <stdexcept>
#include <string>
int main()
{
std::string line;
while (std::getline(std::cin, line))
{
try {
size_t pos = 0;
int ival = std::stoi(line, &pos);
while (pos < line.size()) {
if (!std::isspace(line[pos]))
throw std::runtime_error("Malformed integer value");
++pos;
}
std::cout << "Integer read: " << ival << '\n';
}
catch(std::exception &e)
{
std::cerr << "Invalid input: " << line << '\n';
}
}
}
Live demo here: https://godbolt.org/z/vK1WxTh3n

Characters after a space is not being printed out

I was using character arrays to get inputs from the user then display the output afterwards. However, every time I enter values with spaces in between, only the first word before the space is printed.
For instance, this is what I typed:
Customer No.: 7877 323 2332
This will be the output:
Customer No.: 7877
I already searched for possible solutions but I can't seem to find the right solution.
This is my code for reference:
#include<iostream>
using namespace std;
int main()
{
char custNum[10] = " "; // The assignment does not allow std::string
cout << "Please enter values for the following: " << endl;
cout << "Customer No.: ";
cin >> custNum;
cout << "Customer No.: " << custNum << endl;
}
Another option is to use std::basic_istream::getline to read the entire string into the buffer and then remove the spaces with a simple for loop. But when using plain-old character arrays don't skimp on buffer size. It is far better to be 1000-characters too long than one-character too short. With your input, your absolute minimum size of custNum is 14 characters (the 13 shown plus the '\0' (nul-terminating) character. (rough rule-of-thumb, take your longest estimated input and double it -- to allow for user-mistake, cat stepping on keyboard, etc...)
In you case you can simply do:
#include <iostream>
#include <cctype>
int main() {
char custNum[32] = " "; // The assignment does not allow std::string
int wrt = 0;
std::cout << "Please enter values for the following:\nCustomer No.: ";
if (std::cin.getline(custNum, 32)) { /* validate every input */
for (int rd = 0; custNum[rd]; rd++)
if (!isspace((unsigned char)custNum[rd]))
custNum[wrt++] = custNum[rd];
custNum[wrt] = 0;
std::cout << "Customer No.: " << custNum << '\n';
}
}
The two loop counters rd (read position) and wrt (write position) are simply used to loop over the original string and remove any whitespace found, nul-terminating again when the loop is left.
Example Use/Output
$ ./bin/readcustnum
Please enter values for the following:
Customer No.: 7877 323 2332
Customer No.: 78773232332
Also take a look at Why is “using namespace std;” considered bad practice? and C++: “std::endl” vs “\n”. Much easier to build good habits now than it is to break bad ones later... Look things over and let me know if you have questions.
Apart from std::getline, if you are going to use C-style strings, try the following code:
int main() {
char* str = new char[60];
scanf("%[^\n]s", str); //accepts space a a part of the string (does not give UB as it may seem initially
printf("%s", str);
return 0;
}
Also, if you absolutely need it to be a number, then use atoi
int ivar = std::atoi(str);
PS Not to forget gets (!!dangerous!!)
char* str;
gets(str);
puts(str);
cin >> int_variable will stop reading input when it reaches the first character that isn't a valid part of a number. C++ does not consider spaces part of a number, so it stops reading as soon as it encounters one.
You could use std::getline to read into a string instead, then remove the spaces from the string before converting to an integer. Or maybe in this case you don't even need the integer and can leave it as a string.

Unable to run reverse string program

I have recently started learning C++ and have written a few lines which accepts a string, displays the number of characters in it and also displays the reverse of the input string. This is what I have written.
#include <iostream>
int main()
{
char string[25],rev_string[25];
int counter=0,length=0;
std::cout << "\n Enter the string : ";
std::cin >> string;
while(counter==!'\0')
{
counter=counter+1;
length=length+1;
}
counter=0;
std::cout << "The string has "<<length<<" characters in it.";
while(length>=0)
{
rev_string[counter]=string[length];
counter=counter+1;
length=length-1;
}
std::cout << "\n The reverse of the given string is : "<<rev_string;
return(0);
}
There is no error when I debug, however when I run the program, I get some unexpected value and the string length shows zero. Can you please point out where have I made mistakes.
This is what I get when I run the program.
while ( counter == !'\0' ) { … }
Well, !'\0' is true, which as an integer is 1. So you have while (counter == 1), and counter is initialized to 0, making the expression immediately false, so the loop never executes.
You probably meant to write != '\0'. But this is still a problem, since counter starts off with the value 0, and 0 != 0 is still false and the loop doesn’t loop.
When you input Hey as your string, the characters H, e, y, and \0 are placed in the string variable. You want to find where that \0 character is, which we see is at string[3]. So why are you comparing counter with '\0'? Maybe you want string[counter]?
When you get the number of characters in Hey, which is 3, you begin your reverse loop copying the \0 at index 3 to index 0 ... all 4 characters in the reverse order: \0, y, e, H. Unfortunately, the \0 at the start will mark the end of the string, so the string will appear empty..
C++ is difficult to learn if you learn it as C. And also you get some ugly habits. Please learn and practice C++.
#include <string>
#include <algorithm>
#include <iostream>
int main()
{
std::string s;
std::cin >> s;
std::cout << "number of characters: " << s.size() << std::endl;
std::reverse(s.begin(), s.end());
std::cout << "reverse string: " << s << std::endl;
}
This is how you write your problem in C++. Now compare with what you are trying to do and I think it speaks for itself.

c++ string loops checking the same words

I have to get let's say 10 words from the user.The program will warn the user if the same word is entered again.What could be the general logic of the program ? I managed to take 10 words from the user with a loop but cant check if the entered words are all different or not ?
Save the words and check if you already have them:
#include <iostream>
#include <set>
#include <string>
int main()
{
std::set<std::string> words;
for (std::string word; std::cin >> word; )
{
if (!words.insert(std::move(word)).second)
{
std::cout << "Word already encountered!\n";
}
}
std::cout << "We got " << words.size() << " distinct words.\n";
// use "words"
}
(You can add a counter or check words.size() if you want at most a certain number of words.)
You could use a std::set, which by definition may not have any duplicates, all elements must be unique. You could do something like
std::set<std::string> uniqueWords;
while (uniqueWords.size() < 10)
{
std::string user;
std::cin >> user;
uniqueWords.insert(user);
}
If the user inputs a duplicate word, set::insert will not add the duplicate, so the length of the set will not increase. The while loop will only terminate once the length of the set grows to 10 elements. Then you can continue on.

C++ stringstream, if word is numeric, divide by two

I am fairly new to programming and have to create a program which reads the prompt: "I have 8 dollars to spend." It then needs to print out with each word on a separate line, and then if any of the strings is numeric, it needs to be divided by 2. Therefore it should end up printing out as:
I
have
4
dollars
to
spend.
I have managed to do everything, except finding the numeric value and dividing it by 2. So far I have this:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main()
{
string prompt;
string word;
cout << "Prompt: ";
getline(cin, prompt);
stringstream ss;
ss.str(prompt);
while (ss >> word)
{
cout << word << endl;
}
return 0;
}
After looking through various other posts, I cannot manage to get this to work. I'm assuming its an if/else statement within the while loop along the lines of, if numeric, set int num to num / 2 then cout << num << endl;, else cout << word << endl;, but I can't figure it out.
Thanks in advance.
You can use the stringstream class, which handles conversions between strings and other data types, to attempt to convert a given string to a number. If the attempt is successful, you know
The stringstream object allows you to treat a string as though it is a stream similar to cin or cout.
Incorporate this into your while loop, like so:
while (ss >> word)
{
int value = 0;
stringstream convert(word); //create a _stringstream_ from a string
//if *word* (and therefore *convert*) contains a numeric value,
//it can be read into an _int_
if(convert >> value) { //this will be false if the data in *convert* is not numeric
cout << value / 2 << endl;
}
else
cout << word << endl;
}
The strtol (C++11 version that works on std::string directly: std::stol) function is really good for testing whether a string holds a number, and if so, what the numeric value is.
Or you could continue using iostreams like you have been... try extracting a number (int or double variable), and if that fails, clear the error bit and read a string.
I dont have 50 rep so I cant comment, thats why I'm writing it as answer.
I think you can check it character by character, using Ascii value of each char, & if there are ascii values representing numbers between two spaces(two \n in this case as you've already seperated each word), then you have to divide the number by 2.