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
Join the discussion
Registration is free. Ask a follow-up in this thread, or start your own.
14 replies · 6K views
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:
Physics 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,046
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;
}
 
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
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)
 
@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: 930
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:
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