简体   繁体   中英

Need help creating a loop

My loop needs to be able to generate the letters ABC ext. verticaly like this:

A
B
C 

Yet when it reaches letter J it needs to start over. The user inputs how many lines to generate through the command line. I'm having trouble figuring out a way to make the loop start over after it reaches the letter J. I have my code here:

#include <iostream>

using namespace std;

int main(int argc, char **argv)
{
    int letter = 65;

    for(int i = 0; i < atoi(argv[1]); i++)
    {
        cout <<(char)letter++;
        cout << endl;

        if(letter == 75)
        {
            int letter = 65;
        }
    }   

    return(0);
}

Notice that the int letter is replaced with letter inside the if statement

#include <iostream>
#include <cstdlib>

using namespace std;

int main(int argc, char **argv)
{
    int letter = 65;

    for(int i = 0; i < atoi(argv[1]); i++)
    {
        cout <<(char)letter++;
        cout << endl;

        if(letter == 75)
        {
            letter = 65;
        }
    }

    return(0);
}

Output with input as 16:

A
B
C
D
E
F
G
H
I
J
A
B
C
D
E
F

You could do this:

#include <iostream>
#include <cassert>
#include <cstdlib>

int main(int argc, char **argv)
{
  using namespace std;

  assert(argc >= 1 + 1); //Fail with an error message rather than a segfault if the argument isn't provided

  int n_iterations = atoi(argv[1]);
  int range_size = 'J' - 'A' + 1; //include 'J'

  for(int i=0; i < n_iterations; i++){
    cout<< char('A'+i % range_size) << '\n';
  }

  return 0;
}

The main points are:

  • call atoi once rather than in each iteration
  • descriptive code (ie, 'A' ) is better than magic numbers
  • to wrap around a number, use i % range_size rather than if
  • not flushing after each line ( endl flushes) will be better for performance in pipelines (if you want performance you'll also likely want to turn of syncing with stdio by doing ios::sync_with_stdio(false); )

If you really want to use if , then the problem of:

 if(letter == 75)
        {
            int letter = 65;
        }

is that since int letter = 65; is in a new scope (=pair of curly braces), it will create a new local letter variable that will overshadow the original letter .

if(letter == 75){
   letter = 65;
}

should solve the problem.

Here :

 if(letter == 75)
 {  
  int letter = 65;
 }

You are redeclaring letter inside the braces, instead of modifying your existing letter variable. This letter variable is local to that block, and hides your other letter variable.

You could have debugged this yourself by putting a breakpoint at the start of your program, and watching the letter variable there. You would have noticed it is not modified when going into the if .

Try this:

   if(letter == 75)
      {
        letter = 65;
       }

There are many ways to do the task. For example you could write the program the following way

#include <iostream>
#include <cstdlib>

int main( int argc, char **argv )
{
    const int N = 'J' - 'A' + 1;

    int n = 0;

    if ( argv[1] ) n = std::atoi( argv[1] ); 

    for ( int i = 0; i < n; i++ ) std::cout << char( 'A' + i % N ) << std::endl;
}    

For example if the command line argument will be set to 14 then the output will look like

A
B
C
D
E
F
G
H
I
J
A
B
C
D

Or you can write the main loop as it is shown in this demonstrative program

#include <iostream>
#include <cstdlib>

int main( int argc, char **argv )
{
    const char A = 'A', J = 'J';

    int n = 0;

    if ( argv[1] ) n = std::atoi( argv[1] ); 

    for ( char c = A; n-- > 0; c == J ? c = A : ++c ) std::cout << c << std::endl;
}    

The output will look the same way as above.

One more approach.

#include <iostream>
#include <cstdlib>

int main( int argc, char **argv )
{
    const char *letters = "ABCDEFGHIJ";

    int n = 0;

    if ( argv[1] ) n = std::atoi( argv[1] ); 

    for ( const char *p = letters; n-- > 0; *++p ? p : p = letters )
    {        
        std::cout << *p << std::endl;           
    }        
}    

As for your code then you should not use magic numbers like 65 or 75. First of all it makes difficult to understand the code and in other coding systems as for example EBCDIC these magic numbers will not make sense.

Also in this code snippet

if(letter == 75)
{
    int letter = 65;
}

you are declaring one more local variable with name letter that will not be alive after the closing brace. So this code snippet also does not make sense.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM