A C++ program to check if a string is a pangram I'm new to C++ and decided to implement a simple program that checks if a string is a pangram (i.e. the string contains all the English alphabet letters). It's my first program in C++ and I have some background with interpreted programming languages like Python and R.
I want to know what are the common beginners mistakes I'm making in this implementation, whether I'm following good practices, what I should avoid etc.
The Code
#include&lt;iostream&gt;
#include&lt;string&gt;
#include&lt;vector&gt;
#include &lt;algorithm&gt;

bool isPangram(std::string str) {
    std::transform(str.begin(), str.end(), str.begin(), ::toupper); // Transforming a string to upper case
    std::vector&lt;bool&gt; hash_table(26, false); // a hash_table that maps the  index of a letter from the alphabet
                                             // and a boolean saying if the string contains this element                                             
    int index;
    for(auto c: str){
        if(isalpha(c))
            // Checks if the element in the string is in the alphabet
            index = c - 'A';
            hash_table[index] = true; 
            std::cout &lt;&lt; index &lt;&lt; std::endl;

    };

    if(std::any_of(hash_table.begin(), hash_table.end(), [](bool v) { return !v; })) {
        // if any of the items in the array evaluates to false
        // means that the string don't contain all the elements 
        // in the alphabet,hence, it's not a pangram

        return false;
    }
    return true;    
};

int main() {
    std::string str = &quot;We promptly judged antique ivory buckles for the next prize&quot;; 
    if (isPangram(str)){ 
         std::cout &lt;&lt; &quot;Yes&quot; &lt;&lt; std::endl; 
     }
     else {
         std::cout &lt;&lt; &quot;No&quot; &lt;&lt; std::endl; 
     };
     return 0;
}
```
Here are a number of things that may help you improve your program.
Make sure you have all required #includes
The code uses toupper but doesn't #include &lt;cctype&gt;.
Eliminate spurious semicolons
The code has a number of spurious semicolons immediately after closing braces.  They don't bother the compiler but they will bother any other programmer who looks at your code.
Check your if statements for proper braces
It appears from the indentation in the if statement in the isPangram routine is not what you intended to write.  The only thing that is currently associated with the if statement is index = c - 'A'; -- all of the lines after that are executed in every case.
Initialize variables before use
The index variable, as mentioned above, may or may not actually get initialized to anything as it's currently written.  That leads to undefined behavior of your program, which is not a good thing.  Best practice is to initialize variables when they are declared.
Return boolean values directly
The isPangram ends with this strange construct:
if(std::any_of(hash_table.begin(), hash_table.end(), [](bool v) { return !v; })) {
    return false;
}
return true;

Here's a much more direct way to do that:
return std::all_of(hash_table.begin(), hash_table.end(), [](bool v){return v;});

Similarly, within main, I'd write this:
std::cout &lt;&lt; (isPangram(str) ? &quot;Yes&quot; : &quot;No&quot; ) &lt;&lt; '\n';

Consider a more efficient approach
Consider that the the transform must necessarily visit every letter.  We then make another pass through with the main loop.  It is possible to do everything in a single pass.
Don't use std::endl unless you really need to flush the stream
The difference between std::endl and '\n' is that std::endl actually flushes the stream. This can be a costly operation in terms of processing time, so it's best to get in the habit of only using it when flushing the stream is actually required. It's not for this code.
Eliminate return 0 at the end of main
When a C++ program reaches the end of main the compiler will automatically generate code to return 0, so it is not necessary to explicitly write that.  Some people prefer to do so for style reasons, but it's important to know that it's not required by the standard.
Consider using std::spanstd::accumulate
If your compiler is C++20 capable, this would be a good use of std::accumulate (not std::span as I originally wrote).  This version is faster than anything so far.
// helper function for isPangram_accum
constexpr uint_fast32_t charToMask(const unsigned char c){ 
    // can't use non-const toupper in constexpr function
    unsigned index{(c | 0x20u) - 'a'};
    return index &lt; 26 ? ~(1u &lt;&lt; index) : ~0;
}

bool isPangram_accum(const std::string&amp; str) {
    uint_fast32_t present{(1u &lt;&lt; 26) - 1};
    constexpr auto letterMask = [](uint_fast32_t collection, char ch) {
      if (collection)
        collection &amp;= charToMask(ch);
      return collection;
    };
    return std::accumulate(str.begin(), str.end(), present, letterMask) == 0;
}