Why is a character converted to a digit when using toupper?

194 Views Asked by At

tinyc.h

#ifndef _TINYC_H
#define _TINYC_H

#include <string>
#include <vector>
#include <map>

namespace tinyc {

using token_t = std::map<std::string, std::string>;
using tokens_t = std::vector<token_t>;

// const std::string DIGITS = "0123456789";
// const std::string WHITESPACE = " \t\n";
    
tokens_t tokenize(const std::string& str);
void print_tokens(const tokens_t& tokens);

} // namespace tinyc

#endif // _TINYC_H

main.cpp

#include <iostream>
#include "tinyc.h"

int main() {
    tinyc::tokens_t tokens;

    try {
        tokens = tinyc::tokenize("()");
    } catch (const std::string& e) {
        std::cerr << e << '\n';
    }

    tinyc::print_tokens(tokens);
}

This is the whole code.

In this part of the code in tinyc.h:

void print_tokens(const tokens_t& tokens) {
    if (!tokens.empty()) {
        for (const token_t& token : tokens) {
            for (const auto& token_pair : token) { // std::pair<...>
                for (const char& c : token_pair.first) { // token_pair.first = std::string
                    std::cout << ::toupper(static_cast<unsigned char>(c));
                }
                std::cout << ':' << token_pair.second << '\n';
            }
        }
    }
}

Inside this part, this here:

std::cout << ::toupper(static_cast<unsigned char>(c)); // Prints random digits. No idea why!? Changed toupper to tolower, un-typecasted it, etc, but nothing worked.

Prints random digits. I have no idea why. I changed toupper to tolower, didn't typecast it, etc, but nothing worked.

But for some reason, this code below works perfectly fine:

std::cout << c;

This code below, std::cout << c, works perfectly fine and prints the actual characters, not any random digits.

I've also tried (c & ~32) to upper case it but same results, it prints random digits.

            tokens.push_back({
                { "type", "rparen" },
                { "value", ")" }
            });

This is how I insert a map in the vector; am I doing this wrong? Is this what causes the issue?

Why is this printing random digits when it should be printing characters?

1

There are 1 best solutions below

2
On

Function int toupper( int ch ); is inherited from C, so it returns int. To print properly, you need to typecast back to char:

std::cout << static_cast<char>(::toupper(static_cast<unsigned char>(c)));