Indefinite size of an array [duplicate] - c++

This question already has answers here:
How to define member array size at runtime
(3 answers)
Closed 6 years ago.
I was trying to make a simple program that counts the number of vowels and consonants the user's name has. The size of the array is dependent on how many letters does the user's name has. I'm using queue to display the letters. When ever I run the program, the .Exe file crashes. So I tried to change the array size to a number instead of a variable and it worked. The problem is in using a variable for the size of the array, I think. Is there anyway to fix it? So that I can still use a variable for the size of my array. Here is my code
#include <iostream>
#include <queue>
using namespace std;
int main()
{
int i;
char bin[i];
queue<char> name;
int v = 0, c = 0;
cout << "how many letters does your name have?:";
cin >> i;
cout << "Enter the letters of your name one by one:\n";
do {
for (int k = 0; k < i; k++) {
cout << " ";
cin >> bin[k];
name.push(bin[k]);
if (bin[k] == 'a' || bin[k] == 'A') {
v++;
}
if (bin[k] == 'e' || bin[k] == 'E') {
v++;
}
if (bin[k] == 'i' || bin[k] == 'I') {
v++;
}
if (bin[k] == 'o' || bin[k] == 'O') {
v++;
}
if (bin[k] == 'u' || bin[k] == 'U') {
v++;
}
if (bin[k] == 'b' || bin[k] == 'B') {
c++;
}
if (bin[k] == 'c' || bin[k] == 'C') {
c++;
}
if (bin[k] == 'i' || bin[k] == 'D') {
c++;
}
if (bin[k] == 'f' || bin[k] == 'F') {
c++;
}
if (bin[k] == 'g' || bin[k] == 'G') {
c++;
}
if (bin[k] == 'h' || bin[k] == 'H') {
c++;
}
if (bin[k] == 'j' || bin[k] == 'J') {
c++;
}
if (bin[k] == 'k' || bin[k] == 'K') {
v++;
}
if (bin[k] == 'l' || bin[k] == 'L') {
v++;
}
if (bin[k] == 'm' || bin[k] == 'M') {
c++;
}
if (bin[k] == 'n' || bin[k] == 'N') {
c++;
}
if (bin[k] == 'P' || bin[k] == 'p') {
c++;
}
if (bin[k] == 'q' || bin[k] == 'Q') {
c++;
}
if (bin[k] == 'r' || bin[k] == 'R') {
c++;
}
if (bin[k] == 's' || bin[k] == 'S') {
c++;
}
if (bin[k] == 't' || bin[k] == 'T') {
c++;
}
if (bin[k] == 'v' || bin[k] == 'V') {
c++;
}
if (bin[k] == 'w' || bin[k] == 'W') {
c++;
}
if (bin[k] == 'x' || bin[k] == 'X') {
c++;
}
if (bin[k] == 'y' || bin[k] == 'Y') {
c++;
}
if (bin[k] == 'z' || bin[k] == 'Z') {
c++;
}
}
} while (bin[100] != '1');
cout << "\n\nYour name is:\n";
for (queue<char> run = name; !run.empty(); run.pop()) {
cout << " " << run.front() << endl;
}
cout << "\nVowels= " << v;
cout << "\nConsonants= " << c << "\n";
cout << "\n\n\n\n";
system("PAUSE");
return 0;
}

Your code has undefined behavior. int i; creates an uninitialized int named i. Then you use the uninitialized garbage variable in char bin[i];. So now we have an array with undefined size.
At this point we can't go any further. Once undefined behavior is invoked we can no longer reason how the code should work. If you need an array and you are not going to know what the size is until run time then you should use a std::vector and push_back()

Related

How do I print multiple inputs and outputs in C++?

