This question already has answers here:
Output non-null terminated char array behaviours?
(3 answers)
Closed 3 months ago.
I am trying to make my own WORDLE game with C++. I have gotten to the point where I can check if a character is in the right spot but I do not know how to check if a letter is in the word but in a different place. This is what I have so far:
#include <iostream>
#include <fstream>
#include <string>
#include <stdio.h>
#include <cstdlib>
using namespace std;
string pickword();
string checkword(string ans, string word);
int main() {
string guess;
cout << "Hi welcome to WORDLE\n\n*Hit enter to start*";
cin.ignore();
string word = pickword();
cout << endl << word;
cout << "\nEnter a 5-letter word: ";
cin >> guess;
checkword(guess, word);
}
string pickword() {
srand((unsigned) time(NULL));
int random = 1 + (rand() % 1999);
string string;
ifstream ReadFile;
ReadFile.open("words.txt");
for (int i = 1; i <= random; i++) {
getline(ReadFile, string);
}
ReadFile.close();
return string;
}
string checkword(string ans, string word) {
char anslst[5];
char wrdlst[5];
for (int i = 0; i <= 4; i++) {
anslst[i] = ans[i];
wrdlst[i] = word[i];
}
//Green = \033[32m
//Red = \033[31m
//Yellow = \033[33m
for (int i = 0; i <= 4; i++) {
if (anslst[i] == wrdlst[i]) {
cout << "\033[32m" << anslst[i];
}
else if (anslst[i] != wrdlst[i]) {
cout << "\033[31m" << anslst[i];
}
}
return word;
}
the part relevent to the question is the bottom of checkword(). how can I see if the letters in the player's guess are in the the list containing the letters of the answer?
This main problem you're faced with isn't so much a question about C++, but instead an algorithmic question of "what to do with repeated letters?" For example, my understanding of the rules of Wordle are that a guess of "APPLE" when the answer was "PASTE", your first "P" should be yellow, but your second "P" should be grey. But if the answer had been "SPIPE", then "APPLE"'s second "P" should be yellow (because its first "P" is now green).
If we were to extend your C++ example with some of the programming choices you've already made, the central part of your checkword() might be written something like this:
EResult result[5];
for (int i = 0; i <= 4; i++) {
if (anslst[i] == wrdlst[i]) {
result[i] = GREEN;
}
else {
result[i] = GREY;
}
}
for (int i = 0; i <= 4; i++) {
if (result[i] != GREEN) {
bool searchingForYellow = true;
for (int j = 0; j <= 4 && searchingForYellow; j++) {
if (result[j] == GREY && anslst[i] == wrdlst[j]) {
result[j] = YELLOW;
searchingForYellow = false;
}
}
}
}
for (int i = 0; i <= 4; i++) {
if (result[i] == GREEN) {
cout << "\033[32m" << wrdlst[i];
}
else if (result[i] == YELLOW) {
cout << "\033[33m" << wrdlst[i];
}
else { // GREY
cout << "\033[31m" << wrdlst[i];
}
}
Notice that I've assumed you have an enumeration type named EResult with values GREEN or YELLOW or GREY (I haven't defined that type in my example code). You might need to study a bit about C++ enumerations if that is a new concept for you. Also consider using a "switch" statement instead of the condition at the end (but I'm not sure if you're familiar with "switch", so I wrote it this way for you instead). Also, consider using a "break" statement instead of the boolean variable (but again, I'm not sure how familiar you are with that programming element).
I need some help with the use of parallel vectors. What I want to do is have 2 vectors, 1 containing the alphabet, and the other containing the alphabet the other way around. When someone types in a word, it prints out the word using the inverted alphabet.
This is what I've done up until now and I'm not too sure if I'm on the right track or not:
#include <iostream>
#include <ctype.h>
using namespace std;
void search(char alfab[], char cripto[], int code){
cout << "Introduce your message: " << endl;
cin >> code;
for(int i = 0; i < code; i++)
{
if(code == 0){
cout << "Your code is:" << cripto[i] << endl;
}
}
}
int main(){
char alfab[26] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
char cripto[26] = {'z','y','x','w','v','u','t','s','r','q','p','o','n','m','l','k','j','i','h','g','f','e','d','c','b','a'};
char code;
}
Think about how you would do this by hand. Then try to translate those steps to code.
Get user input
for each letter:
decide which letter of your reversed alphabet it is
write that new letter down in the same position as the original
output new string
Try something more like this instead:
#include <iostream>
#include <string>
static const char alfab[26] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
static const char cripto[26] = {'z','y','x','w','v','u','t','s','r','q','p','o','n','m','l','k','j','i','h','g','f','e','d','c','b','a'};
std::string invert(const std::string &word){
std::string inverted = word;
for(std::string::size_type i = 0; i < inverted.size(); ++i)
{
char ch = inverted[i];
for(int j = 0; j < 26; ++j)
{
if (alfab[j] == ch)
{
inverted[i] = cripto[j];
break;
}
}
}
return inverted;
}
int main(){
std::string word;
std::cout << "Enter a word: " << std::endl;
std::cin >> word;
std::cout << "Your code is: " << invert(word) << std::endl;
}
You could try using one array:
std::string invert(const std::string& original)
{
static const char cripto[26] =
{
'z','y','x','w',
'v','u','t','s','r',
'q','p','o','n','m',
'l','k','j','i','h',
'g','f','e','d','c',
'b','a'
};
const size_t length = original.length();
std::string inverted_text;
for (unsigned int i = 0; i < length)
{
char c = original[i];
inverted_text += cripto[c - 'a'];
}
return inverted_text;
}
Edit 1: Using some math
You could simplify the encryption (inversion) by using some math.
std::string invert(const std::string& original)
{
const size_t length = original.length();
std::string inverted_text;
for (unsigned int i = 0; i < length)
{
char c = original[i];
inverted_text += (25 - (c - 'a')) + 'a';
}
return inverted_text;
}
Using transform
You could use std::transform:
char invert_char(char c)
{
return (25 - (c - 'a')) + 'a':
}
//...
std::transform(original_word.begin(), original_word.end(),
original_word.begin(), invert_char);
I am trying to implement the algorithm RLE with simple input like:
ddddddddddhhhhhhhhhhhhhhhttttttttttttt
code:
#include<iostream>
#include<fstream>
#include<vector>
using namespace std;
int main() {
vector<char> read;
ifstream file;
file.open("file.txt");
if (!file) {
cout << "Unable to open";
}
char v;
while(file>>v) {
read.push_back(v);
}
char x;
int count=0;
for(int i=0; i<read.size(); i++) {
x = read[i];
if(x != read[++i]) {
cout << x << "1";
}
while(x == read[++i]) {
count++;
}
cout << x << count;
count = 0;
}
return 0;
}
The output I am getting is:
d9d1h12h1t10t1
Please help me with the code.
Update: I have updated the question as I have realized few things.
Plus: This code produced no output, is there anything wrong which I am doing wrong?
char o;
char n;
int count=0;
for(int i=0; i<read.size(); i++) {
o = read[i];
n = read[++i];
while(o == n) {
count++;
}
cout << o << count;
if(o != n) {
cout << o << "1";
} count = 0;
}
return 0;
This loop:
char x;
int count=0;
for(int i=0; i<read.size(); i++) {
int j=i;
x = read[i];
if(x != read[++j]) {
cout << x << "1";
}
while(x == read[++j]) {
count++;
}
cout << x << count;
}
Has several errors. First, you should use two indices, i and j. i is going through each element of read, but then j is iterating through a subsequence too. What you want is to go through each element only once, and in each case either print or increase the count. However having a for loop and moving the index inside too is not a very good practice, is rather error-prone. Also you have to cout statements that are do not run at the right time (you don't wan to print something on every iteration, only when the character changes). You could do it with a while loop, or using a simpler structure like:
// If there are no characters finish
if (read.empty()) {
return 0;
}
// Get the first character
char lastChar = read[0];
int count = 1; // We have counted one character for now
// Go through each character (note start from 1 instead of 0)
for(int i = 1; i < read.size(); i++) {
// Get the next char
char newChar = read[i];
// If it is different, print the current count and reset the counter
if (lastChar != newChar) {
cout << lastChar << count;
count = 1;
lastChar = newChar;
} else { // Else increase the counter
count++;
}
}
// Print the last one
cout << lastChar << count;
return 0;
I'm trying to write a function which only reads four ints out of a users input like this: ewzge242jfdsiii23 So it is supposed to save only 2422.
This is my code and it just gives me some weird output, if I let it cout number.
Can you maybe see my mistakes and explain why I can't do it how I did and what I could do instead? Thanks a lot!
int readnumber ( ) {
char kar, ont_kar, ont_ont_kar;
int number;
while (kar != '\n' ){
cin.get (kar);
if (kar >= '0' && kar <= '9') {
old_kar=kar;
old_kar = old_kar*10 + (kar - '0');
old_old_kar = old_kar ;
} //if
} //while
if (old_kar < 9999) {
number=old_kar;
}//if
else {
number=old_old_kar;
}//else
}//readnumber
This looks too complicated, why do you need so many variables?
Also old_kar and old_old_kar are misstyped. The function does not return, that should be the main problem.
Here's a quick simple example:
unsigned readnumber(int number_of_chars) {
char ch;
unsigned number = 0;
while (number_of_chars > 0) {
std::cin.get(ch);
if ('\n' == ch)
break; // Stop on new line
if (ch < '0' or ch > '9')
continue; // Skip non-digits
--number_of_chars; // One digit processed
number = number * 10 + ch - '0'; // And added to the result
}
return number;
}
And here is a full version without break or continue:
#include <iostream> // std::cin, std::cout
#include <fstream> // std::ifstream
using namespace std;
int readnumber(int number_of_chars) {
char ch;
int number = 0;
while (number_of_chars > 0) {
std::cin.get(ch);
if ('\n' == ch)
return number;
if (ch >= '0' and ch <= '9') {
--number_of_chars;
number = number * 10 + ch - '0';
}
}
return number;
}
int main() {
int n = readnumber(4);
cout << "You entered: " << n << endl;
return 0;
}
NB: Always compile with all warnings on, this will save you a lot of time.
I'm trying to read from a text file and then count the number of occurences of each word and then export the results to a different text file. I'm only allowed to use loops and arrays for this assignment. I'm just looking for a slight push in the right direction, primarily in the beginning of the code. It's not compiling correctly!
using namespace std;
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
void put(string word, string words[], int counts[], int & size)
{
int w;
for (w = 0; w < size && word >= words[w]; w++);
if (w >= size) {
words[w] = word;
counts[w] = 1;
++size;
}
else if (word < words[w]) {
for (int i = size - 1; i >= w; i--) {
words[i + 1] = words[i];
counts[i + 1] = counts[i];
}
words[w] = word;
counts[w] = 1;
++size;
}
else {
counts[w] = counts[w] + 1;
}
}
int main()
{
int word;
ifstream input("input.txt");
ofstream chout("charcount.txt");
ofstream wout("wordscounts.txt");
int inputSize = sizeof(input) / sizeof(string);
int counts[100];
const int MAX = 100;
string words[MAX];
int wordsSize = 0;
while (input >> word) {
put(input[word], words, counts, wordsSize);
}
wout << " Word Frequency" << endl;
for (word = 0; word < inputSize; ++word) {
wout << setw(10) << words[word] << setw(4) << counts[word] << endl;
}
chout.close();
wout.close();
system("pause");
return 0;
}
This line:
put(input[word], words, counts, wordsSize);
You are trying to index into an ifstream. This is simply not allowed. The compiler (g++ 4.8.4) said:
no match for ‘operator[]’ (operand types are ‘std::ifstream {aka std::basic_ifstream<char>}’ and ‘int’)