Why am I getting an extra blank line at the end of my output?

  • Context:
  • Thread starter Thread starter YoungPhysicist
  • Start date Start date
  • Tags Tags
    Line Output
Click For Summary

Discussion Overview

The discussion centers around a programming issue related to C++ code that produces an extra blank line at the end of output when formatting a list of names. Participants explore various coding practices, potential causes of the issue, and alternative approaches to achieve the desired output format.

Discussion Character

  • Technical explanation
  • Debate/contested
  • Mathematical reasoning

Main Points Raised

  • One participant describes the problem of an extra newline character appearing after the output and shares their code.
  • Another participant explains the behavior of the "break" statement, clarifying that it only exits the innermost loop.
  • Concerns are raised about the use of global and local variables with the same name, suggesting that it is poor practice.
  • Some participants suggest checking for additional whitespace characters to prevent printing unwanted newlines.
  • A participant proposes modifying the code to exit both loops when necessary to avoid the extra newline.
  • Alternative code snippets are provided, with some participants noting issues with capitalization and the handling of the last character in names.
  • There are multiple suggestions for using the C++ `std::string` type instead of C-style strings, with some participants questioning the relevance of using char arrays in modern C++ programming.
  • One participant expresses gratitude for a solution that worked for them, while acknowledging previous coding habits that led to confusion.

Areas of Agreement / Disagreement

Participants express a range of opinions on coding practices, the handling of strings, and the specific implementation details of the code. There is no consensus on a single solution, as multiple approaches are discussed and some participants continue to refine their ideas.

Contextual Notes

Some code snippets provided contain errors or inconsistencies, such as incorrect variable names and potential logical flaws. Participants also note the importance of handling different newline conventions across operating systems.

Who May Find This Useful

Programmers and students interested in C++ coding practices, string manipulation, and debugging output formatting issues may find this discussion relevant.

YoungPhysicist
Insights Author
Messages
350
Reaction score
203
Note: this is not a homework question!
The problem that this program should solve is turn a input like this:(no space and the end of the input string)
Code:
james shawn charles nicholas
into something like this:
Code:
James
Shawn
Charles
Nicholas
But I keep getting an excess line at the bottom of all outputs like this:
Code:
James
Shawn
Charles
Nicholas
                  <-This line
So my code send an excess ‘\n’,but I can’t find which part of my code went wrong.
My code:
Code:
#include<iostream>
#include<string.h>
using namespace std;
char n[1000];
int lcv = 0;
int main(){
   cin.getline(n,300);
   cout<<char(toupper(n[0]));
   for(unsigned short lcv = 1;lcv<strlen(n)-1;lcv++){
       while(n[lcv] != ' '){
           if(lcv>=strlen(n))
           break;
           cout<<n[lcv];
           lcv++;
       }
       cout<<'\n'<<char(toupper(n[lcv+1]));
       lcv++;
   }
return 0;
}
 
Last edited:
Technology news on Phys.org
The "break" statement only takes you out of the "while { ...} " code. It doesn't cause the program to skip the
Code:
cout<<'\n'<<char(toupper(n[lcv+1]));
statement.
 
  • Like
Likes   Reactions: QuantumQuest and YoungPhysicist
To elaborate on what @Stephen Tashi said, break exits the innermost enclosing loop, which in this case is the while loop. It doesn't get you out of the outer loop.

Some other comments:
  1. Why have you declared lcv twice? You have a global variable of type int with this name, and also a variable of the same name of a different type that is local to the for loop. Having global variables like this is generally a bad practice.
  2. Your variable names are not well chosen -- n is not a good name for a string variable. Single-letter names for variables are usually not good practice, except for loop control variables, which typically are called i, j, and the like. All other variable names should be chosen so that a reader can easily tell what they're supposed to represent.
 
  • Like
Likes   Reactions: QuantumQuest and YoungPhysicist
If you are reading your data from a text file then the new line \n is likely at the end of your line.

Try nulling out the last character of your line of data and see if it goes away or subtract one from the string length.

Also be aware that on windows systems text lines will have a CRLF ie \r\n termination.
 
  • Like