I'm trying to solve a problem on a competitive programming book where the output only appears after entering in the last input. I seem to have gotten the logic down but I'm still confuse as to how to do the input/output portion.
Here is the code:
#include <bits/stdc++.h>
int main()
{
std::ios_base::sync_with_stdio(false);
std::cin.tie(NULL);
std::vector<int>soundex;
std::string word;
for(int i = 0; i < word.length(); i++)
{
if (word[i] == 'B'|| word[i] == 'F' || word[i] == 'P' || word[i] == 'V')
{
soundex.push_back(1);
}
if (word[i] == 'C' || word[i] == 'G' || word[i] == 'J' || word[i] == 'K' || word[i] == 'Q' || word[i] == 'S' || word[i] == 'X' || word[i] == 'Z')
{
soundex.push_back(2);
}
if (word[i] == 'D' || word[i] == 'T')
{
soundex.push_back(3);
}
if (word[i] == 'L')
{
soundex.push_back(4);
}
if (word[i] == 'M' || word[i] == 'N')
{
soundex.push_back(5);
}
if (word[i] == 'R')
{
soundex.push_back(6);
}
}
for (int j = 0; j < soundex.size(); j++)
{
if (soundex[j] == soundex[j+1])
{
soundex.erase(soundex.begin() + 1);
}
std::cout << soundex[j];
}
std::cout << "\n";
return 0;
}
It behaves like this:
Input:
KHAWN
Output:
25
Input:
PFISTER
Output:
1236
Input:
BOBBY
Output:
11
But I need it to behave like this, per the instructions of the problem:
Input:
KHAWN
PFISTER
BOBBY
Output:
25
1236
11
Use while(cin >> word){ ... your code ... } to read until EOF (End Of File) in case every line only contains a word (no spaces allowed). You can keep the output as it is.

delete all consonents from the string "Hello, have a good day"

I have seen many good code to do this problem. I am new to coding. My question is where my logic went wrong. I think that problem is with second string str1. I din't initialize it. even when I am printing element by element withing if , it is working. but it is not working, when I am trying to print whole string str1.
#include<iostream>
#include<string>
using namespace std;
int main()
{
string str = "Hello, have a good day", str1;
for (int i = 0, j =0; i < str.length(); ++i)
{
if((str[i]>='a'&& str[i]<='z') || (str[i]>='A'&& str[i]<='Z'))
if (str[i] == 'I' || str[i] == 'i' || str[i] == 'U' || str[i] == 'u' || str[i] == 'O' || str[i] == 'o' ||
str[i] == 'A' || str[i] == 'a' || str[i] == 'E' || str[i] == 'e' )
{
str1[j] = str[i];
//std::cout << str1[j] ;
j++;
}
else
{
str1[j] = str[i];
j++;
}
}
cout << str1 <<'\n';
}
output is just blank.
The first thing to do is to write a function that determines whether a character is a consonant:
bool is_not_consonant(char ch) {
static char consonants[] = "bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ";
return std::find(std::begin(consonants), std::end(consonants), ch) == std::end(consonants);
}
Then use that function as a predicate to std::copy_if:
std::string result;
std::string input = whatever;
std::copy_if(std::begin(input), std::end(input),
std::back_inserter(result),
is_not_consonant);
Explanation
The problem is that you don't need the else condition. All you need to do is check for a vowel, and print if found which is rightly covered in your if condition.
Code
Try this:
#include<string>
using namespace std;
int main()
{
string str = "Hello, have a good day", str1;
for (int i = 0; i < str.length(); ++i)
{
if((str[i]>='a'&& str[i]<='z') || (str[i]>='A'&& str[i]<='Z'))
if (str[i] == 'I' || str[i] == 'i' || str[i] == 'U' || str[i] == 'u' || str[i] == 'O' || str[i] == 'o' || str[i] == 'A' || str[i] == 'a' || str[i] == 'E' || str[i] == 'e' )
{
str1 += str[i];
}
}
cout << str1 <<'\n';
}

game does not allow you to win

