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!
CodePudding user response:
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
}
CodePudding user response:
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.
