1

I'm writing a program in c++ and I'm trying to separate letters like this: "A,B,C"

But it comes out like this, and I don't know why: ",A,B,C".

Help?

My code is below:

#include <iostream>

#include <ctype.h>

using namespace std;


int main()

{
    
    
    char startChar='Z';
    
    char stopChar='A';
    
    while (startChar>stopChar)
        
    {
        
        cin >> startChar;
        
        startChar = toupper(startChar);
        
        
        cin >> stopChar;
        
        stopChar=toupper(stopChar);
        
    }
    
    for (char chLoop=startChar; chLoop<=stopChar; chLoop++)
        
    {
        if (stopChar > startChar)
            cout << ",";
        
        
        cout <<chLoop;
    }
    
}

thanks!

Lywo
  • 23
  • 4

2 Answers2

3

When stopChar is C and startChar is A, this condition will be true and therefore a , will be printed in every iteration of the loop (including the first):

if (stopChar > startChar)
    cout << ",";

You can fix it by changing it to:

if (chLoop != startChar)
    std::cout << ',';

That is, only if chLoop is not startChar, print a ,.

Another option that doesn't require an if at all:

std::cout << startChar;         // print the first char before the loop
for (char chLoop = startChar + 1; chLoop <= stopChar; chLoop++) {
    std::cout << ',' << chLoop; // now print the , unconditionally
}
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
2

Ted Lyngmo’s answer is correct. I just wanted to add some useful information about generating sequences with joiners (or separators).

The usual idiom in C++ works by printing your first element, then printing the remaining elements with the joiner prepended. For example:

char first = 'A';
char last  = 'Z' + 1;  // in C++, last/end is always _one past_

std::cout << first;
while (++first != last)
{
  std::cout << "," << first;
}

In general, you also want to check to make sure you have at least one element before you start:

char first = 'A';
char last  = 'Z' + 1;  // in C++, last/end is always _one past_

if (first != last)     // make sure there is at least one item to print
{
  std::cout << first;
  while (++first != last)
  {
    std::cout << "," << first;
  }
}

This works for any sequence you can get iterators for as well:

std::vector xs = { 2, 3, 5, 7, 11 };

auto first = xs.begin();
auto last  = xs.end();

if (first != last)
{
  std::cout << *first;
  while (++first != last)
  {
    std::cout << "," << *first;
  }
}

Everything is a variation of this. Here’s one some people like and others hate, but typically gets good performance on std::string and std::ostream:

if (first != last)
  std::accumulate( std::next(first), last, *first, [&delimiter]( auto a, auto b )
    {
      return a.append( delimiter ).append( b );
    } );

C++ can’t leave things alone, though, and programmers want smaller, simpler, prettier code. There’s an entire thread about this operation, and Kikuko’s answer gives you a C++20 ranges_v3 solution.

Dúthomhas
  • 8,200
  • 2
  • 17
  • 39