2016-02-13 71 views
6

我正在使用C++ 14并试图为每个循环创建一个打印出数组的每个字符串。我得到的错误:对于每个循环只需要第一个字符串的数组C++

user.cpp:12:34: error: invalid initialization of reference of type ‘std::string& {aka std::basic_string&}’ from expression of type ‘char’

for(std::string &str : *(u->favs)){

当我改变的std :: string自动在foreach循环中,它的工作原理,但STR为的收藏数组中的第一个字符串的单个字符。 我的代码如下:

user.h

class User{ 
    private: 

    public: 
     User(){ 
      favs = new std::string[5]{std::string("Hello"), std::string("how"), std::string("are"), std::string("you"), std::string("?")}; 
     } 

     ~User(){ 
      delete[] favs; 
     } 

     std::string lName; 
     std::string fName; 
     int age; 
     std::string *favs; 
}; 

user.cpp

#include <iostream> 
#include "user.h" 

void create(User *u){ 
    std::cout << "Please enter first name: "; 
    std::cin >> u->fName; 
    std::cout << "Please enter last name: "; 
    std::cin >> u->lName; 
    std::cout << "Please enter age: "; 
    std::cin >> u->age; 

    for(std::string &str : *(u->favs)){ 
     std::cout << str << std::endl; 
    } 

    std::cout << "\n"; 
} 

的main.cpp

#include <iostream> 
#include <string> 
#include "user.h"  

int main(){ 
    std::string command; 
    User user; 
    std::cout << "bp1: " << user.favs->size() << std::endl; 
    while(true){ 
     std::cout << "Please enter a command (Create, Update, View, Favorites, or Quit): "; 
     std::cin >> command; 
     if(command == "Create"){ 
      create(&user); 
     } else if(command == "Update"){ 
      update(&user); 
     } else if(command == "View"){ 
      view(&user); 
     } else if(command == "Favorites"){ 
      //favorites(&user); 
     } else if(command == "Quit"){ 
      break; 
     } else std::cout << "Please input a valid command.\n"; 
    } 
} 
+0

此外,user.favs的大小是数组中第一个字符串的大小,而不是数组中元素的数量 – a0935

回答

5

当你提领u->favs您将得到一个std::string&,然后基于范围的值开始迭代该string一次一个字符。这就是为什么当你auto你看到第一个字符串中的单个字符,并且当你试图将该字符绑定到string&时,你会得到一个编译错误。

由于无法知道指针指向多少个对象,因此无法获得基于范围的指针类型。如果您对代码进行了以下更改以将favs声明为静态大小的数组,则您的代码将起作用。

类定义更改为

using namespace std::string_literals; // allows use of operator""s (user defined literal) 
class User 
{ 
public: 
    User() 
    : favs{{"Hello"s, "how"s, "are"s, "you"s, "?"s}} // use operator""s 
    {} 

    // no need for a destructor definition 

    std::string lName; 
    std::string fName; 
    int age; 
    std::array<std::string, 5> favs; // statically sized array 
}; 

如果你需要一个动态大小的数组,然后使用std::vector<std::string>,而是和你的循环仍然可以工作。

+0

如果您想快速尝试使用矢量而不是基本数组,则@Praetorian的答案也可以通过向量的初始化列表,如果你直接换出'std :: string favs [5];'从'std :: vector favs';' – MtRoad

+0

''回答很正确,但我毫不犹豫地提出了一个促进C数组的答案,尤其是结合其他现代C++结构。 – ildjarn

+0

@ildjarn但与标准的C数组相比,'std :: array'的键入更加丰富:) – Praetorian

1

如果你想使用基于范围的循环,有2种方式:

1)std::string favs[n];

基于范围的循环的工作原理对阵列具有恒定大小

2)std::vector<std::string> favs

基于范围的循环的工作原理对已实施的对象开始/结束,和STL容器做到这一点。

class User{ 
    public: 
     User() : favs {"Hello", "how", "are", "you", "?"} { } 
     std::vector<std::string> favs; 
}; 

for(std::string& str : u->favs) 
    std::cout << str << std::endl; 

3)如果favs将是你的类...的主阵列和你想尝试的开始/结束的想法,这里是你会怎么做:

class User 
{ 
public: 
    std::string *favs; 
    int favs_size; 
    User() 
    { 
     favs_size = 5; 
     favs = new string[favs_size]; 
    } 
    ~User() { delete[] favs; } 

public: 
    std::string* begin() { return favs; } 
    std::string* end() { return favs+favs_size ; } 
}; 

User u; 
for(std::string &str : u) 
    std::cout << str << std::endl; 
相关问题