【问题标题】:Beginner C++ Question初学者 C++ 问题
【发布时间】:2010-04-22 16:13:09
【问题描述】:

我已经按照这里的代码示例进行了操作

toupper c++ example

并在我自己的代码中实现如下

void CharString::MakeUpper()
{
char* str[strlen(m_pString)];
int i=0;
str[strlen(m_pString)]=m_pString;
char* c;
while (str[i])
  {
    c=str[i];
    putchar (toupper(c));
    i++;
  }
}

但这给了我以下编译器错误

CharString.cpp: In member function 'void CharString::MakeUpper()':
CharString.cpp:276: error: invalid conversion from 'char*' to 'int'
CharString.cpp:276: error:   initializing argument 1of 'int toupper(int)'
CharString.cpp: In member function 'void CharString::MakeLower()':

这是第 276 行

putchar (toupper(c));

我知道 toupper 正在寻找 int 作为参数并返回一个 int ,这是问题吗?如果是这样,该示例如何工作?

【问题讨论】:

  • 您能否进一步说明 m_pString 是什么?您是要大写单个字符数组(C 字符串)还是大写字符串数组?
  • 尝试将单个字符串中的每个字符大写
  • 您对charchar* 的使用从根本上混淆;你似乎是靠耳朵玩的。在继续之前,强烈建议认真阅读 C 语言。
  • 谢谢弗拉德,你假设我没有意识到这一点,我很清楚我的 C/C++ 知识几乎不存在,但是我不打算学习 C++ 只是移植一些旧的 C++供 JNI 使用。如果您有很好的阅读材料链接,请务必分享。谢谢

标签: c++ string compiler-construction char


【解决方案1】:

还有,

char* str[strlen(m_pString)];
int i=0;
str[strlen(m_pString)]=m_pString;

不是有效的 C++ - 数组必须使用编译时常量进行标注 - 这是 C99 的一项功能。而且我真的不认为代码会做你想做的事,即使它是合法的,因为你似乎正在访问数组末尾的一个。如果您发布完整的类定义会很方便。

【讨论】:

  • 数组必须使用编译时间常数来确定尺寸——很有趣。这是新的 C++ 规范吗?
  • @WhirlWind 一直都是这样。在 C++0x 中没有改变。
  • @WhirlWind:C++ 一直如此,C99 之前的 C 也是如此。在即将到来的 C++ 标准中没有动力改变这一点,因为std::vector<> 将处理可变长度并做更多事情。
  • 我一直认为有一些努力可以使 C++ 或多或少成为 C 的强类型超集...看到这里的分歧很有趣。
【解决方案2】:

我不认为你的代码做你想让它做的事情,事实上,如果它编译它会爆炸。



char* str[strlen(m_pString)]; // you've made an array of X C strings where 
                              // X is the length of your original string.
int i=0;


str[strlen(m_pString)]=m_pString; // You've attempted to assign the C string in your array
                                  // at location X to point at you m_pString.  X is the
                                  // same X as before and so is 1 past the end of the array
                                  // This is a buffer overrun.

我认为你真正想做的是将 m_pString 的内容复制到 str 中。你会这样做:



char * str = new char[strlen(m_pString)];
memcpy(str, m_pString); // I may have the operands reversed, see the docs.

不过,更简单的方法是停止使用 C 字符串并使用 C++ 字符串:



std::string str = m_pString;

还有更多问题,但这应该可以引导您朝着正确的方向前进。

【讨论】:

    【解决方案3】:

    您需要为 toupper() 提供一个 int(或 char)而不是 char *,这就是您声明 c 的方式。

    尝试:

    char c;
    

    还有,

    char* str[strlen(m_pString)];
    

    是一个指向字符的指针数组,而不仅仅是一个字符串。

    这一行:

    str[strlen(m_pString)]=m_pString;
    

    然后是对坏指针的赋值,因为没有分配。

    【讨论】:

      【解决方案4】:

      我将假设 m_pString 是 C 风格的字符串 (char *)。你做的比你需要做的更多。

      void CharString::MakeUpper()
      {
         char* str = m_pString; // Since you're not modifying the string, there's no need to make a local copy, just get a pointer to the existing string.
         while (*str) // You can use the string pointer as an iterator over the individual chars
         {
            putchar (toupper(*str)); // Dereference the pointer to get each char.
            str++;   // Move to the next char (you can merge this into the previous line if so desired, but there's no need.
         }
      }
      

      在您引用的示例中,它起作用的原因是变量的声明方式。

      int main ()
      {
        int i=0;
        char str[]="Test String.\n";  // This is a compile time string literal, so it's ok to initialize the array with it.  Also, it's an array of `char`s not `char*`s.
        char c;  // Note that this is also a `char`, not a `char *`
        while (str[i])
        {
          c=str[i];
          putchar (toupper(c));
          i++;
        }
        return 0;
      }
      

      由于使用 C 字符串的方式容易出错,因此最好的选择是 std::string:

      void CharString::MakeUpper()
      {
         string str(m_pString);
         transform(str.begin(), str.end(), ostream_iterator<char>(cout), &toupper);
      }
      

      【讨论】:

      • 其实大错特错——while (str)应该是while (*str)。直到指针指向NULL,您才前进,直到指向的字符为'\0'。请参阅上面的更正版本。更有理由远离 C 字符串并使用 std::string
      • 使用字符串引入了一大堆新的编译器错误:(我包括 但我得到字符串未定义错误
      • @donal: &lt;String.h&gt; 已弃用,您需要包含&lt;string&gt; 以获取std::string&lt;algorithm&gt; 以获取std::transform&lt;iterator&gt; 以获取ostream_iterator 和@987654336 @得到cout。这看起来很多,但您可以将它们放入项目的预编译头文件中。您还必须使用命名空间前缀 std:: - 例如std::stringstd::algorithmstd::ostream_iterator,或者在包含标题后在您的 cpp 文件中添加 using namespace std;。 (不要把它放在标题中,否则你可能会遇到麻烦。)
      【解决方案5】:

      没有从char *int 的内置转换,这就是发生错误的原因。由于您要尝试将字符大写,因此需要取消对指针的引用。

      putchar(toupper(*c));

      【讨论】:

      • @Matt,这只是冰山一角。他在任何他应该使用char的地方都使用char*
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-11
      • 2020-01-04
      • 2020-11-23
      • 2015-03-16
      • 2012-04-15
      • 1970-01-01
      相关资源
      最近更新 更多