C++ Add random characters into a string array - c++

So I want to create 1000 words with a length of 5 random characters. In my main I have word[1000] but when I try to run this code, it gives me an error saying "Expression:string subscript out of range". I'm not sure why it does that because I thought string arrays were 2 dimensional? If anyone could tell me why my code is wrong I'd appreciate it. Thanks.
void createText(string w[], int seed) {
char ch;
srand(seed);
for(int i = 0; i < 1000; i++) {
for(int j = 0; j < 5; j++) {
ch = ('A' + rand() % 26);
w[i][j] = ch;
}
}
for(int i = 0; i < 1000; i++) {
cout << w[i];
}
cout << endl;
}

I suppose that the array w does not have 1000 elements, also remember that here you will get a copy of string w[]. Better would be passing a pointer to w (string* w), then You will have very clearly what is wrong. remember also that cout writes the string out untill it reaches a '\0' character, this also might be the cause. Quick session with gdb will help:
gdb program
...
run
bt full
should pinpoint Your problem. if it's some kind of IDE, learn how to debug in it. Valgrind or some other memcheck like visual leak detector or luke stackwalker will also show you some tips about bad initialization or unmentioned memory leaks.

If an array is bidimensional, you can't print its values like w[i]. You must print always keeping in mind that the array is bidimensional, which means that the output must be done like cout << w[i][j];
In addition, you're passing an array of strings as an argument, and what you're doing is add characters to every single position, which means that you won't actually have nothing but 1000 characters inserted into that string (because you actually added "one-char" strings), so you'll only put 200 words with a length of 5 characters each one. Insert strings directly, and you'll get your 1000 words, but first find a way to build strings with random characters.
Something like:
for(conditions){
for(conditions){
build a word
}
array[x][y] = string
}
I guess it is similar to what you intended to do

Related

C++, return duplicate instances from an array to a string

Background to this: This is not homework, it's completely optional review for a basic c++ class. As I want to pass, I'm going through each example the best I can, This one I'm super stuck on, and have been for about three hours now.
Problem: Write a function to return a string composed of the most frequent lowercase letter found in each row of a 10 x 10 array of lowercase alphabetic chars in the range a through z.
If there is more than one most frequent character, use the one that come first alphabetically.
Use neither cin nor cout.
#include <iostream>
#include <string>
using namespace std;
string mostFrequent(char c[10][10]){
// this is the function I need to create
}
int main(){
char c[10][10] = {
'a','b','f','d','e','f','g','h','i','j',
'a','b','c','r','c','r','g','h','r','j',
'a','b','c','d','e','f','g','h','o','o',
'z','w','p','d','e','f','g','h','i','j',
'o','d','o','d','o','b','o','d','o','d',
'a','l','l','d','e','f','f','h','l','j',
'a','b','c','d','i','f','g','h','i','j',
'a','b','z','v','z','v','g','g','v','z',
'a','b','c','d','e','f','g','h','i','e',
'a','b','s','d','e','f','g','h','s','j',
};
cout << mostFrequent(c) << endl;
return 0;
}
So in research for this I found some material that allows me to count how many times a specific int or char would appear inside the array, but it doesn't quite suit the needs of the problem as it needs to return a string composed of the most frequent character. See below.
int myints[] = {10,20,30,30,20,10,10,20};
int mycount = std::count (myints, myints+8, 10);
Because it doesn't work though, I was thinking a for loop, to go row to row, I'll mostly likely need to save things into an array to count, but I'm not sure at all how to implement something like that. I even considered a caesar shift with an array, but I'm not sure where to go if that is the solution.
If I understood the task correctly, you have a matrix 10x10 and you have to create a string of length 10, where character at position i is the one that is most frequent among characters in the row i.
string mostFrequent(char c[10][10]) {
// The idea here is to find the most common character in each row and then append that character to the string
string s = "";
for (int i = 0; i < 10; i++) s += findMostFrequentCharacter(c[i]);
return s;
}
Now we just have to implement a function char findMostFrequentCharacter(char c). We are going to do that by counting all of the characters and picking the one that is most frequent (or it comes alphabetically before if there is more than one most frequent character):
char findMostFrequentCharacter(char c[10]) {
int counts[256]; // Assuming these are ASCII characters, we can have max 256 different values
// Fill it with zeroes (you can use memset to do that, but for clarity I'll write a for-loop
for (int i = 0; i < 256; i++) c[i] = 0;
// Do the actual counting
for (int i = 0; i < 10; i++) // For each character
counts[ c[i] ]++; // Increase it's count by 1, note that c[i] is going to have values between 65 (upper case A) and 122 (lower case z)
char mostFrequent = 0;
// Find the one that is most frequent
for (char ch = 'A'; ch <= 'z' ch++) // This will ensure that we iterate over all upper and lower case letters (+ some more but we don't care about it)
if (counts[ch] > counts[c]) c = ch; // Take the one that is more frequent, note that in case they have the same count nothing will happen which is what we want since we are iterating through characters in alphabetical order
return c;
}
I have written the code out of my head so I'm sorry if there are any compile errors.

