0

So, I made a program that lets the user type in his full name, showing its initials. (using a char array, so the names will be delimited by a space).

This is my code:

#include <iostream>
#include <cstring>
using namespace std;

int main()
{
   char name[100];
   cout << "Name: "; cin >> name;
   cout << name[0];
   for (int i = 1; i<=strlen(name); i++)
      if (name[i] == 32)
         cout << name[i+1];
   return 0;
}

It will find the space between the names and the things that will be shown are the first element from the array and the next element after the space.

For example, if I type in: John Doe, the output will be: J D.

My problem is, it only shows J. Why?

6
  • @FrancoisAndrieux Not really. Commented Jan 25, 2018 at 21:10
  • std::cin only reads 1 word at a time. name will contain "John". The problem is the spaces in your input, thus the duplicate. Commented Jan 25, 2018 at 21:11
  • 1
    also your loop is wrong. should be i < strlen Commented Jan 25, 2018 at 21:13
  • use getline instead of cin >> cplusplus.com/reference/string/string/getline Commented Jan 25, 2018 at 21:15
  • 1
    and dont use magic numbers like 32 - use ' ' Commented Jan 25, 2018 at 21:16

2 Answers 2

2

Because std::cin >> name will only read characters until whitespace is encountered.

Try using std::getline to read the entire line (read until line break).

std::string s;
std::getline(std::cin, s);
std::cout << s[0] << " " << s[s.find(' ') + 1] << std::endl;

Note: above has no bounds check, e.g., if no space is found.

Sign up to request clarification or add additional context in comments.

4 Comments

So, using getline(cin, name) would do it?
@MateașMario Yes, except that std::getline expects to read into a std::string variable. Which makes sense. Use std::string.
@Snps Though there really should be bounds checking, in this case it'll work out (in the sense that the behavior is at least well defined). std::string::find returns std::string::npos if it fails to find something. Due to how unsigned integer types work, npos + 1 is well defined and produces 0. So in this case, if there are no spaces, it would print the first letter twice (assuming the string isn't empty).
When searching searching for a single character, prefer s.find(' ').
1

std::cin >> name reads a single word from the input stream. It never read the second word.

You could use std::getline()[1] to read a whole line of input, or you could read single words in a loop using std::cin >> word.

Either way, I would strongly recommend using std::string instead of C strings. strlen(name) will have to count the string length on each iterator of the loop.

You're also potentially reading beyond the end of the string with i <= strlen(name) and reading name[i+1].

Something like this should work (untested):

#include <iostream>
#include <string>

int main() {
   std::string name;
   std::getline(std::cin, name);

   for (std::size_t i = 0; i < name.size(); i++) {
      if (i == 0 || name[i - 1] == ' ') {
        std::cout << name[i];
      }
   }
}

3 Comments

Wasn't it < name.size() or <= name.size()-1?
It would be if you were reading just name[i]. But since you're also reading name[i+1] you need to stop your loop one iteration earlier.
Changed the answer to read name[i - 1] (if i != 0) and name[i], so then the loop should indeed continue until i < name.size()

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.