cout operator << 不适用于 vector<char>

cout operator << doesn't work for vector<char>

为什么这个矢量图打印不出来?

 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;
     }   
 }

我收到一个错误:

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

当您尝试显示时,您的 'str' 变量中没有任何内容。您也不会将向量初始化为任何变量,以便函数无论如何都可以读取。

这里有 3 个大问题。

  • 您是按值而不是按引用传递矢量。因此,对函数中的向量所做的任何更改都将保留在初始化为该函数调用堆栈的一部分的向量中。它将在您 return 时被删除。所以将签名更改为 str_read(std::vector<char>& str).
  • 您正在逐个字符地完成 stdin 捕获。 AFAIK scanf 虽然会读取换行符,但会将其留在缓冲区中而不会将其附加到您的字符串中。从它的外观来看,您要做的就是从 stdin 中读取一个字符串,将其存储在一个字符数组中,然后打印出该字符数组。不要过度设计东西。只需使用 std::cin 并将其存储在字符串中,例如
std::string captured_string;
std::getline(std::cin, captured_string);

然后您可以std:cout << captured_string << "\n";直接

  • 如果你坚持将字符存储在一个向量中,我不明白你为什么需要这样做,你可以这样做 std::vector<uint8_t> char_array(captured_string.begin(), captured_string.end())。但是,std::cout << char_array << "\n" 仍然不起作用。这有两个原因,第一个是 std::vector<T, allocator> 没有 std::ostream<< 的重载。第二个是当你将字符串转换为字符数组时,它们的意思并不相同。

我认为您误解了 class 中关于将字符串存储为字符数组的内容。它们确实存储为数组,但数组类型和字符串类型根本不同,并不等价。

stdin 捕获字符串无论如何都会将其存储在 char*std::string 中,如我上面所示。您可以直接使用它,而不必将字符串转换为字符数组。

从本质上讲,您的程序会衰减到这个

#include <iostream>
#include <string>

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

编辑

我刚刚意识到您的 objective 可能是逐字符打印字符串。在这种情况下,您不需要将其转换为数组。有多种方法可以做到这一点,但最容易混淆并且可能是最简单的方法是使用基于范围的 for 循环。

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;
}

您收到错误是因为没有为 std::vector 定义标准 operator<<。如果你想要那个,你必须自己实现它。

即便如此,str_read() 接受了一个 std::vector by value,所以它收到了一个 copy调用者的 vector,因此它所做的任何修改都将对该副本进行修改,因此在 str_read() 退出时丢失。这意味着 main() 中的 vector 永远不会被填充。

试试这个:

#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;
}

话虽这么说,为什么不直接使用 std::string 而不是 std::vector<char>?有一个为 std::string 定义的标准 operator<<,以及一个标准 std::getline() 函数,用于将字符读入 std::string 直到 '\n':

#include <iostream>
#include <string>

int main() {
    std::string str;
    std::getline(cin, str);
    std::cout << str << std::endl;
}

先说明一下

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

coutcharacter-oriented 流输出,不接受 vector<char> 类型的输出格式。

Vector 是指定类型的元素数组。如果要使用vector,可以先在里面存值:

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

然后将数组的一个元素打印到标准输出cout

cout << str[0] <<endl;

第二个问题是你的函数str_read被定义为void,它没有值,所以它也不能位于cout的标准输出中。

您似乎想将字符作为输入输入到 vector 中并打印出来。如果将函数定位为void,则需要更改str by reference

的值

下一个问题,我看到你的while循环break时间不对,没有和if结合。您不应在 if 语句后添加分号。

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

最后,如果你选择通过引用来改变str的值,你需要在函数中实现这个,就像上面提到的,当你输入一个ch的值时,你需要使用 str.push_back(ch) 来存储它。