0

just learning C++ here.

#include <iostream>
#include <string>   

int main()
{
    char name[1000];
    std::cout << "What is your name?\n";
    std::cin.get(name, 50);

    name == "Shah Bhuiyan" ? std::cout << "Okay, it's you\n" : std::cout<< "Who is this?\n";


    
}

So here I wrote a program where I created a variable name[100]. I use the cin iostream object thing to take input for the variable name. If the name is equal to my name (as seen in name == "Shah Bhuiyan" :) then output the first thing or output 'Who are you?'

Instead of outputting 'Oh, it's you' it outputs 'who is this?'

Why doesn't this work?

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
Shah Jacob
  • 137
  • 1
  • 9
  • 1
    You've accidentally performed a pointer comparison. [Arrays decay to pointers](https://stackoverflow.com/questions/1461432/what-is-array-to-pointer-decay) and `"Shah Bhuiyan"` is a [String Literal](https://en.cppreference.com/w/cpp/language/string_literal), another array. So `name == "Shah Bhuiyan"` compares two addresses and, because they are both different objects, they can't possibly be pointing at the same place. – user4581301 Sep 23 '21 at 21:02
  • Solution: Use [`strcmp`](https://en.cppreference.com/w/c/string/byte/strcmp) or convert `char name[1000];` to [`std::string name;`](https://en.cppreference.com/w/cpp/string/basic_string) and use [`std::getline`](https://en.cppreference.com/w/cpp/string/basic_string/getline) in place of `std::cin.get`. – user4581301 Sep 23 '21 at 21:04
  • cool, so how do i fix it? also i read the link you shared about array decays to pointers and don't understand - how does array decaying to pointers relate to this situation? and can you tell me how to fix it. – Shah Jacob Sep 23 '21 at 21:04
  • Decay gets involved because you can't compare arrays directly. They decay to pointers and the pointers are compared. – user4581301 Sep 23 '21 at 21:06
  • This is C++, not C, so why are you using `char` arrays as strings? `std::string name; std::getline(std::cin, name); name == "..." ? ... : ...;` would work without `strcmp`, **and** you wouldn't need to think about the max string size. – HolyBlackCat Sep 23 '21 at 21:09
  • honestly, what does pointer decay even mean? i saw in the link that it means loss of size/dimensionality, but here how does a array 'decay' into a pointer? where is the pointer in my soure code? also, how do you know im comparing pointers? im trying to compare the string `shah bhuiyan` to the user input stream in cin not comparing two pointers – Shah Jacob Sep 23 '21 at 21:09
  • @HolyBlackCat not sure, i just used what i googled. okay so std::string name will work, and then i can use std::getline(std::cin, name)? but that syntax is a little confusing. first why are you inserting `std::cin` as the first argument to `std::getline()`. second where is `name == ".."` coming from is that the same line/part of the code where you use `std::getline()`? – Shah Jacob Sep 23 '21 at 21:11
  • *"where is `name == ".."` coming from"* What I mean is that `name == "Shah Bhuiyan" ? std::cout ...` will work as is, if you use `std::string`. *"why are you inserting `std::cin` as the first argument"* Unsure how to answer. This is just how `std::getline` works; the first arg is the source stream from which the string is obtained. – HolyBlackCat Sep 23 '21 at 21:13
  • @HolyBlackCat got it, so `name == "Shah Bhuiyan" ? std::cout ...` is jut the next line. however i have two questions. first why didn't my original code work? what was the issue with trying to compare the value in the input stream cin and the string `"shah bhuiyan"`. second is getline() an object or function – Shah Jacob Sep 23 '21 at 21:16
  • 2
    You will learn the C++ basics much faster if you spend some time with a [good C++ book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). Just guessing will be slow and error prone. – Blastfurnace Sep 23 '21 at 21:20
  • 1
    *"is getline() an object"* `std::getline` is a function, `std::cin` is a variable. *"first why didn't my original code work"* Most things you can do with arrays will implicitly convert the arrays to pointers to their first elements (said conversion is also called "decay"). This happened to `name` and `"Shah Bhuiyan"` in your original code (both are arrays). Since those are two different arrays (I'm not talking about the contents), their first elements have different addresses, hence `==` returned false. – HolyBlackCat Sep 23 '21 at 21:20
  • @HolyBlackCat thanks. how is `"Shah Bhuiyan"` an array? and what do you mean converts to pointers in their first elements? what first elements in the array does it get converted to? – Shah Jacob Sep 23 '21 at 21:27
  • 1
    `string`s allow comparisons with `==`, but `char name[1000];` is not a `string`. It is an array. `"Shah Bhuiyan"` is also not a `string`. It is a [String Literal](https://en.wikipedia.org/wiki/String_literal), another array. – user4581301 Sep 23 '21 at 21:28
  • so are you saying i was trynig to compare two pointers and it didn't work? well why does `std::getline(std::cin, name)` and then doing `name == "Shah Bhuiyan"` work – Shah Jacob Sep 23 '21 at 21:36
  • If you use `std::getline(std::cin, name)`, then `name` must be a `string` and `strings` know how to compare with character arrays with the `==` operator. – user4581301 Sep 23 '21 at 22:00
  • @user4581301 you said "Shah Bhuiyan" is an array when it literally looks exactly like a string? – Shah Jacob Sep 23 '21 at 22:12
  • Yes. String Literals are inherited from the C programming language where there are no `string`s. Just arrays of characters with a null on the end. – user4581301 Sep 23 '21 at 22:19
  • 1
    after reading that article and thinking it over - correct me if i got it wrong. so i compared to arrays, one of them was whatever was inside the input stream in `cin` against '"Shah Bhuiyan" in 'char name[100]`. but that's wrong, because what it actually ended up doing was compare the memory addresses of the first element in both arrays because of 'pointer decay'. how close am i? – Shah Jacob Sep 23 '21 at 22:33

3 Answers3

2

Your code is using arrays of characters. Any comparisons using == will compare their memory address. Since name and "Shah Bhuiyan" are two distinct arrays of characters, it will always be false.

The obvious solution is to use c++ strings from the standard library:

#include <iostream>
#include <string>   

int main()
{
    std::string name;
    std::cout << "What is your name?\n";
    std::getline(std::cin, name);

    name == "Shah Bhuiyan" ? std::cout << "Okay, it's you\n" : std::cout<< "Who is this?\n";
}

The std::string type has operators defined that do the right thing here, and will compare the values of each.

Guillaume Racicot
  • 39,621
  • 9
  • 77
  • 141
  • i marked your answer as the correct one, thanks. however i have a question. why do you say my src code involved pointers? i understand i was using arrays when i did `char name[1000]`, but why are pointers and memory addresses involved? all i did was do the `== "Shah Bhuiyan"` thing by comparing equality to a string, no? someone said "Shah Bhuiyan" was actually a string. – Shah Jacob Sep 23 '21 at 22:17
  • There is the concept of a string, which is nothing but a bunch of characters in a row, and a `string` which is an object that manages a string. By itself a string is pretty stupid and in C++ you often don't know much more than where it starts. Usually you have to keep reading characters until you find a null character that marks the end. A `string` object is much more complicated and [has a much smarter interface](https://en.cppreference.com/w/cpp/string/basic_string) for working with it. `"Shah Bhuiyan"` is the stupid sort of string, just a bunch of characters and a null terminator. – user4581301 Sep 23 '21 at 22:26
  • @ShahJacob To have a meaningful conversation with other C++ programmers you need to know a certain minimum set of terminology, and if you do not have this knowledge, you can't even ask basic questions effectively. If the other programmers understand you and can answer the question, odds are high you won't understand their answers. That's the case here. The best tool to learn this minimum terminology is [a good C++ text book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – user4581301 Sep 23 '21 at 22:31
  • 1
    @user4581301 just downloaded the C++ Programming Practices book by Bjarne. thanks – Shah Jacob Sep 23 '21 at 22:41
  • @ShahJacob c-style arrays decays into pointer during any operations. This is true for `"hello"` which is a character array, and also `char str[1000]`. Any operation like `==`, `[3]`, `++`, passing it in parameters of a function will first decay the array into a pointer. The types `std::string` and `std::string_view` are wrappers around character arrays to make them behave like string values, and implement value semantics. – Guillaume Racicot Sep 24 '21 at 12:03
  • @GuillaumeRacicot just curious (quick follow up question, and much thanks again). so the char arrays `'Shah Bhuiyan'` and the value in `name` are unequal because of the literal value they (which is ASCII characters), or is it because they have different locations in memory? – Shah Jacob Sep 27 '21 at 22:06
  • @ShahJacob In my answer, `name` is a `std::string`, so the comparison operation is comparing the values. If you have only char arrays, for example `"yo" == "yo"` is gonna be false, since all character array have different location, especially if one is on the stack and the other in the static memory. – Guillaume Racicot Sep 28 '21 at 15:33
1

Arrays do not have the comparison operator. In fact in this expression

name == "Shah Bhuiyan"

there are compared two pointers (due to the implicit conversion of array designators to pointers to their first elements): the first one is a pointer to the first character of the character array name and the second one is a pointer to the first character of the string literal.

As the array and the string literal occupy different extents of memory the comparison of the addresses will always evaluate to false.

You need to use the standard C string function strcmp to compare two strings.

#include <cstring>

//...

std::strcmp( name, "Shah Bhuiyan" ) == 0 ? std::cout << "Okay, it's you\n" : std::cout<< "Who is this?\n";

If you want to use the equality operator == then instead of the character array use an object of the type std::string.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • why do i need to use strcmp? i want to use the functionality of strings in cpp not do the c-string stuff. also i am quite confused at what you just did... why are you setting `strcmp()` to `0`??? i mean why are you checking if strcmp is equal to 0, this is so confusing. im trying to check if the input is equal to the string `Shah Bhuiyan`. – Shah Jacob Sep 23 '21 at 21:07
  • @ShahJacob You declared a character array and are comparing character strings. If you want to use the operator == then declare an object of the type std::string. – Vlad from Moscow Sep 23 '21 at 21:12
0

You could use std::getline to read into std::string instead of C-style char buffer.

Vlad Feinstein
  • 10,960
  • 1
  • 12
  • 27