I'm writing the code for a game with C++, and when a player is supposed to win, for example all x's on the top row, the game keeps on prompting the next player for their move even when there is supposed to already be a winner. I don't know what's wrong with it, so any help in catching the problem is appreciated! Below is my full code.
#include <iostream>
#include <string>
using namespace std;
enum status{X_WON, O_WON, DRAW, UNFINISHED};
class Board{
public:
char boardArray[3][3];
Board();
bool makeMove(int, int, char);
status gameState();
void print();
};
Board::Board(){
for(int i = 0; i < 3; i++){
for(int j = 0; j < 3; j++){
boardArray[i][j] = '*';
};
};
};
bool Board::makeMove(int xIn, int yIn, char player){
if (boardArray[xIn][yIn] == '*'){
boardArray[xIn][yIn] = player;
return true;
}else{
return false;
};
};
status Board::gameState(){
status result;
if(boardArray[0][0] == 'x' && boardArray[0][1] == 'x' && boardArray[0] [2] == 'x'){
result = X_WON;
};
if(boardArray[0][0] == 'o' && boardArray[0][1] == 'o' && boardArray[0][2] == 'o'){
result = O_WON;
};
if(boardArray[1][0] == 'x' && boardArray[1][1] == 'x' && boardArray[1][2] == 'x'){
result = X_WON;
};
if(boardArray[1][0] == 'o' && boardArray[1][1] == 'o' && boardArray[1][2] == 'o'){
result = O_WON;
};
if(boardArray[2][0] == 'x' && boardArray[2][1] == 'x' && boardArray[2][2] == 'x'){
result = X_WON;
};
if(boardArray[2][0] == 'o' && boardArray[2][1] == 'o' && boardArray[2][2] == 'o'){
result = O_WON;
};
if(boardArray[0][0] == 'x' && boardArray[1][0] == 'x' && boardArray[2][0] == 'x'){
result = X_WON;
};
if(boardArray[0][0] == 'o' && boardArray[1][0] == 'o' && boardArray[2][0] == 'o'){
result = O_WON;
};
if(boardArray[0][1] == 'x' && boardArray[1][1] == 'x' && boardArray[2][1] == 'x'){
result = X_WON;
};
if(boardArray[0][1] == 'o' && boardArray[1][1] == 'o' && boardArray[2][1] == 'o'){
result = O_WON;
};
if(boardArray[0][2] == 'x' && boardArray[1][2] == 'x' && boardArray[2][2] == 'x'){
result = X_WON;
};
if(boardArray[0][2] == 'o' && boardArray[1][2] == 'o' && boardArray[2][2] == 'o'){
result = O_WON;
};
if(boardArray[0][0] == 'x' && boardArray[1][1] == 'x' && boardArray[2][2] == 'x'){
result = X_WON;
};
if(boardArray[0][0] == 'o' && boardArray[1][1] == 'o' && boardArray[2][2] == 'o'){
result = O_WON;
};
if(boardArray[0][2] == 'x' && boardArray[1][1] == 'x' && boardArray[2][0] == 'x'){
result = X_WON;
};
if(boardArray[0][2] == 'o' && boardArray[1][1] == 'o' && boardArray[2][0] == 'o'){
result = O_WON;
};
int taken = 0;
for(int i = 0; i < 3; i++){
for(int j = 0; j < 3; j++){
if(boardArray[i][j] != '*'){
taken++;
};
};
};
if(taken == 9 && (result != X_WON || result != O_WON)){
result = DRAW;
};
if(taken != 9 && (result != X_WON || result != O_WON || result != DRAW)){
result = UNFINISHED;
};
return result;
};
void Board::print(){
cout << " " << "0 " << "1 " << "2" << endl;
for(int i = 0; i < 3; i++){
cout << i << " ";
for(int j = 0; j < 3; j++){
cout << boardArray[i][j] << " ";
};
cout << endl;
};
};
class Ttt {
private:
char player;
public:
Board newBoard;
Ttt();
void play();
};
Ttt::Ttt(){
do{
cout << "Who should have the first move? x or o?" << endl;
cin >> player;
if (player == 'x' || player == 'o'){
break;
}else{
cout << "Not a valid player. Try again." << endl;
};
}while(true);
};
void Ttt::play(){
do{
int xcoord, ycoord;
do{
cout << "Player " << player << " , please enter your move. Example: 0 [enter] 0 (numbers from 0 - 2)" << endl;
cin >> xcoord >> ycoord;
if(newBoard.makeMove(xcoord, ycoord, player) == false){
cout << "That move is not valid. Try again." << endl;
}else{
break;
};
}while(true);
newBoard.makeMove(xcoord, ycoord, player);
newBoard.print();
if(player == 'x'){
player = 'o';
}else{
player = 'x';
};
if(newBoard.gameState() == X_WON){
cout << "Player X is the winner!" << endl;
break;
};
if(newBoard.gameState() == O_WON){
cout << "Player O is the winner!" << endl;
break;
};
if(newBoard.gameState() == DRAW){
cout << "Draw!" << endl;
break;
};
}while(true);
};
int main(){
Ttt newgame;
newgame.play();
}
The test
(result != X_WON || result != O_WON || result != DRAW)
is always true, since result can't be equal to all 3 values.
result should be initialised to UNFINISHED and the test changed to:
(taken != 9 && result == UNFINISHED)

