Trying to ignore all spaces up to the first character (desperate for a simple push)

I'll be honest, this is a small piece of code that I need to complete my homework. I know that the community is very suspicious of helping students, but I stood against the wall for the past 5 hours and literally achieved nothing in this assignment. I never asked for help in any assignments, but no one gave me this problem.

All I came across is that the program blocks leading spaces. I think I can handle the rest. I am not asking for a solution for my general purpose, just a push in this particular section.

I will post the full text of the appointment here, but I am NOT sending it to try to get a complete solution, I only post it so that others can see the conditions in which I have to work with.

"This homework will give you more practice in writing functions, as well as how numbers are read into a variable. You need to write a function that reads an unsigned integer into a variable of type unsigned short int. It will have a maximum value of 65535, and the function must take care of illegal numbers. You cannot use "cin โ†’" inside the function. The rules for numerical input are basically the following:

1) skip all leading spaces 2) the first character found must be numeric, otherwise an error will occur 3) the numeric characters are then processed one at a time and combined with number 4) processing stops when non-numeric detection

We will follow these rules as well as add error handling and overflow. If an invalid entry is made before a numerical number, except for error code "1", is sent back, if an overflow occurs, this number is greater than 65535, then error code "2" will be sent back. If there is no error, then "0" is returned.

Make sure that the main function continues the cycle until the user enters โ€œnโ€ or โ€œNโ€ for NO, the main one must check the error code returned by the โ€œReadIntโ€ function and display the corresponding error messages or display the number if not mistakes. Take care of the development of the ReadInt function, it should be a return value and have a reference parameter. The function should process one character at a time from the input buffer and process it correctly. After the number has been read, make sure that the input buffer is empty, otherwise the loop in the main one may not work correctly. I know that this is not how extraction works, but allows you to do it this way.

You do not need to include an algorithm with this purpose, but I would advise you to write it. And a debugger might be useful. You basically rewrite the extraction operator since it works with integers.

Most of my code doesn't make sense, as I delete things and add things like crazy to try everything I can think of.

#include <iostream> #include <CTYPE.h> using namespace std; int ReadInt (unsigned short int &UserIn); int main() { int Error; unsigned short int UserInput; char RepeatProgram; do { Error=ReadInt(UserInput); if (Error==0) cout << "Number is " << UserInput << endl; else if (Error==1) cout << "Illegal Data Entry\n"; else if (Error==2) cout << "Numerical overflow, number too big\n"; cout << "Continue? n/N to quit: "; cin >> RepeatProgram; cout << endl; } while (RepeatProgram!='N' && RepeatProgram!='n'); } int ReadInt (unsigned short int &UserIn) { int Err=0; char TemporaryStorage; long int FinalNumber=0; cout << "Enter a number: "; //cin.ignore(1000, !' '); this didn't work cin.get(TemporaryStorage); cout << TemporaryStorage;//I'm only displaying this while I test my ideas to see if they are working or not, before I move onto the the next step cout << endl; return Err; } 

I really appreciate any help that I can get, and I hope that I do not have the impression that I am looking for a complete free solution to the whole problem. I want to do it on my own, I just have a lot in this beginning.

+5
source share
2 answers

As a preface, I want to say that this is a question asked by a student, but unlike most of their types, this is a quality question that deserves a qualitative answer, so I will try to do it;). I will not try to just answer your specific question, but to show you other small problems in your code.

First of all, analyze your code step by step. More or less like what the debugger does. Take the time to read this carefully;) ...

 #include <iostream> #include <CTYPE.h> 

Includes the headers <iostream> and <ctype.h> (uppercase works due to some NTFS Windows flaws / solutions). I recommend that you replace the second line with #include <cctype> .

 using namespace std; 

This is normal for any beginner / student, but he has no habit! For the purpose of "cleanliness," I would explicitly use std:: along this answer, as if this line did not exist.

 int ReadInt (unsigned short int &UserIn); 