Likes   Reactions: QuantumQuest
A problem I see with your code is you are only checking for space characters, so you will print the \n character at the end of the line as though it were part of the last word which it isn't. For the cleanest code, you need a better check there. I personally would check for " \t\r\n" which should be good enough.
 
  • Like
Likes   Reactions: QuantumQuest and jedishrfu
Thanks everyone,problem solved.I simply add another expression to jump out of two loops at once.:smile::smile:
Code:
#include<iostream>
#include<string.h>
using namespace std;
char n[1000];
int main(){
 cin.getline(n,300);
 count<<char(toupper(n[0]));
 for(unsigned short i = 1;i<strlen(n)-1;i++){
  while(n[i] != ' '){
   if(i>=strlen(n))
   break;
   count<<n[i];
   i++;
  }
  if(i>=strlen(n))                       // HERE
  break;                                   // HERE
  count<<'\n'<<char(toupper(n[i+1]));
  i++;
 }
return 0;
}
 
That is horrible. Try
Code:
#include<iostream>
#include<string.h>
using namespace std;
char input[1000];
int main(){
 cin.getline(n,300);
 bool newword = true; /* If bool is not available (C < C99) use an int */
 for (int i = 0; i < strlen(n) - 1; i++) {
  if (n[i] == ' ') {
   newword = 1;
  } else if (newword) {
   newword = false;
   count<<'\n'<<char(toupper(n[i]));
  } else {
   count<<n[i];
  }
 }
return 0;
}
 
pbuk said:
That is horrible. Try
Code:
#include<iostream>
#include<string.h>
using namespace std;
char input[1000];
int main(){
 cin.getline(n,300);
 bool newword = true; /* If bool is not available (C < C99) use an int */
 for (int i = 0; i < strlen(n) - 1; i++) {
  if (n[i] == ' ') {
   newword = 1;
  } else if (newword) {
   newword = false;
   count<<'\n'<<char(toupper(n[i]));
  } else {
   count<<n[i];
  }
 }
return 0;
}
Thanks,but first,you forgot to replace my “n” with your “input”,second,it doesn’t work.It can’t get the last alphabet of every name.
85DF0A19-D197-4F7C-A3F4-FDAFB7E4AFC0.jpeg
 

Attachments

  • 85DF0A19-D197-4F7C-A3F4-FDAFB7E4AFC0.jpeg
    85DF0A19-D197-4F7C-A3F4-FDAFB7E4AFC0.jpeg
    20.4 KB · Views: 1,026
Sorry, didn't have a C compiler handy to test.
Code:
#include <iostream>
#include <string.h>

int main(){
  // Get the input string.
  char input[1000];
  std::cin.getline(input, 1000);

  // Set a flag for the first word (if bool is not available (C < C99) use an int).
  bool newword = true;
  for (int i = 0; i < strlen(input); i++) {
    // A space marks a new word but do not print it.
    if (input[i] == ' ') {
      newword = true;
    // Print the current character, capitalizing if necessary.
    } else if (newword) {
      // Reset the flag for the next character.
      newword = false;
      std::count << '\n' << char(toupper(input[i]));
    } else {
      std::count << input[i];
    }
  }
  return 0;
}
 
  • #10
C++ has had the std::string data type for 20 years (probably since before YoungPhysicist was born :oldwink:). Which C++ textbook/resource is he/she using, that still uses C-strings (char arrays)?

C:
#include <iostream>
#include <string>

int main ()
{
    std::count << "Enter a list of words on a single line:" << std::endl;
    std::string line;
    std::getline (std::cin, line);

    // Does not attempt to consolidate multiple spaces into a single newline.

    for (int k = 0; k < line.size(); ++k)
    {
        if (line[k] == ' ')
            std::count << '\n';
        else
            std::count << line[k];
    }
    std::count << std::endl;
    return 0;
}

Using the C++ 2011 standard, you can loop directly through the characters without using an index variable:

C:
#include <iostream>
#include <string>

int main ()
{
    std::count << "Enter a list of words on a single line:" << std::endl;
    std::string line;
    std::getline (std::cin, line);

    // Does not attempt to consolidate multiple spaces into a single newline.
    // Uses the range-based 'for' loop from C++ 2011 standard.

    for (char thisChar : line)
    {
        if (thisChar == ' ')
            std::count << '\n';
        else
            std::count << thisChar;
    }
    std::count << std::endl;
    return 0;
}