How to ignore certain letters and spaces in character arrays

Trying to make an else statement that get rid of all other letter and spaces then the ones i want. This function is to change user inputted letters into other letters
using namespace std;
void dna_to_rna(char rna[])
{
for (int i = 0; i < 100; i++)
{
if (rna[i] == 'a' || rna[i] == 'A')
rna[i] = 'U';
else if (rna[i] == 'c' || rna[i] == 'C')
rna[i] = 'G';
else if (rna[i] == 'g' || rna[i] == 'G')
rna[i] = 'C';
else if (rna[i] == 't' || rna[i] == 'T')
rna[i] = 'A';
}
What should the else statement look like in order to drop all other chars?
If the input parameter can be changed to std::string, then you can use one of the following implementation:
void dna_to_rna(std::string& rna)
{
auto it = rna.begin();
while (it != rna.end())
{
if (*it == 'a' || *it == 'A') *it = 'U';
else if (*it == 'c' || *it == 'C') *it = 'G';
else if (*it == 'g' || *it == 'G') *it = 'C';
else if (*it == 't' || *it == 'T') *it = 'A';
else
{
it = rna.erase(it);
continue; // it already "points" to the next element
}
++it;
}
}
std::string dna_to_rna(const std::string& dna)
{
std::string rna;
for (auto c : dna)
{
if (c == 'a' || c == 'A') rna += 'U';
else if (c == 'c' || c == 'C') rna += 'G';
else if (c == 'g' || c == 'G') rna += 'C';
else if (c == 't' || c == 'T') rna += 'A';
}
return rna;
}
Maybe like this:
using namespace std;
void dna_to_rna(char rna[])
{
string s = "";
for (int i = 0; i < 100; i++)
{
if (rna[i] == 'a' || rna[i] == 'A')
s += 'U';
else if (rna[i] == 'c' || rna[i] == 'C')
s += 'G';
else if (rna[i] == 'g' || rna[i] == 'G')
s += 'C';
else if (rna[i] == 't' || rna[i] == 'T')
s += 'A';
}
strcpy(rna, s.c_str());
}
The idea is simply to use a std::string as a temporary buffer. The string is empty to start with. Then you add the characters you want one-by-one. When done with the loop, copy the content of the std::string back to the rna-array.
To make you code much simpler, and easier to read:
using namespace std;
void dna_to_rna(char rna[]) {
int arrLength = sizeof(rna)/sizeof(rna[0]); // Get size of array
for (int i = 0; i < arrLength; i++){
if (toupper(rna[i]) == 'A'){
rna[i] = 'U';
}
else if (toupper(rna[i]) == 'C') {
rna[i] = 'G';
}
else if (toupper(rna[i]) == 'G'){
rna[i] = 'C';
}
else if (toupper(rna[i]) == 'T'){
rna[i] = 'A';
}
}
}
I created a second array and as long as the information that I was looking for met the criteria that was necessary I placed it into the second array making sure that the position that I was placing it in the array was always in the right spot by creating a second variable that would count the the proper position in the array then just cout array
using namespace std;
void dna_to_rna(char rna[])
{
int x = 0;
char newrna[100];
for (int i = 0; i < 100; i++)
{
if (rna[i] == 'a' || rna[i] == 'A')
{
newrna[x] = 'U';
x++;
}
else if (rna[i] == 'c' || rna[i] == 'C')
{
newrna[x] = 'G';
x++;
}
else if (rna[i] == 'g' || rna[i] == 'G')
{
newrna[x] = 'C';
x++;
}
else if (rna[i] == 't' || rna[i] == 'T')
{
newrna[x] = 'A';
x++;
}
}

Create a output file from file stream

I am fairly new to c++ and yes this is a homework assignment.
I am considering a switch statement instead of the if else statements in my function.
I am trying to write information read from an input filestream, to an output file after the data has been manipulated.
The prgram is supposed to read information from a file, process it and then display the data on the console and also write the result to an output file, the program should ask the user to enter the filename for both input and output files.
I cannot get my program to create a file. It works with files that already exist though.
Please help me with getting my program to create a file if it does not exist.
Oh and this is in c++
Any help will be greatly appreciated.
MY CODE :
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>
#include <sstream>
using namespace std;
char getNumber(char l);
int main ()
{
string s1 = "D:\\Unisa\\Assignment_stuffs\\COS1512\\Assignment\\";
string inFile, outFile;
cout << " Please enter the input filename: ";
cin >> inFile;
cout << "\nPlease enter the output filename: ";
cin >> outFile;
string inFileAdd = s1 + inFile;
string inFileAdd2 = s1 + outFile;
ifstream in_stream;
ofstream out_stream;
in_stream.open(inFileAdd.c_str(), ios::in);
if (in_stream.fail())
{
cout << "Error!! Input file opening failed.";
exit(1);
}
out_stream.open(inFileAdd2.c_str(), ios::out);
if (out_stream.fail())
{
cout << "Error!! Output file opening failed.";
exit(1);
}
char next = ' ';
string letter;
while (!in_stream.eof())
{
in_stream.get(next);
while (next != '\n')
{
cout << next;
out_stream.put(next);
letter = letter + getNumber(next);
in_stream.get(next);
}
cout << " " + letter;
out_stream << " " + letter << endl;
letter = "";
cout << endl;
}
in_stream.close();
return 0;
}
char getNumber(char l)
{
if ((l == 'A') || (l == 'a') || (l == 'B') || (l == 'b') || (l == 'C') || (l == 'c'))
{
return '2';
}
else if ((l == 'D') || (l == 'd') || (l == 'E') || (l == 'e') || (l == 'F') || (l == 'f'))
{
return '3';
}
else if ((l == 'G') || (l == 'g') || (l == 'H') || (l == 'h') || (l == 'I') || (l == 'i'))
{
return '4';
}
else if ((l == 'J') || (l == 'j') || (l == 'K') || (l == 'k') || (l == 'L') || (l == 'l'))
{
return '5';
}
else if ((l == 'M') || (l == 'm') || (l == 'N') || (l == 'n') || (l == 'O') || (l == 'o'))
{
return '6';
}
else if ((l == 'P') || (l == 'p') || (l == 'Q') || (l == 'q') || (l == 'R') || (l == 'r') || (l == 'S') || (l == 's'))
{
return '7';
}
else if ((l == 'T') || (l == 't') || (l == 'U') || (l == 'u') || (l == 'V') || (l == 'v'))
{
return '8';
}
else if ((l == 'W') || (l == 'w') || (l == 'X') || (l == 'x') || (l == 'Y') || (l == 'y') || (l == 'Z') || (l == 'z'))
{
return '9';
}
}
Do what Beta said and create a minimal file opening and writing program first. Get that working. Then build the rest of the needed functionality around that, compiling and fixing errors every step of the way. If you can get this working, add a little bit of your desired functionality to it. Look into permissions on the directory you are writing to if this doesn't work. This compiles in visual studio, you may need to include other libraries on linux/unix/mac:
#include <fstream>
int main()
{
std::ofstream file;
file.open("file.txt"); //open a file
file<<"Hello file\n"; //write to it
file.close(); //close it
}