Как узнать размер массива символов? - PullRequest
0 голосов
/ 06 августа 2020

Как мне go узнать длину массива символов в C ++? Я уже пробовал два метода, но оба они привели к неправильному количеству символов в массиве. До сих пор я использовал strlen и оператор sizeof, но безрезультатно.

void countOccurences(char *str, string word)
{
    char *p;
    string t = "true";
    string f = "false";

    vector<string> a;

    p = strtok(str, " ");
    while (p != NULL)
    {
        a.push_back(p);
        p = strtok(NULL, " ");
    }

    int c = 0;
    for (int i = 0; i < a.size(); i++)
    {
        if (word == a[i])
        {
            c++;
        }
    }

    int length = sizeof(str); //This is where I'm having the problem
    string result;
    cout << length << "\n";

    if (length % 2 != 0)
    {
        if (c % 2 == 0)
        {
            result = "False";
        }
        else
        {
            result = "True";
        }
    }
    else
    {
        if (c % 2 == 0)
        {
            result = "True";
        }
        else
        {
            result = "False";
        }
    }

    if (strlen(str) != 0)
    {
        cout << result;
    }
}

int boolean()
{
    char str[1000];
    cin.getline(str, sizeof(str));
    string word = "not";
    countOccurences(str, word);
    return 0;
}

Ответы [ 3 ]

5 голосов
/ 06 августа 2020

sizeof(str) неверно. Он дает вам размер указателя (str - указатель), который является фиксированным числом, обычно 4 или 8 в зависимости от вашей платформы.

std::strlen(str) правильно, но strtok вставляет кучу \0 в ваш массив перед тем, как вы попытаетесь получить размер. strlen остановится на первом \0 и выдаст количество предшествующих ему символов.

Вызов strlen перед strtok и сохранение его возвращаемого значения в переменной.

0 голосов
/ 06 августа 2020

Здесь вы можете найти современное решение на C ++:

#include <iostream>
#include <string_view>
#include <string>
#include <type_traits>

template<typename String>
inline std::size_t StrLength(String&& str)
{
    using PureString = std::remove_reference_t<std::remove_const_t<String>>;
    if constexpr(std::is_same_v<char, PureString>){
        return 1;
    }
    else 
    if constexpr(std::is_same_v<char*, PureString>){
        return strlen(str);
    }
    else{
        return str.length();
    }
}

template<
    typename String,
    typename Lambda,
    typename Delim = char
>
void ForEachWord(String&& str, Lambda&& lambda, Delim&& delim = ' ')
{
    using PureStr = std::remove_reference_t<std::remove_reference_t<String>>;
    using View = std::basic_string_view<typename PureStr::value_type>;

    auto start = 0;
    auto view = View(str);

    while(true)
    {
        auto wordEndPos = view.find_first_of(delim, start);
        auto word =  view.substr(start, wordEndPos-start);

        if (word.length() > 0){
            lambda(word);
        }
        
        if (wordEndPos == PureStr::npos)
        {
            break;
        }
        start = wordEndPos + StrLength(delim);
    }
}

int main() {
   std::string text = "This is not a good sentence.";
   auto cnt = 0;
   ForEachWord(
       text, 
       [&](auto word)
       {
          //some code for every word... like counting or printing
          if (word == "not" ){
             ++cnt;
          }
       },
       ' '
   );
   std::cout << cnt << "\n";
}
0 голосов
/ 06 августа 2020

«Конец строки» - это проверка символа '\ 0' для этого символа, чтобы остановить поиск.

...