String and Cycle - c++

Premise: I'm a newbie on C and C++, that's why I need your help.
Hello guys, I have a problem with strings and cycle on C++ (I'm pretty inexperienced):
I want to make a simple login screen, I made a struct with username, password etc and I decided that the username must be >3 characters and <15 characters, but I don't know how to do it, let me explain:
#include <iostream>
#include <cstdlib>
using namespace std;
struct login{
string userID;
string userPSW;
string userMAIL;
char userGENDER;
}login1;
cout << "Username: ";
cin >> login1.userID;
I made a an if/else, while and for, but when I try to compare a string with an int (like: login1.userID < 15), there is an error, I found some solution (like convert to int the string) but my code doesn't work.
So, can someone help me with this problem?
Another problem is while cycle, i tried with char userID , but the cycle keep spamming the cout << "error" that i made and it's not what i want, i want a cycle where there is an error if characters are <3 and >15 and cycle must return to "Username: ", with this method people can retry to insert an username.
I don't speak/write english very well, but I tried to get understood.
Thank you in advance guys.
STRING PROBLEM FIXED WITH YOUR HELP!
cycle problem still not solved :(

You cannot compare a std::string to a number. If you want to compare the length of the string, use .length():
cout << "Username: ";
cin >> login1.userID;
if(login1.userID.length() > 15)
{
cout << "please chose a shorter name." << endl;

You cannot compare a string to an int. If you want to compare the string's length then you can use the length() method. It will return the number of chars in the string that you can compare.
Like
string barString = "hello"
if(barString.length() > 15)
cout<< "string longer than 15 chars";

Related

How does inputting a string into an int variable work in C++

this is some code that i have in C++:
#include <iostream>
using namespace std;
int main() {
int num1;
string some;
cout << "enter something";
cin >> num1 >> some;
cout << num1 << endl << some;
return 0;
}
I'm a bit confused about how inputting works exactly in C++. First of all, through observation i figured that when asking for multiple inputs, C++ looks for either space or line separated data and am not sure if that is exactly true as websites i have looked at don't say this explicitly. Also my main problem is what happens when for num1, which is an integer variable, i input 'hello', which is a string, and click enter. In that case, C++ doesn't even ask me for an input for some and instead just outputs 0. I am a beginner in C++ and am very confused why this happens as i would expect an error message instead. I am hoping that someone would explain to me the procedure that C++ goes through when dealing with a situation like this, where a string gets stored in an int variable, to better understand inputting in C++. Thanks!
With "Hello" you are putting the cout and cin into an error state where especially cin doesn't accept any further input.
If you want to prevent the user from writing text instead of numbers, you have to check each input character. There are several functions that can check if a key code equals a number or not.

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.

The variabel in my program is not giving the value user already gave

I am right now learning about making a program using Borland, so this is my first time on use it. I got confused by the result, cause the result is not what I expected.
Below is my code:
#include<iostream.h>
#include<conio.h>
#include<stdio.h>
void main()
{
char nama[25];
char kelas[5];
char jurusan[30];
char universitas[30];
char alamat[30];
cout<<"Masukkan Nama Anda\t : ";
gets(nama);
cout<<endl;
cout<<"Kelas\t\t\t : ";
gets(kelas);
cout<<endl;
cout<<"Jurusan\t\t\t : ";
gets(jurusan);
cout<<endl;
cout<<"Universitas\t\t : ";
gets(universitas);
cout<<endl;
cout<<"Alamat\t\t\t : ";
gets(alamat);
cout<<endl;
cout<<"\n\tBIODATA ANDA SEBAGAI MAHASISWA ADALAH SEBAGAI BERIKUT:"<<endl;
cout<<"\n\nNama\t\t\t : "<<nama<<endl;
cout<<"Kelas\t\t\t : "<<kelas<<endl;
cout<<"Jurusan\t\t\t : "<<jurusan<<endl;
cout<<"Universitas\t\t : "<<universitas<<endl;
cout<<"Alamat\t\t\t : "<<alamat<<endl;
cout<<"\n\nSilahkan tekan tombol ENTER untuk keluar dari program biodata singkat ini!";
getch();
}
The result I got is kinda fine, but there is still one problem that I got here. Which there is one variable that don't show what the value of the user already gave, it did not show the value, it even just gave the word "u" which I don't understand from where this word was coming. I sent it with my picture, so you can see it.
I hope you would help me, and thank you very much for reading my problem.
All of your input arrays:
char nama[25];
char kelas[5];
char jurusan[30];
char universitas[30];
char alamat[30];
are going to be one continuous block of chars. Your input methods will easily overflow from one array to the next causing all sorts of havoc.
Try using std::string instead and input from std::cin:
std::string nama;
std::string kelas;
std::string jurusan;
std::string universitas;
std::string alamat;
std::cout << "Masukkan Nama Anda\t : ";
std::cin >> nama;
std::cout << std::endl;
std::cout <<"Kelas\t\t\t : ";
std::cin >> kelas;
std::cout << std::endl;
std::cout << "Jurusan\t\t\t : ";
std::cin >> jurusan;
std::cout <<std::endl;
std::cout << "Universitas\t\t : ";
std::cin >> universitas;
std::cout <<std::endl;
std::cout << "Alamat\t\t\t : ";
std::cin >> alamat;
std::cout << std::endl;
After i tried some several suggestion to solve my own problem. Then i wonder, why there is just the variable of Jurusan which contain character that i don't know where it comes from. I tried to see it again, and then i reverse the place of another variable, also i put a comment sign //comment to make it not being seen as a code by machine in front of the Jurusan variable there is no problem anymore. Quite thinking, and then i just tried to count the sum of character in a variable which exactly below the Jurusan variable(Universitas variable), and then i also count the size of that variable(Universitas variable).
After this i just realised if the word "u" which in the variable Jurusan is the rest of the characther which comes from the variable below the Jurusan variable, which variable Universitas.
I am as the user, put the characther greater than the size of Universitas variable. And of course, that is wrong, and a mistake.
I came back to the code, and make the size of the variable Universitas is greater than before, and right now the problem is solved. And you guys can see it in my picture below if that is already succed, you also can compare it with the previous picture that i sent here in the Question section which has problem.
So, thank you guys for you who tried to help me. Cheers!

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.

C++, Text to ASCII while-loop error

I've come this far without asking for help, but I've got a problem that I can't seem to fix. I like cryptology, so now that I am learning C++, I want to make programs to encrypt and decrypt strings. I read that the best way is to convert the text to ASCII and go from there, so here is a simple program I made in C++ to try and convert a char variable to ASCII:
#include <iostream>
#include <string>
#include <math.h>
using namespace std;
int main()
{
char strString[1000];
cout<<"Enter you message:"<<endl;
cin>>strString[1000];
string strEncrypt;
int a = 0;
while (strString != '\0')
{
int b = (int)strString[a];
strEncrypt.at(a) = b; //This is where I'm getting an error.
a++;
}
cout<<"Encrypted message:"<<endl;
cout<<strEncrypt<<endl;
}
So, I've tried all 3 things I know to do to troubleshoot (Google, check for missing simicolons, and make sure I'm doing == not =, but this is just something I don't know how to do, not something I'm forgetting (I hope). So, any help would great!
You don't have to change the characters to ASCII they already are. Chars are basically the same as integers in memory.
Now to your question; . If you want to set a character in a string you can do that like this
string[index] = b;
Another thing to be careful for in your code. You are using cin to read the string from the user. This will not let you read messages that have spaces in them and will only read the first word. For example, if the user enters "Love Crypto" cin will only read "Love" and "Crypto" will be ignored. To get the entire line, use getline instead.
As for looping over characters in a string, it's better to do it as follows:
for(int i = 0; i < strString.length(); i++)
{
strString[i] = bla;
}
Again, you're code isn't actually doing anything. It is only reading a letter and then storing a "letter" in another string.
string::at() throws exception if the index passed to at() is out of range. So, if you are getting runtime error then it's expected. Because, your string strEncrypt is initialized to "" and thus the size is 0.
You may try
strEncrypt.reserve(strlen(strString));
Easiest way to actually make the code you have work is change this line strEncrypt.at(a) = b; to this strEncrypt += b; Which will add the characters to the empty string strEncrypt.
Your code doesn't make much sense though as char types are already ascii. You'll have to explain more about what kind of encrypting you are trying to do and maybe we can point you in the right direction.
EDIT: After thinking about what you're trying to do a bit more based on the code you have it seems like you want to print the numeric ascii value of characters. You can do that with just a cast like this:
string input;
cout << "Enter you message:" << endl;
// handle spaces in the message
getline(cin, input);
cout << "String chars as ascii values:" << endl;
cout << "Char: " << "ASCII Code:" << endl;
for (int i = 0; i < input.length(); ++i)
{
// casting the char to an int with (int) will print the ascii code
cout << input[i] << " " << (int)input[i] << endl;
}
On top of the fact that your input is already in ASCII, keep in mind that doing cin >> strString[1000] doesn't limit the input captured to the length of your buffer unless you specifically specify the number of characters to capture for the stream object using setw() or setting it's ios_base::width data member. So your method right now risks buffer overflows.
Secondly, the form of cin >> that you're using will not capture the entire line of input. Instead it will stop at the first white-space or any other delimiting character (or end-of-file if that is reached first). In your case, if you are entering a line like "Hello World", then the syntax you're using will only capture "Hello" and drop "World".
A much better idea would be to use the getline() function with a std::string object if you are wanting to capture a line of input to a string and remove the delimiting newline character without risking buffer overflows ... for instance:
string strString;
getline(cin, strString);
Apart from advises given, when receiving this kind of run-time errors use Cppcheck utility.
It will give you the answer: "Message: Array 'strString[1000]' index 1000 out of bounds".