Oops, I forgot you want to capitalize the first letter of each word (name).
 
Last edited:
  • Like
Likes   Reactions: YoungPhysicist, QuantumQuest and pbuk
  • #11
jtbell said:
C++ has had the std::string data type for 20 years (probably since before YoungPhysicist was born :oldwink:). Which C++ textbook/resource is he/she using, that still uses C-strings (char arrays)?

C:
#include <iostream>
#include <string>

int main ()
{
    std::count << "Enter a list of words on a single line:" << std::endl;
    std::string line;
    std::getline (std::cin, line);

    // Does not attempt to consolidate multiple spaces into a single newline.

    for (int k = 0; k < line.size(); ++k)
    {
        if (line[k] == ' ')
            std::count << '\n';
        else
            std::count << line[k];
    }
    std::count << std::endl;
    return 0;
}

Using the C++ 2011 standard, you can loop directly through the characters without using an index variable:

C:
#include <iostream>
#include <string>

int main ()
{
    std::count << "Enter a list of words on a single line:" << std::endl;
    std::string line;
    std::getline (std::cin, line);

    // Does not attempt to consolidate multiple spaces into a single newline.
    // Uses the range-based 'for' loop from C++ 2011 standard.

    for (char thisChar : line)
    {
        if (thisChar == ' ')
            std::count << '\n';
        else
            std::count << thisChar;
    }
    std::count << std::endl;
    return 0;
}

Oops, I forgot you want to capitalize the first letter of each word (name).
Oops,I simply forgot it.:nb)(and all previous programs in my life)
 
  • #12
@pbuk your program worked!
833A8629-B251-49A2-9EFB-F48F163FE4D3.jpeg

If you can connect to this forum’s servers via internet,try this one:
https://www.onlinegdb.com/
Now you got a C/C++ compiler handy!
And thanks @jtbell for pointing out the string problem,I have use an index variable for my past couple years,thank you for reminding me that!
 

Attachments

  • 833A8629-B251-49A2-9EFB-F48F163FE4D3.jpeg
    833A8629-B251-49A2-9EFB-F48F163FE4D3.jpeg
    19.3 KB · Views: 910
  • #13
Young physicist said:
If you can connect to this forum’s servers via internet,try this one...
Thanks for the suggestion, although I currently use Repl.it.

EDIT: Mentor added code from repl.it for posterity:

C:
#include <iostream>
#include <string.h>

int main(){
// Get the input string.
char input[1000];
std::cin.getline(input, 1000);

// Set a flag for the first word (if bool is not available (C < C99) use an int).
bool newword = true;
for (int i = 0; i < strlen(input); i++) {
// A space marks a new word but do not print it.
if (input[i] == ' ') {
newword = true;
// Print the current character, capitalizing if necessary.
} else if (newword) {
// Reset the flag for the next character.
newword = false;
std::count << '\n' << char(toupper(input[i]));
} else {
std::count << input[i];
}
}
return 0;
}
 
Last edited by a moderator:
  • #14
pbuk said:
Thanks for the suggestion, although I currently use Repl.it.
Great one!
 
  • #15
I stick to old-fashioned C. There is already a string function in the library called strtok:
Code:
char *strtok(char *restrict s1, const char *restrict delimiters);
A sequence of calls to strtok() breaks the string pointed to by s1 into a sequence of tokens, each of which is delimited by a byte from the string pointed to by delimiters. The first call in the sequence has s1 as its first argument, and is followed by calls with a null pointer as their first argument. The separator string pointed to by delimiters may be different from call to call.

Read more in https://en.wikibooks.org/wiki/C_Programming/String_manipulation
 
  • Like
Likes   Reactions: YoungPhysicist

Similar threads

  • · Replies 1 ·
Replies
1
Views
2K
Replies
12
Views
3K
  • · Replies 8 ·
Replies
8
Views
2K
  • · Replies 13 ·
Replies
13
Views
3K
  • · Replies 89 ·
3
Replies
89
Views
6K
Replies
4
Views
2K
  • · Replies 30 ·
2
Replies
30
Views
5K
Replies
6
Views
2K
Replies
89
Views
7K
  • · Replies 5 ·
Replies
5
Views
3K