Task using for (strcmp aswell) - c++

This is the code that I have now:
int main() {
char stupac1, stupac2;
for (stupac1 = 'A'; stupac1 <= 'Z'; ++stupac1)
{
for (stupac2 = 'a'; stupac2 <= 'z'; ++stupac2)
// between the caps and the non caps there are 32 letters (ASCII code)
if(strcmp (reinterpret_cast <const char*> (stupac1),
reinterpret_cast <const char*> (stupac2)) == 32 )
{
cout <<stupac1 << stupac2 << endl;
}
else
{
cout << "These letters suck" << endl;
}
}
return 0;
}
The task: I need to write a program with 2 consecutive loops that will make a table which has the letters A-Z and a-z in 2 columns.
I need to use for, but strcmp can be removed if is not necessary. I was trying something but nothing is printed when I run this code and it crashes.

In C++, characters (char) are scalar values just like int, not strings. For example 'A' is equal to 65, assuming an ASCII/Unicode system. To test for equality, use the == operator.
It's quite easy to "count" from A to Z in ASCII, but not all C++ implementations are ASCII. For bonus points with your teacher, point out that the program wouldn't run under EBCDIC.
Also, before getting too accustomed to char * strings, be aware that real C++ programs almost exclusively use std::string, which also uses the == operator for comparison.

strcmp (reinterpret_cast <const char*> (stupac1), reinterpret_cast <const char*>(stupac2))
This invokes undefined behavior, as the arguments to strcmp should be null-terminated strings, but what you're passing are not null-terminated.
Since it is not clear what you're trying to do, I'm not going to suggest an alternative and correct solution.

Single chars are just like a smaller version of int, so you can compare them or subtract their values, just like with ints.
A much simpler version of your test would be
if (stupac2 - stupac1 == 32)
See, much easier. :-)
Whenever you seem to need reinterpret_cast you are probably trying things the wrong way.

Related

bulletproof use of from_chars()

I have some literal strings which I want to convert to integer and even double. The base is 16, 10, 8, and 2.
At this time, I wonder about the behavior of std::from_chars() - I try to convert and the error code inside from_chars_result return holds success - even if it isn't as shown here:
#include <iostream>
#include <string_view>
#include <charconv>
using namespace std::literals::string_view_literals;
int main()
{
auto const buf = "01234567890ABCDEFG.FFp1024"sv;
double d;
auto const out = std::from_chars(buf.begin(), buf.end(), d, std::chars_format::hex);
if(out.ec != std::errc{} || out.ptr != buf.end())
{
std::cerr << buf << '\n'
<< std::string(std::distance(buf.begin(), out.ptr), ' ') << "^- here\n";
auto const ec = std::make_error_code(out.ec);
std::cerr << "err: " << ec.message() << '\n';
return 1;
}
std::cout << d << '\n';
}
gives:
01234567890ABCDEFG.FFp1024
^- here
err: Success
For convenience also at coliru.
In my use case, I'll check the character set before but, I'm not sure about the checks to make it bulletproof. Is this behavior expected (maybe my English isn't sufficient, or I didn't read carefully enough)? I've never seen such checks on iterators on blogs etc.
The other question is related to different base like 2 and 8. Base of 10 and 16 seems to be supported - what would be the way for the other two bases?
Addendum/Edit:
Bulletproof here means that I can have nasty things in the string. The obvious thing for me is that 'G' is not a hex character. But I would have expected an appropriate error code in some way! The comparison out.ptr != buf.end() I've never seen in blogs (or I didn't read the right ones :)
If I enter a crazy long hex float, at least a numerical result out of range comes up.
By bulletproof I also mean that I can find such impossible strings by length, for example, so that I can save myself the call to from_chars() - for float/doubles and integers (here I would 'strlen' compare digits10 from std::numeric_limits).
The from_chars utility is designed to convert the first number it finds in the string and to return a pointer to the point where it stopped. This allows you to parse strings like "42 centimeters" by first converting the number and then parsing the rest of the string yourself for what comes after it.
The comparison out.ptr != buf.end() I've never seen in blogs (or I didn't read the right ones :)
If you know that the entire string should be a number, then checking that the pointer in the result points to the end of the string is the normal way to ensure that from_chars read the entire string.

Char array gets cleared after function gets() on C++

