-2

Why doesn't this vector print out?

 void str_read(std::vector<char> str);

 int main() {
     std::vector<char> str;
     str_read(str);
     std::cout << str << std::endl;

     return -1;
 }

 void str_read(std::vector<char> str) {
     while (1) {
         char ch;
         scanf("%c", &ch);
         if (ch == '\n');
         break;
     }   
 }

I get an error:

error: no type named 'type' in 'struct std::enable_if<false, void>'
Chris
  • 26,361
  • 5
  • 21
  • 42
  • 1
    When evaluating error messages from compiler, you want to address the FIRST error in the list of errors. Not the last. Any after the first have a high chance of being a result of the first error. – JohnFilleau Dec 17 '21 at 01:09
  • One other problem you'll have. `str_read` accepts the parameter by value, so whatever you do to the vector inside the function will be lost when the function ends. – Retired Ninja Dec 17 '21 at 01:14
  • 1
    `if(ch == '\n');` that semi-colon might cause you some problems. – Chris Dec 17 '21 at 01:16
  • The cause of your error message is that there is no `operator<<()` that accepts a `std::vector` as an argument. It would have helped if you had quoted the FIRST error message emitted by the compiler, rather than the LAST (of many). When the compiler continues after emitting an error message, it tends to be in some state of confusion - and that confusion tends to increase so error messages have less relationship to subsequent code. – Peter Dec 17 '21 at 03:36

4 Answers4

1

There are 3 BIG problems here.

  • You are passing the vector by value, not by reference. As a result, any changes made to the vector in the function will stay local to the vector initialised as a part of that function call stack. It will be deleted by the time you return. so change the signature to str_read(std::vector<char>& str).
  • You are going through the stdin capture character by character. AFAIK scanf although will read the new line character, will leave it in the buffer not appending it to your string. From the looks of it, all you are trying to do is read a string from stdin, store it in a char array, and print that char array out. Don't overengineer stuff. just use std::cin and store it in a string, to begin with, like
std::string captured_string;
std::getline(std::cin, captured_string);

You can then std:cout << captured_string << "\n"; directly

  • If you insist on storing characters in a vector, which I do not understand why would you need to, you can just do std::vector<uint8_t> char_array(captured_string.begin(), captured_string.end()). However, std::cout << char_array << "\n" will still not work. That is for 2 reasons, the first one being that std::vector<T, allocator> does not have an overload for << of std::ostream. The second is that the moment you convert your string to an array of characters, they do not mean the same thing.

I think you misunderstood what you were taught in class about strings being stored as arrays of characters. They are indeed stored as arrays, but an array type and a string type are fundamentally different and are not equivalent.

Capturing the string from stdin will anyway store it in a char* or a std::string as I have shown above. You can use that directly without having to convert a string to an array of characters.

In essence, your program decays to this

#include <iostream>
#include <string>

int main()
{
  std::string captured_string;
  std::getline(std::cin, captured_string);
  std::cout << captured_string << "\n";
  return EXIT_SUCCESS;
}

EDIT

I just realised that your objective may have been to print the string character by character. In that case, you don't need to convert it to an array. There are multiple ways of doing this, but the least confusing and probably the easiest way of doing this would be to use the range-based for loop.

int main()
{
  std::string captured_string;
  std::getline(std::cin, captured_string);
  for (auto& ch: captured_string) // containers in the standard library support range based for loops.
    std::cout << ch << "\n"; // print each character in the string on a new line
  return EXIT_SUCCESS;
}
sarthakt
  • 42
  • 1
  • 7
1

You get the error because there is no standard operator<< defined for std::vector. If you want that, you have to implement it yourself.

Even so, str_read() takes in a std::vector by value, so it receives a copy of the caller's vector, and thus any modifications it makes will be to that copy and thus lost when str_read() exits. That means the vector in main() is never populated.

Try this instead:

#include <iostream>
#include <vector>
#include <string>

std::ostream operator<<(std::ostream &out, const std::vector<char> &vec) {
    for(auto ch : vec) {
        out << ch;
    }
    return out;

    /* alternatively:
    return out.write(vec.data(), vec.size());
    */ 
}

void str_read(std::vector<char> &str) {
    char ch;
    while (cin.get(ch) && ch != '\n') {
        str.push_back(ch);
    }   
}

int main() {
    std::vector<char> str;
    str_read(str);
    std::cout << str << std::endl;
}

That being said, why not just use std::string instead of std::vector<char>? There is a standard operator<< defined for std::string, and a standard std::getline() function for reading characters into std::string until '\n':

#include <iostream>
#include <string>

int main() {
    std::string str;
    std::getline(cin, str);
    std::cout << str << std::endl;
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
0

First, explain

error: no type named 'type' in 'struct std::enable_if<false, void>'

cout is character-oriented stream output and does not accept output formats of the vector<char> type.

Vector is an array of elements of the specified type. If you want to use a vector, you can store values in it first:

vector<char> str;
str.push_back('H');

An element of the array is then printed to standard output cout

cout << str[0] <<endl;

The second problem is that your function str_read is defined as void, which has no value, so it cannot be located in cout's standard output either.

It looks like you want to put the characters as input into a vector and print them out. If you position the function as void, you will need to change the value of str by reference

Next question, I see that your while loop break is mistimed and does not combine with if. You should not add a semicolon after an if statement.

if (ch == '\n')break;

Finally, if you choose to change the value of str by reference, you need to implement this in the function, as mentioned above, when you type a value of ch, you need to use str.push_back(ch) to store it.

-1

Your 'str' variable doesn't have anything in it when you try to display it. You also don't initialize your vector to any variables for the function to read anyways.

  • If the program compiled then there wouldn't be any output at runtime because of the empty vector, but this is a question about a compile error not any possible runtime behavior. – Retired Ninja Dec 17 '21 at 01:20