at() not working in function

I believe that I am doing everything right, but the string is not being filled with the characters it is assigned. Here is what I know by testing: random is the correct character, q is the correct int, and s[i].name is a string. I have tried using .at(q) and [q], but nothing is working.
This is my error:
terminate called after throwing an instance of 'std::out_of_range'
what(): basic_string::at
Abort (core dumped)
for (int i = 0; i < num; i++) {
int q = 0;
char random = 50;
for (; random != 32;) {
file.get(random);
s[i].name.at(q) = random;
q++;
}
q = 0;
}
cout << s[0].name;
If that's all the code, it's crashing because name isn't allocating memory anywhere. A call to at requires that there be at least that many elements already allocated for it to work. Try calling push_back instead, that will add the element at the back of the string, expanding it if necessary.
Also, the last line of the for is superfluous, no point in setting q to 0 since it gets destroyed the next line and a new q is allocated on the next loop. Not to mention that with push_back, keeping track of the index with q becomes entirely redundant.
Lastly, the for is making things unnecessarily complicated, use while in this case instead.
This is difficult, because you didn't give us complete code, but if I understand your intention, you should be able to get something like it with this:
for (int i = 0; i < num; i++) {
char random = 50;
s[i].name = "";
for (; random != 32;) {
file.get(random);
s[i].name += random;
}
}
cout << s[0].name;
If your string is too short, at() will throw an exception. Using concatenation like I did should handle arbitrarily large strings.

2D Array : Recording an ambiguous '48' after writing to it

I'm pretty new to coding and these forums so please be patient with me if I mess up.
Anyway to the question, I'm creating a 2D array to hold past guesses for my game mastermind, as a record, so the user can look back on their previous attempts. I have made a 2D array for the old guesses and it has worked fine from my small "make sure it sorta works" attempts. However, the near exact same for the old feedback (like the you got 2 colours in the right place, 1 in the wrong place and 1 completely wrong colour) it messing up,the number 48 is appearing in it from no-where and for the life, I cant work out why.
Here's my code:
const int FEEDBACK_ARRAY_ROWS = 8;
const int FEEDBACK_ARRAY_COL = 3;
int fb_cur_row = 0;
int fb_cur_col = 0;
int Feedback2DArray[FEEDBACK_ARRAY_ROWS][FEEDBACK_ARRAY_COL];
for(int i = 0; i < 3; i++)
{
Feedback2DArray[fb_cur_row][fb_cur_col] = feedback_string[i];
fb_cur_col++;
cout << feedback_string[0];
cout << Feedback2DArray[0][0];
}
fb_cur_row++;
for(int i = 0; i < fb_cur_row; i++)
{
for(int j = 0; j < 3; j++)
{
cout << Feedback2DArray[i][j];
}
}
}
For some reason this "code formatting" doesn't like 1/2 of my code so, luckily this is all I could manage but im pretty sure it has the essential stuff on there. Basically I've for the cout << feedback_string[0];
cout << Feedback2DArray[0][0];
As they should output the same thing but they're not. The first line is outputting what it should which is '0' as the counter it is based off is (as they all are) 0. However the send line outputs '48'. Any ideas why ?
feedback_string most likely is declared something like the following:
char feedback_string[3];
In other words, it is an array of char. This holds the 3 characters, which are all '0', which has a decimal value of 48 (in ASCII Code). When you perform the assignment below:
Feedback2DArray[fb_cur_row][fb_cur_col] = feedback_string[i];
You are converting an object of type char to an object of type int. This is why you see 48 printed, because when you pass an int to cout, it prints out the value the int object holds. When you pass an object of type char, it prints out the character representation of that value.
Now, if your goal is to convert the character '0' to the actual value 0, you can use the following trick which takes advantage of how ASCII codes are ordered:
Feedback2DArray[fb_cur_row][fb_cur_col] = feedback_string[i] - '0';

std::string Array Element Access

