使用基于范围的For循环和Char指针字符串 我是C++ 11的新手,坦白说,我一年多没有使用C++,所以我开始有点生疏了。我在做一些以前大学课文中的练习,在尝试迭代char指针字符串(例如:char*c=“a string”)时遇到了一个问题。我在谷歌上找不到任何有用的东西。我已经习惯了Java,foreach循环可以在任何集合上进行迭代。我知道指针是如何工作的,但是我从C++中的长假让我对使用它们的语法一无所知。有人能告诉我为什么下面的代码(特别是convert()函数)在编译时会导致错误,其中说“begin”和“end”没有在这个范围内声明吗

使用基于范围的For循环和Char指针字符串 我是C++ 11的新手,坦白说,我一年多没有使用C++,所以我开始有点生疏了。我在做一些以前大学课文中的练习,在尝试迭代char指针字符串(例如:char*c=“a string”)时遇到了一个问题。我在谷歌上找不到任何有用的东西。我已经习惯了Java,foreach循环可以在任何集合上进行迭代。我知道指针是如何工作的,但是我从C++中的长假让我对使用它们的语法一无所知。有人能告诉我为什么下面的代码(特别是convert()函数)在编译时会导致错误,其中说“begin”和“end”没有在这个范围内声明吗,c++,pointers,c++11,C++,Pointers,C++11,Ex12_01_RomanType.h #ifndef EX12_01_ROMANTYPE_H #define EX12_01_ROMANTYPE_H class RomanType { public: RomanType(); RomanType(char * n); virtual ~RomanType(); char * toString(); int getValue(); private: char * numeral;

Ex12_01_RomanType.h

#ifndef EX12_01_ROMANTYPE_H
#define EX12_01_ROMANTYPE_H

class RomanType {
  public:
    RomanType();
    RomanType(char * n);
    virtual ~RomanType();

    char * toString();
    int getValue();
  private:
    char * numeral;
    int decimal;

    void convert();
};

#endif // EX12_01_ROMANTYPE_H
Ex12_01_RomanType.cpp

#include "Ex12_01_RomanType.h"

RomanType::RomanType() {
  // Default Constructor
  numeral = "I";
  decimal = 0;
  convert();
}

RomanType::RomanType(char * n) {
  // Specific Constructor
  numeral = n;
  decimal = 0;
  convert();
}

RomanType::~RomanType() {
  delete numeral;
}

char * RomanType::toString() {
  return numeral;
}

int RomanType::getValue() {
  return decimal;
}

void RomanType::convert() {
  /* Iterates over each character in the numeral string and adds that
     character's value to the decimal value. This method should only
     be called once during the constructor. */
  for(char c : numeral) {
    if(c == 'M') decimal += 1000;
    else if(c == 'D') decimal += 500;
    else if(c == 'C') decimal += 100;
    else if(c == 'L') decimal += 50;
    else if(c == 'X') decimal += 10;
    else if(c == 'V') decimal += 5;
    else if(c == 'I') decimal += 1;
    else decimal += 0;
  }
}

对不起,如果这个问题对某些人来说是基本的。Java把我惯坏了。

基于范围的-
for
适用于数组、具有成员
begin
end
的类,或者当存在适当的非成员
begin
end

如果不遍历
c
样式的字符串(指向
NUL
-终止的
char
数组的指针),就无法找到该字符串的“end”

最简单的修复方法是只使用
std::string
,它将与基于范围的-
for
一起使用

(编辑:现在我想起来了,即使直接使用
char
数组,也要小心:

const char myString[] = "Hello";
for ( auto c : myString ) //...

因为您将处理数组的所有6成员,包括
NUL
-终止符。虽然您在这里不能这样做。)

我认为解决问题的最简单方法是使用其范围构造函数
std::string(char*begin,char*end)创建一个字符串
并为其上的每个循环调用一个。

字符没有开始或结束,因此基于范围的for循环对字符类型不起作用,请使用较新的
std::string

您已经有了答案。 如果您想用c++11的方式做更多的工作,请尝试用std::string替换所有char*。今天的C++是如果你可以不用新的/删除的东西来做你的东西,请先试试。 <如果你在罗马数字中练习这个链接是用C++ C++逐级解释十进制到罗马。

基于范围的for循环适用于容器或数组类型。这里的
numeric
char*
类型。如果将
numeric
正确地实现为
std::string
,这将起作用。现代C++风格避免了手动内存管理和尽可能使用原始指针。CHAR *没有定义的开始或结束迭代器。请参阅此链接了解详细信息。您不能直接使用基于范围的for循环迭代
char*
,因为编译器不清楚字符串的长度(它不是容器)。不过,您可以编写一个适配器,允许对以null结尾的字符串进行迭代。当默认构造函数中的默认构造的
numeric
指向字符串文本时,此类具有未定义的行为,这将在析构函数中删除。我想我只是想了解在C时代如何将字符指针用作字符串。哦,好吧……使用std::string当然是最好的解决方案,但也值得一提的是
numeric=“I”
赋值的问题。它不复制文本的内容,只复制其地址。此外,它还将文本的地址分配给一个非常量
char*
@DarinBeaudreau现在,如果我发现自己要使用普通的C指针,我会深吸一口气并重新考虑。@DarinBeaudreau:C风格的字符串指针与库函数、手写循环一起使用,以及对底层阵列的仔细管理。在C++中,类如“代码> STD::String 呈现友好的界面并隐藏了细节。我之所以使用这个而不是字符串,部分原因是我想使用而不是因为我不特别喜欢“CUT”样式…我喜欢用函数来做这类事情。