I'm trying to learn C++. Sometimes I get confused by C style strings and its functions. I've been using
char var[1];
fflush(stdin);
gets(var);
to write a string into a char array. I don't know if thats the most efficient way but thats how I've been taught.
Now, I'm making a console program in which I read some variables that way and make things with them. It's all working fine but I have a char array, estudios[1] and I have to compare it with strcmp (I'm not talking about the strcmp(estudios, "N") != 0 I wrote below) to a specific value and i found that te result of the comparation was always the same no matter the value estudios had. I realized that after this chunk of code:
if (strcmp(estudios, "N") != 0){
cout << "Estudios completos o incompletos?" << endl;
fflush(stdin);
gets(indicador);
}
Let's say that the value of estudios is "P". Before the code i showed the value of estudios is "P" but after it it changes it value to "". To be more precise it changes after the gets(indicator);
Why does that happen? Is it supposed to do that? Sorry for such a newbie question
Don't use gets. It is dangerous. It shouldn't be used at all. It has been removed from both C and C++ standards. Don't use gets.
I have a char array, estudios[1]
strcmp(estudios, "N") != 0
A character array of length 1 can only contain the null terminated string of length 0. The string "N" contains two characters: 'N' and '\0' which is the null termination character.
If estudios[0] is anything other than the null termination character, then it doesn't contain a null terminated string, and passing it to strcmp will violate the pre-conditions of the function and the behaviour of the program will be undefined.
Why does that happen?
The behaviour of the program is undefined.
Is it supposed to do that?
You aren't supposed to pass non-null-terminated strings into strcmp.
Here is a fixed program that probably does what you're trying to do (your example is incomplete, so I'm guessing):
std::string indicator;
char c;
std::cin >> c;
if (c != 'N') {
cout << "Estudios completos o incompletos?" << endl;
std::cin >> indicador;
}

Change the value of a variable in C++?

i hope you can help me.
The thing is that i don't know how to change the value of a variable, for example, i have a
"char" variable and then i wanna change it to "int" or "float"
This is the code
#include<iostream>
#include<cstdlib>
using namespace std;
main()
{
{
cout<<" El valor de las calificaciones es A=10,B=9,C=8,D=7,E=6,F=5,G=4,H=3,I=2,J=1 " <<endl;}
char calificaciones[4];
int resultado,A=10,B=9,C=8,D=7,E=6,F=5,G=4,H=3,I=2,J=1, i, promedio;
for(i=1;i<4;i++)
{
cout<<"Ingrese calificacion con letra "<<i;
cin>>calificaciones[i];
}
promedio=(calificaciones[1]+calificaciones[2]+calificaciones[3])/3;
cout<<"El promedio de sus tres calificaciones es "<<promedio<<endl;
system("pause");
}
The program is supposed to ask for the user to enter three scores and the scores are shown in letters as you can see, A=10, B=9, etc, and once the user enters three letters the program is going to divide them into three, but since the variable "calificaciones" was a string first, how do i make the operation i want to do this, or whats the command that i could use for the program to understand that the user entered three letters and an operation will be made with them?
Hope you can help me and thanks.
If your original question is, how to change datatype, sorry that is not possible.
Although, what you are trying to achieve can be done by std::map
Create Map of your grades.
std::map<char,int> myGrades;
myGrades.insert ( std::pair<char,int>('A',10) );
myGrades.insert ( std::pair<char,int>('B',9) );
myGrades.insert ( std::pair<char,int>('C',8) );
myGrades.insert ( std::pair<char,int>('D',7) );
Read input: (this is same. only change is index starts from 0)
for(i=0;i<3;i++)
{
cout<<"Ingrese calificacion con letra "<<i;
cin>>calificaciones[i];
}
Get actual integers from map.
int total_grades = ( myGrades.find(calificaciones[0])->second +
myGrades.find(calificaciones[1])->second +
myGrades.find(calificaciones[2])->second);
promedio=total_grades /3.0; //<-- NOtice 3.0 to avoid int/int
It's impossible to change the datatype of a variable in strongly-typed languages like C++, Java, etc. You'll need to define a new variable with the desired type instead. Weakly-typed languages like Python and PHP are (generally) typeless and will let you mix and match datatypes however you like, but it's not possible in C++. You can technically use void pointers to point to objects of any type, but they don't let you change the type of existing variables. Here is more information on strong and weak typing.
If you're okay with creating a new variable, you can use conversion functions or manually convert between datatypes (if possible). For example, it's not possible to convert the string "Hello world" to an int, but you can change a string like "42" to an int. The cstdlib / stdlib.h header provides functions like atof() and atoi() which can do basic conversions (make sure you convert any C++ strings to character arrays using myString.c_str() before passing them). stringstream is also a very powerful tool which easily converts practically anything to a string, among other uses.
I'm not quite sure what you want to do, but you can use the ASCII values of the characters to convert them. For example, the letter A has the ASCII value of 65, B is 66, C is 67, and so on. Because characters are inherently stored as numbers, you can convert them without using special conversion functions. You can simply assign a char to an int:
char ch = 'A';
int x = ch; // this is an implicit conversion
cout << x << endl; // this prints '65'
The character is being cast to an integer. You can also explicitly convert it:
char ch = 'A';
cout << ch << endl; // this prints 'A'
cout << (int) ch << endl; // this prints '65' because of the explicit conversion
It also works the other way around:
int x = 65;
char ch = x;
cout << ch << endl; // this prints 'A'

