【问题标题】:How would i change every character in the string a different color instead of the whole string我如何将字符串中的每个字符更改为不同的颜色而不是整个字符串
【发布时间】:2012-07-30 13:03:18
【问题描述】:
#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

编辑:整理了一下,随机的效果很好,谢谢大家^_^现在按字符着色?

【问题讨论】:

  • std::srand(std::time(0))(来自 )在您第一次调用 std::rand() 之前。这为伪随机数生成器设置了一个种子,该生成器是相当随机的(rand() 本质上只是迭代一长串数字,这些数字预计以随机的外观模式分布。srand(seed) set 是 rand, time 的种子(0) 是自纪元以来的当前时间(以秒为单位)(通常无论如何,无论哪种方式,它都是某些度量中的当前时间)。
  • 整理提示:您使用了很多额外的牙套。我有时会使用额外的大括号来限制特定变量的生命周期,但是这里有些大括号除了弄乱缩进之外什么都不做。我会删除那些。
  • 整理提示:您正在混合不同的变量大小写风格。选择一种风格,并坚持下去;)
  • endl 都添加新行并刷新缓冲区。这可能会导致输出性能受到很大影响。几乎总是你只想写一个换行符:cout &lt;&lt; Test &lt;&lt; '\n';using namespace std; 在开始编程示例中也被大量使用,但 IMO 最好不要使用它,而只是限定名称:std::cout &lt;&lt; Test &lt;&lt; '\n'; 或使用更具体的使用声明:using std::cout; ... cout &lt;&lt; Test;
  • @BoBTFish 因为这是使用endl 的Windows 控制台,实际上并不需要立即显示输出,IMO 最好养成不使用endl 的习惯。但是您是对的,在其他平台上,此应用程序可能需要刷新,因此是需要 endl 的少数情况之一(或您指出的 flush,因为我认为您可能是对的更清楚)。

标签: c++ string colors


【解决方案1】:

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

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

srand(time(NULL));

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

【讨论】:

    【解决方案2】:

    为了按字符着色,您必须手动遍历字符串的字符并在输出每个字符之前设置颜色属性。

    (下面的代码通过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 &lt;random&gt; 库用于随机数,因为它比 rand() 更好。它提供了许多现成的发行版,并且更难出错(rand() % 15 + 1 有轻微的偏差,即使 rand() 质量很高,但它可能不是)。

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

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

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

    【讨论】:

      【解决方案3】:

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

      使用 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;
      }
      

      【讨论】:

      • 请不要引用 cplusplus dot com。这是一个糟糕的网站,包含很多不良信息。
      • Shahbaz 需要详细说明吗?我在 cplusplus.com 和 cppreference 上的参考资料之间交替使用,通常我觉得没有太大区别。
      • @Cubic:几年前,那里的一些信息有点粗略,名声不好。这些天看起来很好,虽然我相信如果你足够努力的话,你可能会犯奇怪的错误,而且我希望每次在这里引用它时的下意识反应都不会结束。
      • @Shahbaz 这个特定的例子有什么问题吗,还是你一般不喜欢这个网站?
      猜你喜欢
      • 2011-09-12
      • 2016-09-27
      • 1970-01-01
      • 2013-09-04
      • 2017-11-07
      • 1970-01-01
      • 2018-06-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多