控制台输出中奇怪的非ASCII字符

时间:2013-05-22 22:49:15

标签: c++ console-application

以下是几个看似随机的另一个夜晚的例子,导致在控制台中显示奇怪的ascii字符。例如,player.level显示笑脸ascii字符。有些只显示几个空格,有些则显示单个奇怪的ascii字符。

图片示例:

代码工作正常,我遇到了一些我修复过的编译器问题。大约在同一时间我将很多“int”数据类型更改为uint8_t等。一旦我修复了编译器问题,我就开始看到这个新问题了。

语言:C ++(11)(CodeBlocks IDE)

//randstats.cpp

#include "encounter.h"
#include "player.h"
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int_distribution.hpp>
#include <iostream>
#include "createchar.h"
#include "randstats.h"

boost::random::mt19937 gen;

player_vars randStats()
{
    /*
        Randomize new characters stats if the player chooses to do so rather than manually assign them.
        Also going to use this to test against random encounters for balance purposes.
    */

    player.str = 8;
    player.dex = 8;
    player.con = 8;
    player.intel = 8;
    player.wis = 8;
    player.cha = 8;
    uint8_t remaining_points = 25; // starting pts to hand out freely
    uint8_t total_possible = player.str + player.dex + player.con + player.intel + player.wis + player.cha + remaining_points; // max points to assign

    /*
        Basically the whole purpose of this is to pick random numbers and spread them out among random stats.
        The stats will not be higher than total_possible + remaining points (assigned above).
    */

    while (remaining_points > 0)
    {

        boost::random::uniform_int_distribution<> dist13(1, 3);
        uint8_t random_number = dist13(gen);

        uint8_t x = 0;
        // Get current or total points currently assigned
        uint8_t totalpts = player.str + player.dex + player.con + player.intel + player.wis + player.cha;

        //if we're in range and won't go over
        if ((totalpts < total_possible) && ((random_number + totalpts) < total_possible))
        {
            x = random_number;
            // remaining_points - x;
        }
        //if we're going to go over, only assign the number of points from random that will stop us at 73 points
        else if ((random_number + totalpts) > total_possible)
        {
            // Since we're going over the max total points, how many do we assign to a stat?
            uint8_t y = totalpts - total_possible;
            x = abs(y);
            remaining_points = 0; //force this because we exceeded
        }

        //random numbering choosing which stat the points go to
        boost::random::uniform_int_distribution<> dist16(1, 6);

        switch(dist16(gen))
        {
        case 1 :
            player.str += x;
            break;
        case 2 :
            player.dex += x;
            break;
        case 3 :
            player.con += x;
            break;
        case 4 :
            player.intel += x;
            break;
        case 5 :
            player.wis += x;
            break;
        case 6 :
            player.cha += x;
            break;
        default :
            break;
        }

    }

    //print the new results
    std::cout << "\nNew Character Stats: \n";
    std::cout << "Strength: [" << player.str << "]" << std::endl;
    std::cout << "Dexterity: [" << player.dex << "]" << std::endl;
    std::cout << "Constitution: [" << player.con << "]" << std::endl;
    std::cout << "Intelligence: [" << player.intel << "]" << std::endl;
    std::cout << "Wisdom: [" << player.wis << "]" << std::endl;
    std::cout << "Charisma: [" << player.cha << "]" << std::endl;
    std::cout << "Total Points Assigned: " << player.str + player.dex + player.con + player.intel + player.wis + player.cha << std::endl;

    std::cout << "Accept these results? [y/n]: ";
    char selection;
    std::cin >> selection;

    switch(selection)
    {
    case 'Y' :
    case 'y' :
        createPlayer();
        break;
    case 'N' :
    case 'n' :
        randStats();
        break;
    default:
        std::cout << "\nInvalid response. Keeping results.\n";
        createPlayer();
    }

    return player;
}//close function


   //player.h
   #ifndef PLAYER_H_INCLUDED
   #define PLAYER_H_INCLUDED

   #include <string>
   #include <cstdint>

   struct player_vars {
    std::string alias;
    uint8_t current_level;
    bool is_alive; // alive or dead
    uint8_t str;
    uint8_t dex;
    uint8_t con;
    uint8_t intel;
    uint8_t wis;
    uint8_t cha;
    uint32_t gold;
    std::string profileName; // may use
    int16_t hitpoints; // current HP dependent on class, level, feats, con, etc.
    uint8_t size_id; // character size
    uint8_t class_id; // check comments
    uint8_t base_attack_bonus; // dependent on player's class
    uint8_t weapon_id; // check comments

    uint8_t getHitPoints();

    }; extern player_vars player;

1 个答案:

答案 0 :(得分:2)

uint8_t通常typedefunsigned char。这在C中很有用。

C ++的流操作符正在查看您的unsigned char值并尝试将它们打印为字符,而不是将整数转换为字符串。所以你所看到的是特定终端/控制台决定为该字符代码显示的内容。

省去麻烦,坚持int。我们只讨论4个字节而不是1个字节。而且不必担心255的极小限制。

如果确实希望将您的数据存储为uint_8,那么您需要先将其转换为int,然后再将其转换为cout

std::cout << "Strength: [" << (int)player.str << "]" << std::endl;