Declares a ReadInt function that takes a UserIn link to enter unsigned short int and returns an object of type int .

 int main() { 

Special function main ; no parameters, returns int . Start function.

  int Error; unsigned short int UserInput; char RepeatProgram; 

Declares the variables Error , UserInput and RepeatProgram with the corresponding types int , unsigned short int and char .

  do { 

Do-while block. Begin.

  Error=ReadInt(UserInput); 

Assign an int ReadInt returned with the UserInput argument of int& type int& Error variable of unsigned short int .

  if (Error==0) std::cout << "Number is " << UserInput << endl; 

If Error is zero, print UserInput to standard output.

  else if (Error==1) std::cout << "Illegal Data Entry\n"; else if (Error==2) std::cout << "Numerical overflow, number too big\n"; 

Otherwise, if an error occurs, report it to the user using std::cout .

  std::cout << "Continue? n/N to quit: "; std::cin >> RepeatProgram; 

Ask the user if he wants to continue or exit. Save the input character in a RepeatProgram type char .

  std::cout << std::endl; 

It is redundant if you do not want to add indentation, which is probably your goal. Actually, you'd better do std::cout << '\n' , but that doesn't really matter.

  } while (RepeatProgram!='N' && RepeatProgram!='n'); 

The expression match for the do-while block above. Repeat this block if RepeatProgram is neither the lowercase nor the capital letter N

 } 

The final function is main . The implicit return value is zero.

 int ReadInt (unsigned short int &UserIn) { 

The ReadInt function accepts the ReadInt link in an unsigned short int and returns an object of type int . Start function.

  int Err=0; char TemporaryStorage; long int FinalNumber=0; 

Declares Err , TemporaryStorage and FinalNumber corresponding int , char and long int types. Err and FinalNumber initialized to 0 and 0 , respectively. But, only one thing. Didn't the job indicate that the exit number is stored in unsigned short int ? So, better ...

  unsigned short int FinalNumber = 0; 

Now...

  std::cout << "Enter a number: "; //std::cin.ignore(1000, !' '); this didn't work 

A? What was that supposed to be? ( Error : canceling the debugger because it does not make logic! **). I expect you just forgot // before the comment, right? Now what do you expect from !' ' !' ' for a rating other than '\0' ? istream::ignore(n, ch) will discard characters from the input stream until N characters are discarded, ch found, or the final file is reached.

A better approach would be ...

  do std::cin.get(TemporaryStorage); while(std::isspace(TemporyStorage)); 

Now...

  std::cin.get(TemporaryStorage); 

This line can be discarded using the above approach;).

Right Now that you are in the part where you obviously hit your head on all the solid objects known to mankind. Let me help you a little. We have such a situation. With the above code, TemporaryStorage will contain the first character, which is not a space after the while-while loop. So, we have three things left. First of all, make sure that the input has at least one digit, otherwise return an error. Now that the input is made up of numbers, convert the characters to integers and then multiply them to get the actual integer. Finally, and this is the most ... ah ... the weird part, we need to avoid overflow.

  if (!std::isdigit(TemporaryStorage)) { Err = 1; return Err; } while (std::isdigit(TemporaryStorage)) { unsigned short int OverflowChecker = FinalNumber; FinalNumber *= 10; // Make slot for another digit FinalNumber += TemporaryStorage - '0'; '0' - '0' = 0, '1' - '0' = 1... // If an unsigned overflows, it'll "wrap-around" to zero. We exploit that to detect any possible overflow if (FinalNumber > 65535 || OverflowChecker > FinalNumber) { Err = 2; return Err; } std::cin.get(TemporaryStorage); } // We've got the number, yay! UserIn = FinalNumber; 

The code is self-explanatory. Please comment if you have any doubts.

  std::cout << TemporaryStorage;//I'm only displaying this while I test my ideas to see if they are working or not, before I move onto the the next step cout << endl; return Err; 

Should I say something here? Anyway, I already did it. Just remember to take this std::cout before showing your work;).

 } 

The ultimate ReadInt function.

+5
source

You can skip leading spaces from the stream with std::ws . For instance:

 std::cin >> std::ws; 

This use >> just calls the std::ws manipulator in the stream. To meet the requirements of the teacher, you can call him directly:

 std::ws(std::cin); 

Formatted input automatically skips spaces. Please note that you should also always check if the login was successful:

 if (std::cin.get(TemporaryStorage)) { ... } 
+2
source

Source: https://habr.com/ru/post/1235348/


All Articles