无法正确终止 cstring

Cannot terminate cstring properly

我正在编写一个程序来查找最常输入的字符并将其输出,但如果它小于数组值,则垃圾字符会接管输出。我试过将 null 放在多个地方。放在最后,放在开头。不知为何一直给我垃圾字符╠

#include <iostream>
using namespace std;
void getMaxCharfrequ(char arr[], int size) {
    arr[0] = '[=10=]';
    char maxChar = ' ';
    int maxfreq = 0;
    
    for (int i = 0; i < size; i++)
    {
        int count = 1;
        for (int j = i + 1; j < size; j++)
            if (arr[i] == arr[j])
                count++;
        if (count > maxfreq)
            maxfreq = count;
    }

    for (int i = 0; i < size; i++)
    {
        int count = 1;
        for (int j = i + 1; j < size; j++)
            if (arr[i] == arr[j])
                count++;
        if (count == maxfreq)
            maxChar = arr[i];
    }

    cout << "The max character frequency is " << maxChar << " with frequency " << maxfreq;
    
}
#define size 15
void main() {
    char arr[size];
    arr[0] = '[=10=]';
    cout << "Please enter your string: ";
    cin >> arr;
    getMaxCharfrequ(arr, size);
}

您的代码存在多个问题。在讨论问题之前,建议 - 阅读 C++ 中的 std::string 并开始使用它而不是普通的 C 样式字符数组。我将在您的程序中使用 std::string 留给您。下面的答案指出了您现有代码中的问题。让我们一一讨论:

第一个:

main()函数中,你在做

arr[0] = '[=10=]';

在接受用户输入之前。它不是必需的,因为 cin 在读取 char *.

时在末尾添加了一个空终止符

第二:

您正在这样阅读用户输入 -

cin >> arr;

当用户输入超过 15 个字符时会发生什么?

至少使用cin.get (arr, size)。最好是使用 std::string,而不是普通的 char 数组。

第三:

您正在将 size 传递给 getMaxCharfrequ() 函数。 size 是将扩展为值 15 的宏。在 getMaxCharfrequ() 函数中,您正在迭代循环直到 size,因此无论输入用户给出什么,循环都会迭代 15 次,这是不正确的。这也是您面临的问题的根本原因。相反,循环应该迭代输入字符串中的字符数,例如,如果用户输入字符串 hello,循环应该只迭代 5 个字符。您应该将输入字符串的长度而不是 size 传递给 getMaxCharfrequ() 函数,或者您也可以迭代直到字符串的 [=38=] 个字符,在这种情况下,您不需要传递字符串的长度。

第四:

getMaxCharfrequ()函数中,第一条语句是

arr[0] = '[=10=]';

这意味着,您正在用空终止字符覆盖用户输入的第一个字符。你不需要这样做。

第五:

您不需要再次重复字符串来识别最大频率字符。相反,您可以在计算字符串中字符的频率时执行此操作。只记录count > maxfreq.

时的字符

第六:

main()的return类型应该是int

第七:

这个

using namespace std;

bad practice,避开它。

把这些加在一起,可以做到:

#include <iostream>
#include <cstring>

void getMaxCharfrequ(char arr[], size_t size) {
    char maxChar = ' ';
    int maxfreq = 0;

    for (size_t i = 0; i < size; i++) {
        int count = 1;
        for (size_t j = i + 1; j < size; j++) {
            if (arr[i] == arr[j]) {
                count++;
            }
        }
        if (count > maxfreq) {
            maxfreq = count;
            maxChar = arr[i];
        }
    }

    if (arr[0] == '[=14=]') {
        std::cout << "Input string is empty" << std::endl;
    } else {
        std::cout << "The max character frequency is " << maxChar << " with frequency " << maxfreq << std::endl;
    }
    
}

#define size 15

int main() {
    char arr[size];

    std::cout << "Please enter your string: ";
    std::cin.get(arr, size);
    getMaxCharfrequ(arr, strlen(arr));

    return 0;
}

输出:

# ./a.out
Please enter your string: helloworld
The max character frequency is l with frequency 3
# ./a.out
Please enter your string: 
Input string is empty
# ./a.out
Please enter your string: aaabbbbcc
The max character frequency is b with frequency 4
# ./a.out
Please enter your string: aaabbggggg
The max character frequency is g with frequency 5

答案已给出并被接受。我想另外介绍一个更现代的 C++ 解决方案,它适用于任何可迭代容器。

请看下面的例子:

#include <iostream>
#include <utility>
#include <unordered_map>
#include <queue>
#include <vector>
#include <iterator>
#include <type_traits>
#include <string>
#include <list>

// Some Alias names for later easier reading --------------------------------------------------------------------------
template <typename Container>
using ValueType = std::ranges::range_value_t<Container>;

template <typename Container>
using Pair = std::pair<ValueType<Container>, size_t>;

template <typename Container>
using Counter = std::unordered_map<ValueType<Container>, size_t>;

template <typename Container>
using UnderlyingContainer = std::vector<Pair<Container>>;

// Predicate Functor
template <class Container> struct LessForSecondOfPair {
    bool operator ()(const Pair<Container>& p1, const Pair<Container>& p2) { return p1.second < p2.second; }
};

template <typename Container>
using MaxHeap = std::priority_queue<Pair<Container>, UnderlyingContainer<Container>, LessForSecondOfPair<Container>>;

// Calculate max element ---------------------------------------------------------------------------------------------
template <class Container>
auto topFrequent(const Container& data) {

    if constexpr (std::ranges::range<Container>) {  // Evaluated at compile time

        // Count all occurences of data
        Counter<Container> counter{};
        for (const auto& d : data) counter[d]++;

        // Build a Max-Heap
        MaxHeap<Container> maxHeap(counter.begin(), counter.end());

        // Return most frequent element
        return maxHeap.top().first;
    }
    else
        return data;
}

// Test
int main() {
    std::vector testVector{ 1,2,2,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,6,7 };
    std::cout << "Most frequent is: " << topFrequent(testVector) << "\n";

    std::list testList{ 1,2,2,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,6,7 };
    std::cout << "Most frequent is: " << topFrequent(testList) << "\n";

    double cStyleArray[] = { 1.1, 2.2, 2.2, 3.3, 3.3, 3.3 };
    std::cout << "Most frequent is: " << topFrequent(cStyleArray) << "\n";

    std::string s{ "abbcccddddeeeeeffffffggggggg" };
    std::cout << "Most frequent is: " << topFrequent(s) << "\n";

    double value = 12.34;
    std::cout << "Most frequent is: " << topFrequent(value) << "\n";

    return 0;
}

基本上无所谓,用数组还是std::string。该算法适用于任何类型的可迭代容器。

已经给出了很好的答案,但这里有一个更简单的答案。

#include <iostream>
#include <map>

int main(void) {
  std::map<char, int> map;
  std::string input = "aaabbcddaaaddkladfaa";
  int max_freq = 0;
  char max_char;

  for (auto ch : input) {
    map[ch]++;
    if (map[ch] > max_freq) {
      max_freq = map[ch];
      max_char = ch;
    }
  }

  std::cout << "Character '" << max_char
            << "' is most frequent, which is appeared " << max_freq << " times";

  return 0;
}