user1528014
user1528014

Reputation:

How would i change every character in the string a different color instead of the whole string

#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;
}

If I messed this post up I apologize this is only like my second post.

What would be the easiest way to make every character in the string a different color, instead of the entire string the same color.

Tidying up tips would be appreciated as well :P

EDIT: tidy'd up a little, and the random is working well, thank you all ^_^ now for the color by character?

Upvotes: 2

Views: 1779

Answers (3)

bames53
bames53

Reputation: 88155

In order to colorize by character you have to manually iterate through the characters of the string and set the color attribute before outputting each character.

(The below code iterates by char. This doesn't work for character sets that actually use multi-byte encodings. To support those you'll have to use an API to iterate over the string by actual, user perceived characters instead of by char.)

This code has several other changes as well.

#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);
    }
}

I'm using the C++11 <random> library for random numbers because it's better than rand(). It provides many ready-made distributions and is harder to get wrong (rand() % 15 + 1 has a slight bias even if rand() is high quality, which it probably is not).

I extracted the repeated code into a function to eliminate the duplication. Then I replaced the two for loops with a function that has the zigzag output that exactly matches what the two for loops were doing with sz.

I replaced the do {} while() infinite loop with a more readable and idiomatic while(true){}.

I eliminated the string variable that was being resized for the spacing in favor of constructing a temporary each iteration. This does mean there could be an allocation each iteratation instead of a simple resize (although the small string optimization will probably avoid it) but the performance is irrelevant in this case.

Upvotes: 1

user529758
user529758

Reputation:

Why does it not seem random? Well, because it isn't. Computers use pseudorandom number generators to produce seemingly random numbers which are actually well-known and determinate.

The initial state of the pseudorandom generator is called a 'seed'; you have to set it to something different every time to produce more-close-to-random results. In C, you can do it like this:

srand(time(NULL));

This sets the seed to the actual time in seconds upon every call.

Upvotes: 1

You need to provide a seed for your random number generator prior to first use.

An example of using srand to initialize the random number generator is:

/* 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;
}

Upvotes: 0

Related Questions