How to put the string entered into a character array in C++?

Now, I am facing with such a problem: Compare two strings without using "strcmp" in library function.
I have defined the function "mystrcmp" correctly, but I also have to put the string entered into a character array. How can I realize it?
Here is my wrong codes:
char a1[100],a2[100];
int j=0;
do
{
cin>>a1[j];
j=j+1;
}while(getchar()!=10);
int k=0;
do
{
cin>>a2[k];
k=k+1;
}while(getchar()!=10);
cout<<j<<" "<<k<<"\n";
I want to see if the loops are correct through j and k. Unfortunately, the results are wrong.
For example, when I enter "abcdefg" and "gfedcba", I get the result "j=4, k=4".
What's wrong with my codes? How can I correct it?
I'm looking forward to your answers. Thank you.
Why are you using the value 10 in your code? Don't use integer literals in place of character constants, because when you attempt to run this code on a computer that uses the EBCDIC character set you'll notice that '\n' has the value 37, not 10. Use '\n' instead of 10.
Don't mix getchar and cin code. That's a pretty bad idea, because they both consume one character each. In other words, getchar() is consuming one byte, and cin is consuming one byte, so you're consuming two bytes per loop and only storing one of those bytes. If you're going to use getchar, I think you mean something like this:
for (int c = getchar(); c >= 0 && c != '\n'; c = getchar()) {
a1[j++] = c;
}
a1[j] = '\0';
The same sort of thing using C++'s cin:
for (int c = cin.get(); cin.good() && c != '\n'; c = cin.get()) {
a1[j++] = c;
}
a1[j] = '\0';
This is dangerous code. You can write out of a1 & a2 bounds. Use functions made for this, for example cin.getline
http://www.cplusplus.com/reference/istream/istream/getline/

check if a pointer has some string c++

I am not good with c++ and I cannot find this anywhere, please apologize me if it is a bad question. I have a pointer and I want to know if some names store in this pointer begins with some specific string. As in python something like (maybe it is a bad example):
if 'Pre' in pointer_name:
This is what I have:
double t = 0;
for (size_t i =0; i < modules_.size(); ++i){
if(module_[i].name() == "pre"){ // here is what I want to introduce the condition
if (modules_[i].status() == 2){
std::cout << module_[i].name() << "exists" << std::endl;
}
}
}
The equivalent of Python 'Pre' in string_name is:
string_name.find("Pre") != std::string::npos // if using string
std::strstr(pointer_name, "Pre") // if using char*
The equivalent of Python string_name.startswith('Pre') ("begins with some specific string") is:
string_name.size() >= 3 && std::equal(string_name.begin(), string_name.begin() + 3, "Pre"); // if using string
string_name.find("Pre") == 0 // less efficient when it misses, but shorter
std::strncmp(pointer_name, "Pre", 3) == 0 // if using char*
In two of those cases, in practice, you might want to avoid using a literal 3 by measuring the string you're searching for.
Check std::string::find, there are enough good examples. If you are using c-style string, use strstr.
You can use the algorithm header file to do most of things usually one liners in python.
In this case though it might be just easier to use string find method .
If your name variable is of type std::string then you can use name().compare("Pre") == 0 for string comparison.
EDIT: Seems I misunderstood the question, for contains you can use string find, as other said.
Using C style strings, char * is not recommended in C++. They are error prone.