我如何将字符串中的每个字符更改为不同的颜色而不是整个字符串

时间:2012-08-01 15:28:37

标签: c++ string colors

#include "stdafx.h"
#include <iostream>
#include <string>
#include <windows.h>
#include <time.h>

unsigned long n = 1;

int main()
{
    int i = 0;
    std::string text = "I whip my hair back and forth";
    std::string wipIt = " ";
    size_t sz;
    sz = wipIt.size();
    srand(time(0));

    do{
        for(i = 0; i < 10; i++)
        {
            int randomNumber = rand() % 15 + 1;
            Sleep(50);
            wipIt.resize (sz++,' ');
            std::cout << wipIt;
            SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), randomNumber);
            std::cout << text << "\n";
        }
        for(i = 10; i > 0; i--)
        {
            int randomNumber = rand() % 15 + 1;
            Sleep(50);
            wipIt.resize (sz--,' ');
            std::cout << wipIt;
            SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), randomNumber);
            std::cout << text << "\n";
        }
    }
    while (n != 0);
    return 0;
}

如果我把这篇文章搞砸了,我很抱歉这只是我的第二篇文章。

将字符串中的每个字符设置为不同颜色,而不是整个字符串使用相同颜色的最简单方法是什么。

整理技巧也将受到赞赏:P

编辑:整理一下,随机效果很好,谢谢大家^ _ ^现在按颜色逐字逐句?

3 个答案:

答案 0 :(得分:1)

为什么它看起来不随机?好吧,因为它不是。计算机使用伪随机数生成器来生成看似随机的数字,这些数字实际上是众所周知的并且是确定的。

伪随机生成器的初始状态称为“种子”;你必须每次都将它设置为不同的东西,以产生更接近随机的结果。在C中,你可以这样做:

srand(time(NULL));

这会将种子设置为每次通话时的实际时间(以秒为单位)。

答案 1 :(得分:1)

要按字符着色,您必须手动迭代字符串的字符,并在输出每个字符之前设置颜色属性。

(下面的代码按char进行迭代。这对于实际使用多字节编码的字符集不起作用。为了支持那些你必须使用API​​来迭代字符串的实际,用户感知的字符而不是char。)

此代码还有其他一些更改。

#include <iostream>
#include <string>
#include <random>

#include <Windows.h>

void colorize(size_t spacing, std::string const &s, std::mt19937 &eng) {
    std::cout << std::string(spacing, ' ');
    std::uniform_int_distribution<> dist(1,15);
    for (size_t i=0; i<s.size(); ++i) {
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), dist(eng));
        std::cout << s[i];
    }
    std::cout << '\n';
}

int main() {
    std::string text = "I whip my hair back and forth";
    int sz = 0;

    std::random_device r;
    std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()};
    std::mt19937 eng(seed);

    while (true) {
        int spacing = 11 - abs(10 - sz);
        sz = (sz+1) % 20;
        Sleep(50);
        colorize(spacing, text, eng);
    }
}

我正在使用C ++ 11 <random>库来获取随机数,因为它比rand()更好。它提供了许多现成的发行版,并且更难以出错(即使rand() % 15 + 1质量很高,rand()也有轻微的偏见,但可能不是这样。)

我将重复的代码提取到函数中以消除重复。然后我用一个具有zigzag输出的函数替换了两个for循环,该函数与两个for循环用sz完全匹配。

我将do {} while()无限循环替换为更具可读性和惯用性while(true){}

我删除了为间距调整大小的字符串变量,有利于构造临时的每次迭代。这意味着每个迭代都可以分配而不是简单的大小调整(尽管小字符串优化可能会避免它)但在这种情况下性能无关紧要。

答案 2 :(得分:0)

您需要在首次使用之前为随机数生成器提供种子。

使用srand初始化随机数生成器的example是:

/* srand example */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main ()
{
  printf ("First number: %d\n", rand() % 100);
  srand ( time(NULL) );
  printf ("Random number: %d\n", rand() % 100);
  srand ( 1 );
  printf ("Again the first number: %d\n", rand() %100);

  return 0;
}