I want to put a string into a char nxn matrix, which makes the string "abcdefghi" into a 3x3 char matrix, and become
{abc;def;ghi}
but it does not save right.
I try to output every i, j,ch[i][j] and s[j+i*3] in the first loop, and they look right, but in the final output, it goes wrong.
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int main()
{
char ch[2][2];
string s = "abcdefghi";
int i, j;
for (i = 0; i < 3; i++)
{
for(j = 0; j < 3; j++)
{
ch[i][j] = s[j + i * 3];
}
}
for (i = 0; i < 3; i++)
{
cout << ch[i] << endl;
}
return 0;
}
I want the ch matrix become
{abc;def;ghi}
but the output is
{abdegi;degi;gi}
Your code has two problems:
1. char ch[2][2]; is supposed to be char ch[3][3];
2. You assume you can print an entire row with a single cout << ch[i] << endl;, but the rows don't end with a '\0', thus cout prints everything until it hits a null.
Here's a fixed version:
#include <iostream>
int main()
{
char ch[3][3];
auto s = "abcdefghi";
auto* ptr = s;
for (auto& r1 : ch)
{
for (auto& r2 : r1)
{
r2 = *ptr++;
}
}
for (const auto& r1 : ch)
{
for (auto r2 : r1) // char is trivial to copy
{
std::cout << r2;
}
std::cout << '\n';
}
std::cout << std::flush;
return 0;
}
Related
Using nested while loops to count the number of each character in a given string and put those numbers in an array. Then finding the largest number in the array to determine the most common character. Returning this character to the caller.
When placing a breakpoint |down (noted below) Im getting the first array value to be correct, and the second to be incorrect.
I don't know where I'm going wrong. I do have to admit I'm quite burned out right now, so it could be something easy I'm overlooking. I don't know.
#include <iostream>
using namespace std;
#include <string>
#include <string.h>
char median(char *);
int main() {
const int SIZE = 50;
char thing[SIZE];
char *strPtr;
cout << " give me a string: " << endl;
cin.getline(thing, SIZE);
strPtr = thing;
char mostcommon = median(strPtr);
cout << mostcommon;
}
char median(char *strPtr) {
char holder = 'x';
int numberof[50];
int counter = 0;
int arrayspacecounter = 0;
int thirdcounter;
int fourthcounter;
while (*strPtr != '\0') {
holder = *strPtr;
while (*strPtr != '\0') {
strPtr++;
if (holder == *strPtr) {
counter++;
}
}
numberof[arrayspacecounter] = counter; //counts the number of each character.
arrayspacecounter++;
strPtr++;
counter = 0;
}
v
// break point set HERE
^
//find the largest number in numberof[]
int largest = 0;
for (thirdcounter = 0; thirdcounter <= 100; thirdcounter++) {
for (fourthcounter = 1; fourthcounter <= 100; fourthcounter++) {
if (largest < numberof[fourthcounter]) {
largest = numberof[fourthcounter];
}
}
}
return *(strPtr + (largest));
}
numberof is not initialised so will initially contain junk values, any unused entries will still contain junk values where your breakpoint is. Use:
int numberof[50] = { 0 };
Next fourthcounter goes up to 100 but you only have 50 elements in numberof, replace the magic number 50 with a constant like MAX_ELEMENTS:
const size_t MAX_ELEMENTS = 50;
int numberof[MAX_ELEMENTS] = { 0 };
....
for (thirdcounter = 0; thirdcounter < MAX_ELEMENTS; thirdcounter++)
{
for (fourthcounter = 1; fourthcounter < MAX_ELEMENTS; fourthcounter++)
{
Alternatively just use the arrayspacecounter you have created already:
for (thirdcounter = 0; thirdcounter < arrayspacecounter; thirdcounter++)
{
for (fourthcounter = 1; fourthcounter < arrayspacecounter; fourthcounter++)
{
I'm not sure why you have two for loops at the end? The outer one seems redundant. Fixing various other bugs results in the working function:
char median(const char* strPtr)
{
const size_t MAX_ELEMENTS = 50;
int numberof[MAX_ELEMENTS] = { 0 };
int counter = 0;
int arrayspacecounter = 0;
int fourthcounter;
const char* temp = strPtr;
while (*temp != '\0')
{
const char* holder = temp;
while (*temp != '\0')
{
temp++;
if (*holder == *temp)
{
counter++;
}
}
numberof[arrayspacecounter] = counter; //counts the number of each character.
arrayspacecounter++;
temp = holder;
temp++;
counter = 0;
}
//find the largest number in numberof[]
int largest = 0;
for (fourthcounter = 1; fourthcounter < arrayspacecounter; fourthcounter++)
{
if (numberof[largest] < numberof[fourthcounter])
{
largest = fourthcounter;
}
}
return *(strPtr + (largest));
}
Your code could be much simpler though:
#include <iostream>
#include <string>
#include <map>
#include <algorithm>
char median(const char*);
int main()
{
char mostcommon = median("test");
std::cout << mostcommon;
}
char median(const char* strPtr)
{
std::map<char, int> frequencies;
for (auto ch = strPtr; *ch != '\0'; ch++)
{
frequencies[*ch]++;
}
auto max = std::max_element(frequencies.begin(), frequencies.end(), [](const auto& a, const auto& b) { return a.second < b.second; });
return max->first;
}
Your program segfaults in median somewhere, my guess is that you're trying to use a position outside of the boundaries of your array somewhere.
If all you're wanting to count frequency try something simpler, like this for example.
#include <string>
#include<iostream>
int main()
{
std::string phrase;
std::cout << "Enter a phrase \n";
std::getline(std::cin,phrase);
int a = 'A'; //index 0 of your array
int count=0;int max=0;
int counter[26] = {0}; //array that will hold your frequencies
char highestFreq;
for(char c:phrase) {
if(!isspace(c)) count = ++counter[int(toupper(c))-a];
if(count>max) max=count, highestFreq=c;
}
std::cout << "max is: "<<max << ". The letter is '"<< highestFreq << "'.\n"<< std::endl;
}
should be like this output:
Monday
onday
nday
day
ay
y
what I have so far:
#include <iostream>
using namespace std;
int main () {
char *weekDays[7]={"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"};
for (int i=0;i<7;i++){
cout << weekDays[0][i] << endl;
}
return 0;
}
output:
M
o
n
d
a
y
Im on mobile and tired but sth. like this should work:
int main(){recPrint(0);}
void recPrint(int level){
char mon[] = "Monday";
for(int i=level; i<strlen(mon); i++){
std::cout << mon[i];
}
std::cout << std::endl;
recPrint(++level);
}
add another parameter char dayOfTheWeek[] and you can call it with whatever you want.
Try this
#include <iostream>
using namespace std;
void display(char s[])
{
int n = strlen(s);
for(int i = 0; i < n; i++)
{
for(int j = i; j < n; j++)
{
cout << s[j];
}
cout << endl;
}
}
int main () {
char *weekDays[7]={"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"};
display(weekDays[0]);
}
In the following code for loop returns me 5 values [0,1,2,3,4]. I want to get 5 text files with the name h_0.0, h_1.0, h_2.0, h_3.0, h_4.0 and h_0.0 should store first number of for loop i.e.,0 file h_1.0 should store second number of for loop i.e., 1 and so on.
#include <iostream>
using namespace std;
int *name()
{
static int n[5];
for (int i = 0; i < 5; i++)
{
n[i] = i;
}
return n;
}
int main()
{
int *p;
p = name();
for (int i = 0; i < 5; i++)
{
cout << *(p + i) << endl;
}
return 0;
}
If I understand well what you want to do, here is some basic solution, for demo,
creating files in current folder:
#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;
int* name() {
static int n[5];
for (int i = 0; i < 5; i++) {
n[i] = i;
}
return n;
}
int main() {
int* p;
p = name();
for (int i = 0; i < 5; i++)
{
int fn = *(p + i);
std::stringstream ss;
ss << fn;
std::string fname = "h_" + ss.str();
fname += ".0";
std::ofstream f(fname.c_str());
if (f.good()) {
f << fn;
cout << "file h_" << fn << ".0 created" << endl;
}
}
return 0;
}
Use filestream.
#include <fstream> // include filestream
#include <sstream> // for storing anything that can go into a stream
#include <string>
int main()
{
std::string nameholder;
std::ofstream outputstream;
for (int i = 0; i < 5; i++)
{
nameholder = "h_"; // reset name every loop
std::stringstream sstreamholder; // remake stringstream every loop
sstreamholder << i; // store current number in stringstream
nameholder += sstreamholder.str() + ".0"; // append what sstreamholder currenlty has and the file extension .0
outputstream.open(nameholder); // write the filename with the updated name
outputstream << i << std::endl; // write the number in the file
outputstream.close(); // close the file so it's ready for the next open
}
return 0;
}
I have a constructor and a method in an implementation file:
Boggle::Boggle(std::string boardString){
dim = sqrt(boardString.size());
vector<vector<char> > grid(dim, vector<char>(dim));
int co = 0;
for (int i = 0; i < dim; i++)
{
for (int j = 0; j < dim; j++)
{
grid[i][j] = boardString[co];
co++;
}
}
}
void Boggle::printMe() {
for (auto inner : grid)
{
for (auto item : inner)
{
cout << item << " ";
}
cout << endl;
}
}
The program executes, but doesn't do anything. As you can see I have sized my vector when I declared it. I believe the issue lies in my logic of assigning a character to a vector from a string perhaps.
As hinted in comments your vector grid is local to your function. You mostly likely wanted to use a class variable but ended up creating a local variable. You can use resize to set the dimensions of your grid. Also its better to ceil the sqrt to make sure that we are not missing any characters.
Example:
#include <stdio.h>
#include <vector>
#include <string>
#include <cmath>
#include <iostream>
using namespace std; // Avoid this
class Boggle{
public:
int dim;
vector<vector<char>> grid;
Boggle(string boardString);
void printMe();
};
Boggle::Boggle (std::string boardString)
{
dim = ceil(sqrt(boardString.size ()));
grid.resize(dim, vector <char>(dim));
int co = 0;
for (int i = 0; i < dim; i++) {
for (int j = 0; j < dim; j++)
{
grid[i][j] = boardString[co];
co++;
}
}
}
void Boggle::printMe ()
{
for (auto inner:grid) {
for (auto item:inner)
{
cout << item << " ";
}
cout << endl;
}
}
int main(){
Boggle boggle("hello world");
boggle.printMe();
return 0;
}
Result:
h e l l
o w o
r l d
First of all, im a c++ noob! Ok with that being said, i need to declare a function that initializes a grid. The function takes an array of int as the input and needs to return an array of int. I have:
array<int> InitializeGrid (array<int>)
{
const int NB_ROWS = 10;
const int NB_COLUMN = 10;
const int WATER = 0;
int grid[NB_ROWS][NB_COLONN];
for (int i = 0; i < NB_ROWS; i++)
{
for (int j = 0; j < NB_COLONN; j++)
{
grid[i][j] = WATER;
cout << grid[i][j] << " ";
}
cout << endl;
}
return ??
}
You don't need to return anything if you pass the array by reference:
#include <array>
#include <iostream>
static const int NB_ROWS = 10;
static const int NB_COLUMN = 10;
static const int WATER = 0;
void InitializeGrid (std::array<std::array<int, NB_COLUMN>, NB_ROWS> &grid)
{
for (auto &row : grid)
{
for (auto &col : row)
{
col = WATER;
std::cout << col << " ";
}
std::cout << '\n';
}
}
int main()
{
std::array<std::array<int, NB_COLUMN>, NB_ROWS> grid;
InitializeGrid(grid);
}
btw, if your WATER is 0 it is sufficive to write
std::array<std::array<int, NB_COLUMN>, NB_ROWS> grid{};
to initialize all elements to zero.