【问题标题】:Reversing an array in C在C中反转数组
【发布时间】:2012-09-24 00:42:05
【问题描述】:

我是 cpp 新手,对数组有疑问。我在下面的代码应该创建一个反向版本的 str 并将其存储在 newStr 中。但是, newStr 总是空的。有人可以向我解释为什么会发生这种情况,即使我从 str 中分配了一个值?

void reverse (char* str) {
    char* newStr = (char*)malloc(sizeof(str));

    for (int i=0;i<sizeof(str)/sizeof(char);i++) {
       int index = sizeof(str)/sizeof(char)-1-i;
       newStr [i] = str [index];
    }
}

PS:我知道通过移动指针或使用 std::reverse 函数来反转数组效率更高,但我对上述代码为什么不起作用感兴趣。

【问题讨论】:

  • 很多骗子,但sizeof(char*) 不是数组的大小。你也应该使用std::string,或者,如果你别无选择,至少new/new[]delete/delete[]超过mallocfree
  • 不要在 C++ 中使用 malloc,使用 new。
  • unique_ptr无关
  • @Aesthete 是的,他在函数中分配内存并希望调用者知道释放返回的指针。你需要unique_ptr 来解决这种情况。
  • 您不需要unique_ptr 来解决这个问题,您需要更好的设计和良好的内存管理工作知识。在人们理解抽象的内容之前,不要向他们扔抽象。

标签: c arrays string


【解决方案1】:

如上所述,评论者指出sizeof(str) 不会告诉您字符串的长度。你应该使用size_t len = strlen(str);

void reverse (char* str) {
   size_t len = strlen(str);
   char* newStr = (char*)malloc(len + 1);

   for (int i=0; i<len;i++) {
      int index = len-1-i;
      newStr[i] = str[index];
   }
   newStr[len] = '\0'; // Add terminator to the new string.
}

不要忘记freemalloc 的任何记忆。我假设您的函数将返回您的新字符串?

编辑:在长度上 +1 为终结者腾出空间。

【讨论】:

  • 代码中的一个错误:newStr 没有 NULL 终止字符。
  • @Code-Guru 绝对正确。根据您的反馈更新了答案。
  • NULL 字符不会被自动复制(除非您不小心将它复制到了反转字符串的“开头”——这显然是一个逻辑错误)。您必须手动添加它才能正确执行。
  • 是的,一旦我保存了那个编辑,我就得出了同样的结论。
  • NULL 不应用作字符(参见stackoverflow.com/questions/2599207/…);使用 0 或 '\0'。
【解决方案2】:

sizeof 运算符(它不是函数!)在编译时进行评估。您正在向它传递一个指向您声称拥有字符串的内存区域的指针。但是,此字符串的长度在编译时并不固定。 sizeof(str)/sizeof(char) 将始终产生架构上指针的大小,可能是 8 或 4。

您想要的是使用strlen 来确定字符串的长度。

另外,一种更惯用的方法是使用std::string(如果您坚持自己反转字符串)

std::string reverse(std::string str) {
  for (std::string::size_type i = 0, j = str.size(); i+1 < j--; ++i) {
    char const swap = str[i];
    str[i] = str[j];
    str[j] = swap;
  }
  return str;
}

请注意,由于implicit conversion(请参阅重载(5)),您还可以使用纯C 风格的char 指针调用此函数。

【讨论】:

    【解决方案3】:

    这里有两个问题:

    1. sizeof 运算符不会为您提供字符串的长度。相反,它会在您使用的机器上为您提供char* 的大小。您可以改用strlen() 来获取

    2. c 字符串以 NULL 字符终止(这就是为什么 strlen() 可以返回正确的字符串长度)。您需要确保不会意外地将 NULL 字符从源字符串复制到目标字符串的开头。此外,您需要在目标字符串的末尾添加一个 NULL 字符,否则您会得到一些意外的输出。

    【讨论】:

      【解决方案4】:
      #include <bits/stdc++.h>
      
      using namespace std;
      
      vector<string> split_string(string);
      
      // Complete the reverseArray function below.
      vector<int> reverseArray(vector<int> a) {
          return {a.rbegin(), a.rend()};
      
      }
      
      int main()
      {
          ofstream fout(getenv("OUTPUT_PATH"));
      
          int arr_count;
          cin >> arr_count;
          cin.ignore(numeric_limits<streamsize>::max(), '\n');
      
          string arr_temp_temp;
          getline(cin, arr_temp_temp);
      
          vector<string> arr_temp = split_string(arr_temp_temp);
      
          vector<int> arr(arr_count);
      
          for (int i = 0; i < arr_count; i++) {
              int arr_item = stoi(arr_temp[i]);
      
              arr[i] = arr_item;
          }
      
          vector<int> res = reverseArray(arr);
      
          for (int i = 0; i < res.size(); i++) {
              fout << res[i];
      
              if (i != res.size() - 1) {
                  fout << " ";
              }
          }
      
          fout << "\n";
      
          fout.close();
      
          return 0;
      }
      
      vector<string> split_string(string input_string) {
          string::iterator new_end = unique(input_string.begin(), input_string.end(), [] (const char &x, const char &y) {
              return x == y and x == ' ';
          });
      
          input_string.erase(new_end, input_string.end());
      
          while (input_string[input_string.length() - 1] == ' ') {
              input_string.pop_back();
          }
      
          vector<string> splits;
          char delimiter = ' ';
      
          size_t i = 0;
          size_t pos = input_string.find(delimiter);
      
          while (pos != string::npos) {
              splits.push_back(input_string.substr(i, pos - i));
      
              i = pos + 1;
              pos = input_string.find(delimiter, i);
          }
      
          splits.push_back(input_string.substr(i, min(pos, input_string.length()) - i + 1));
      
          return splits;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-01-13
        • 1970-01-01
        • 2022-01-25
        • 2020-01-04
        • 2014-04-03
        • 2016-03-11
        • 2021-05-22
        • 1970-01-01
        相关资源
        最近更新 更多