【问题标题】:tolower() in c++ without using STLc++ 中的 tolower() 不使用 STL
【发布时间】:2019-08-10 12:14:15
【问题描述】:

我想在不使用 STL 的情况下用 C++ 为 tolower() 编写一个函数。 当我输入像“Hello”这样的小输入时,我的代码得到了正确的输出,但是当我输入带有标点符号的大段落时,我得到了错误。任何人都可以帮助解决并帮助理解我为什么会出错吗?

我的代码:

#include <iostream>

using namespace std;

int main()
{ 
std::string str[] = ""Mymommaalwayssaid,\"Lifewaslikeaboxofchocolates.Youneverknowwhatyou'regonnaget.""

     int n ,i;
        string UP[str.size()];

        for(int i=0;i<=str.size();i++)
        {
            if(int(str[i])<=90 && int(str[i])>=65)
            { n = int(str[i]);
                n= n+32;
                UP[i]=char(n);
            }

            else 
                UP[i] = str[i];


        }

        cout<<UP<<endl;


    return 0;
}

【问题讨论】:

  • 创建std::string数组的语法不对。你的代码编译了吗?
  • string UP[str.size()]; 不应该工作 A. 因为str 是一个不能调用成员函数的数组和 B. 因为 C++ 中数组的大小必须在编译时知道-时间。
  • string UP[str.size()]; -- 这不是有效的 C++。另外——我想为 tolower() 编写一个函数——tolower 函数所做的远不止假设所使用的语言是英语并且整理序列是 ASCII,因为你的尝试是做。
  • 首先,不要使用幻数。 str[i] &lt;= ‘z’str[i] &lt;= 90 清晰得多。另外,请注意,并非所有世界都是 ASCII。在某些字符编码中,字母之间混有非字母。标准库提供了tolower,这样您就不必自己动手了。
  • 您想要多便携?当然,在大多数字符集中,小写字母和大写字母都是连续的范围——但情况并非总是...除了与数字 (90, 65) 进行比较之外,您可以与字符文字('Z''A')进行比较,它们共享相同的值,但使用起来更安全。同样:n += 'a' - 'A' 得到适当的差异。

标签: c++ stl c++14


【解决方案1】:

嗯,这个问题有几个令人困惑的地方。首先,问题要求提供tolower()的例子,但代码似乎想创建一个名为UP的字符串。

我继续创建了一个 string_to_lower() 函数。我不想使用与 tolower(char* str) 相同的名称,尽管这样会起作用。

#include <iostream>
#include <string>

std::string string_to_lower(std::string str) {
  const uint diff = 'a' - 'A';  // create a constant from the ascii chars

  std::string lower; // return string.  Could be done with an inline reference.
  lower.reserve(str.length());

  for (int i = 0; i < str.size(); i++) { // Use a ternary to set each char
    lower += (str[i] >= 'A' && str[i] <= 'Z') ? str[i] + diff : str[i];
  }

  return lower;
}

int main()
{
  std::string str = {"My momma always said, \"Life "
                     "is like a box of chocolates."
                     "You never know what you're gonna get.\""};

  std::string lower = string_to_lower(str);
  std::cout << lower << std::endl;
  return 0;
}

【讨论】:

  • 你已经使用了合格的 STL 对象 (std::...),所以你真的应该放弃 using namespace std...
  • @Aconcagua:同意。我已删除从 OP 的帖子中复制的 using namespace std;
  • lower.reserve(str.size() + 1) 会阻止结果中的内部重新分配。承认,我不确定 +1 偏移的必要性,std::string 已经可以适当地考虑终止空字符;也没有在cppreference 上找到任何相关信息...
  • @Aconcagua,我认为 C++ 标准库创建一个包含长度的字符串类以及我们过去在 C 中担心的所有其他内容是没有意义的,只是要求我们分配空终止字符的额外字节。我喜欢 C,但如果我必须用 C++ 编写,它至少应该抽象出担心空终止字符的额外字节的需要,我希望 :-)
【解决方案2】:

接近您的代码并纠正错误的定义是:

#include <iostream>
#include <string>

using namespace std;

int main()
{ 
  string str = "Mymommaalwayssaid,\"Lifewaslikeaboxofchocolates.Youneverknowwhatyou'regonnaget.";
  string lower = str;

  for (size_t i = 0; i < lower.length(); ++i) // can also use an iterator
  {
    char c = lower[i];

    if ((c >= 'A') && (c <= 'Z'))
      lower[i] += ('a' - 'A');
  }

  cout << lower <<endl;

  return 0;
}

编译和执行

pi@raspberrypi:/tmp $ g++ -pedantic -Wextra t.cc
pi@raspberrypi:/tmp $ ./a.out
mymommaalwayssaid,"lifewaslikeaboxofchocolates.youneverknowwhatyou'regonnaget.

但我不明白,因为你说 没有使用 STL 而你使用的是 std::string

不带std::stringiostream可以替换成stdio.h

#include <iostream>

using namespace std;

int main()
{ 
  const char str[] = "Mymommaalwayssaid,\"Lifewaslikeaboxofchocolates.Youneverknowwhatyou'regonnaget.";
  char lower[sizeof(str) + 1]; // if str content unknown so sizeof unknown => strlen and new/malloc etc

  for (size_t i = 0 ; i != sizeof(str); ++i)
  {
    char c = str[i];

    if ((c >= 'A') && (c <= 'Z'))
      c += ('a' - 'A');

    lower[i] = c;
  }

  lower[sizeof(str)] = 0;

  cout << lower <<endl;

  return 0;
}

编译和执行

pi@raspberrypi:/tmp $ g++ -pedantic -Wextra t.cc
pi@raspberrypi:/tmp $ ./a.out
mymommaalwayssaid,"lifewaslikeaboxofchocolates.youneverknowwhatyou'regonnaget.

【讨论】:

  • 说不使用 STL ,我的意思是说不使用 STL 中的 tolower() 函数的直接函数。
  • @gauravpendhari tolower 不是“STL”函数。 sqrtabsstrcat等也不是。它是一个库函数,但与STL无关。
猜你喜欢
  • 2011-07-12
  • 1970-01-01
  • 2011-02-21
  • 2022-11-22
  • 2021-11-06
  • 2011-03-25
  • 2011-09-27
  • 1970-01-01
  • 2011-08-05
相关资源
最近更新 更多