Home > Software engineering >  Error: buffer overrun while writing to array. How to cout the word which starts with certain letter
Error: buffer overrun while writing to array. How to cout the word which starts with certain letter

Time:10-21

I need to cout random word which starts with 'k; I have decided to count the amount of words and amount of words(beginning with 'k'); After that i made it into an array, so i could have an array full of the number of words which start with 'k'; But here is the problem, compiler doesn't let the code to go on and i can't understand what's the problem; I'm a beginner, so go easy on me; Here is the code:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <stdlib.h>
#include <ctime>
#include <cmath>
#include <cstring>
#include <clocale>
#include <Windows.h>
using namespace std;

int main()
{
    srand(time(NULL));
    char str1[150] = "knight kevin once said that maybe that kind of process is necessary to him pushing him on and on and it is very painful he knows.";
    cout << str1 << endl;
    int sz = 1;
    int s = 1;
    int sz_count = 1;
    int s_count = 0;
    int x = 1;
    int* amounts_of_words = new int[s];
    int* array_of_K = new int[sz];

    if (str1[0] == 'k' || str1[0] == 'K') {
        array_of_K[0] = 1;
        sz  ;
    }

    for (int i = 0; str1[i] != '\0'; i  ) {

        if (str1[i] == ' ' || str1[i] == '.' || str1[i] == '?' || str1[i] == '!') {
            amounts_of_words[s_count] = x;
            s  ;
            x  ;
            if (str1[i   1] == 'k') {
                array_of_K[sz_count] = amounts_of_words[s_count]   1;
                sz  ;
                sz_count  ;
            }
            s_count  ;
        }

        if (str1[i   1] == '\0') {
            sz--;
            s--;
        }
    }

    for (int f = 0; f < sz; f  ) {
        cout << array_of_K[f] << " ";
    }

    char* token;
    int randomN = rand() % 4;
    cout << randomN;
    cout << array_of_K[randomN];

    for (int i = 1; i <= s; i  ) {
        if (i == 1 && i == array_of_K[randomN]) {
            token = strtok(str1, " ");
            cout << token;
            break;
        }
        else if (i == 0) {
            token = strtok(str1, " ");
        }
        else {
            token = strtok(NULL, " ");
            if (i == array_of_K[randomN]) {
                cout << token;
                break;
            }
        }
    }

    delete[] array_of_K;
    delete[] amounts_of_words;
}

CodePudding user response:

First you can make your program a lot smaller(in size) and better(general) using std::map Below is the complete working example that shows how can achieve this:

#include <iostream>
#include <map>
#include <sstream>
int main() {
    std::string inputString = "knight kevin once said that maybe that kind of process is necessary to him pushing him on and on and it is very painful he knows.";
    std::istringstream s(inputString);
    //this map maps the char to their respective count
    std::map<char, int> charCount;
    std::string word;
    int count = 0;//this count the total number of words
    while(s >> word)
    {
        charCount[word[0]]  ;
        count  ;
    }
    
    
    std::cout<<"Total number of words are:"<<count<<" out of which"<<std::endl;
    for(std::pair<char, int> pairElement: charCount)
    {
        std::cout<<pairElement.second<<" starts with: "<<pairElement.first<<std::endl;
      
    }
    return 0;
}

Check out the program here.

The output of the above program is as follows:

Total number of words are:26 out of which
2 starts with: a
3 starts with: h
3 starts with: i
4 starts with: k
1 starts with: m
1 starts with: n
4 starts with: o
3 starts with: p
1 starts with: s
3 starts with: t
1 starts with: v

CodePudding user response:

When people say "idiomatic C " they mean something like this:

#include <iostream>
#include <string>
#include <random>
#include <set>

// dont use : using namespace std;

// make functions!
// don't use arrays they need manual memory management with new[]/delete[]
// this is no longer the recommended way in C  
// for dynamically allocatable arrays just use std::vector!

// this is just one way of splitting a string into words.
std::vector<std::string> get_words_starting_with_letter(const std::string& string, const char letter)
{
    static const std::set<char> delimiters{ ' ', '.' }; // all those chars that are not part of a word.
    std::vector<std::string> words;
    char upper_case_letter = static_cast<char>(::toupper(letter));

    auto word_begin = string.begin();
    // use an iterator to move over the string.
    for (auto it = string.begin(); it != string.end();   it)
    {
        // if a non-word character is found then push back 
        // a new string beginning at word_begin adn ending at it 
        if (delimiters.find(*it) != delimiters.end())
        {
            if ((*word_begin == letter) || (*word_begin == upper_case_letter))
            {
                words.emplace_back(word_begin, it);
            }
            
            // skip delimiter
            if (it 1 != string.end())
            {
                  it;
                word_begin = it;
            }
        }
    }

    return words;
}

int main()
{
    // srand is from "C", C   has this:
    std::random_device rd;  // better seed then stime
    std::default_random_engine random{ rd() };

    // if something is a string then use a std::string, make it const because 
    // it is not supposed to be changed
    const std::string str1{ "knight kevin once said that maybe that kind of process is necessary to him pushing him on and on and it is very painful he knows." };

    // really do make functions to make your code readable
    auto words_with_k = get_words_starting_with_letter(str1, 'k');

    // indices in containers use std::size_t
    std::uniform_int_distribution<std::size_t> distribution(0, words_with_k.size()-1); // distributions are inclusive, so take care to substract 1 from size

    // now just output some random words
    for (std::size_t n = 0; n < 10;   n)
    {
        auto index = distribution(random);
        std::cout << "random word beginning with a 'k' #" << n   1 << " is : " << words_with_k.at(index) << "\n";
    }

    return 0;
}
  • Related