Despite being a Project Euler program, the following code doesn't actually concern it much. I want to add 50 100-digit numbers, and I'm assigning each digit of each number to an element in the array addends[100][50]. I'd then add up each digit/place individually, and carry over extra digits. The numbers are being read in from a text file named Input.txt, and it merely contains all the numbers. http://projecteuler.net/problem=13
I'm having trouble assigning characters to elements of a string array (string numbers[100][50]) from a file input stream (<fstream>). The problem is described more completely in the comments:
"[for the 1st loop] This loop assigns a number to every string in the string array. Even though the second number (50) doesn't do anything (it seems to be overridden by std::string; see variable declaration), it needs to be there for the loop to work. Same "logic" for the loop; "j" doesn't do anything but needs to be there for the loop to work?"
And also, (for the 2nd loop) "This loop fills in the "addends[100][50]" array from the corresponding string array element. If I try to call "char_to_int()" with the array"numbers[i][j]", the compiler complains that the input isn't of the right data type. Adding a variable "k" makes the loop work for one run, but eventually crashes on the second loop (using "numbers[i][j][k]"). So I tried "char_to_int((numbers[i][j]).c_str())", but the compiler complains that "const char *" is incompatible with "char". Adding a pointer resolves the issue ("char_to_int( *( (numbers[i][j]).c_str() ) )"), but the program still crashes later." I took out some code that doesn't matter to make it more readable.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int char_to_int(char chInput);
int main()
{
int placeholder; //so console doesn't close immediately upon finish
int sum[102] = {0}; // 100+2, 100 places + 2 places from carrying over
int addends[100][50] = {0};
string numbers[100][50];
ifstream input("Input.txt");
/* This loop assigns a number to every string in the string array. Even
* though the second number (50) doesn't do anything (it seems to be
* overridden by std::string; see variable declaration), it needs to be
* there for the loop to work. Same "logic" for the loop; "j" doesn't do
* anything but needs to be there??? Confused :-\
*/
for (int i = 0; i < 100; i++)
for (int j = 0; j < 1; j++)
getline(input, numbers[i][j]);
/* This loop fills in the "addends[100][50]" array from the corresponding
* string array element. If I try to call "char_to_int()" with the array
* "numbers[i][j]", the compliler complains that the input isn't of the
* right data type. Adding a variable "k" makes the loop work for one run,
* but eventually crashes on the second loop (using "numbers[i][j][k]").
* So I tried "char_to_int((numbers[i][j]).c_str())", but the compiler
* complains that "const char *" is incompatible with "char". Adding a
* pointer resolves the issue ("char_to_int( *( (numbers[i][j]).c_str() ) )"),
* but the program still crashes on the second loop through.
*/
for (int i = 0; i < 100; i++)
for (int j = 0; j < 50; j++)
for (int k = 0; k < 1; k++) //used when the variable "k" was being used
addends[i][j] = char_to_int( (numbers[i][j]).c_str() );
return 0;
}
The code isn't finished; I decided against going on since I (obviously) need to fix this first.
It compiles and runs fine with
string numbers[100];
for (int i = 0; i < 100; i++)
getline(input, numbers[i]);
for (int i = 0; i < 100; i++)
for (int j = 0; j < 50; j++)
addends[i][j] = char_to_int( (numbers[i][j]));
after removing the stdafx.h include and defining char_to_int.
A std::string contains an array of characters itself, so you only need a one-dimensional array of std::strings. You can then access the characters of a string by [] indexing,
numbers[i][j]
gets the j-th character (byte, rather) of the i-th string in the array numbers.

itoa creates an infinite loop in C++

This is very strange. itoa(); seems to create an infinite loop.
for(int i = 0; i < 10; i++)
{
char buffer[1];
itoa(i, buffer, 10);
std::cout << buffer;
}
Why on earth does it do that? I've tried using different variables than i, numerical values without variables (i.e. itoa(1, buffer, 10);), it still keeps ending up in an infinite loop.
I've tried to google without much success, I found an old mail about it here.
I am using Windows XP 32 bit and Code::Blocks (with GCC) as a compiler.
Does anyone know what's wrong? Thanks in advance.
itoa null-terminates the string it produces, but you haven't made buffer large enough to hold the terminating NUL character. Try:
for (int i = 0; i < 10; i++)
{
char buffer[2];
itoa(i, buffer, 10);
std::cout << buffer;
}
Why on earth are you using a general number conversion routine for single digits?
for (int i = 0; i < 10; i++)
std::cout << char('0' + i);
(You need the cast back to char so that the compiler uses the correct overload of <<. The C++ standard guarantees that the character constants '0' through '9' have consecutive numeric values.)
Your buffer is too small -- itoa will write a null-terminated string, so your buffer will need at a minimum 2 bytes to hold values from 0-9.