So, what I'm trying to do is, open and read a file, but read only the first line. I have already done this part. I have to read each character on that line and then I need to print the alphabet letters that are not found in that line.
Let's say the line was:
a b c D E f G H I j k L M n o
So, I will have to print the letters from p-z, because they are not in the line.
So, how will get the letters that are not in the line?!
This is what I have so far:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
using namespace std;
int main(int argc, char *argv[]){
if(argc < 2){
cerr << "Usage: pangram <filename>" << endl;
return 0;
}
ifstream infile(argv[1]);
if (infile.good() == false){
cerr << "Error opening file[" << argv[1] << "]" << endl;
return 1;
}
char ch;
string line;
int a[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};
int brk = 0;
while(infile.good()){
if(brk == 0) {
getline(infile, line);
for(int i=0; i <= line[i]; i++){
if(isalpha(line[i])) {
if(line[i] == )
cout << line[i] << endl;
}
}
}
brk ++;
if(brk == 1) {
break;
}
}
}
Here's a slightly modified version of your solution. I'm intentionally using a stack allocation of 26 bools instead of bitset so it's easier to comprehend.
bool letter_was_seen[26] = {}; // initialize an array to hold 26 bools (A..Z) all to false
getline(infile, line); // read a line into a string
size_t len = line.size();
for (size_t i = 0; i < len; i++)
{
char ch = ::toupper(line[i]); // convert to upper case
if ((line[i] >= 'A') && (line[i] <= 'Z')) // is it a valid letter A..Z ?
{
letter_was_seen[ch - 'A'] = true; // mark it's place in the array as "seen"
}
}
// now print the letters not seen within the line
for (char i = 'A'; i <= 'Z'; i++)
{
int index = (int)(i - 'A');
if (letter_was_seen[index] == false)
{
cout << i; // print the letter not seen
}
}
cout << endl; // print end of line to flush output
Another possible solution,
#include <deque>
#include <algorithm>
#include <iostream>
using namespace std;
int main() {
deque<char> allChars(26);
iota(allChars.begin(), allChars.end(), 'a');
char readString[] = "test xyz";
for (char& c : readString) {
allChars.erase(remove(allChars.begin(), allChars.end(), c),
allChars.end());
}
cout<<"Not removed: ";
for (char& c : allChars) {
cout<<c<<" ";
}
cout<<endl;
}
Related
We are asked to open a text file that contains a sentence and go through all the letters and whitespace in the file and count how many of each ascii character there are.
When I had all my information in the main function it worked fine. I just can't figure out how to call them all successfully in the main. The output should look like:
15 words
6 a
3 d
6 e
3 g
3 h
3 i
15 l
6 o
6 r
3 s
3 t
3 w
I achieved this output when again everything was in the main function so now it's just a matter of getting it like this with my function definitions.
My Code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
//prototypes
//int openFile();
void readFile(ifstream &in);
void closeFile(ifstream &in);
//definitions
int openFile()
{
ifstream in;
in.open("word_data.txt");
}
void readFile(ifstream &in)
{
//store the frequency of the letters
int letters[128];
//declare variables
char let;
int wordCount = 0;
//for loop to initialize all counts to zero
for (int i = 0; i < 128; i++)
{
letters[i] = 0;
}
//get letters until we reach end of file
//whitespace = wordCount++;
let = in.get();
while (let != EOF)
{
if (let == ' ')
wordCount++;
//change to lowercase
let = tolower(let);
letters[let]++;
let = in.get();
}
//output
//num words
cout << wordCount + 1 << " words" << endl;
//count how many of each letter there are & print to screen in alphabetical order
for (char let = 'a'; let <= 'z'; let++)
{
if (letters[let] != 0)
{
cout << letters[let] << " "<< let <<endl;
}
}
}
void closeFile(ifstream &in)
{
in.close();
}
int main()
{
openFile();
readFile(in);
closeFile(in);
return 0;
}
The problem is with your openFile() function. It creates a local ifstream only, it does not open an ifstream that is accessible to the other functions.
Try this instead:
#include <iostream>
#include <fstream>
#include <string>
#include <cctype>
using namespace std;
//prototypes
void openFile(ifstream &in);
void readFile(ifstream &in);
void closeFile(ifstream &in);
//definitions
void openFile(ifstream &in)
{
in.open("word_data.txt");
}
void readFile(ifstream &in)
{
//store the frequency of the letters
int letters[128] = {};
//declare variables
char ch;
int wordCount = 0;
//get letters until we reach end of file
while (in.get(ch))
{
if (ch == ' ')
wordCount++;
//change to lowercase
ch = static_cast<char>(tolower(static_cast<unsigned char>(ch)));
letters[ch]++;
}
//output
//num words
cout << wordCount + 1 << " words" << endl;
//count how many of each letter there are & print to screen in alphabetical order
for (ch = 'a'; ch <= 'z'; ch++)
{
if (letters[ch] != 0)
{
cout << letters[ch] << " " << ch <<endl;
}
}
}
void closeFile(ifstream &in)
{
in.close();
}
int main()
{
ifstream in;
openFile(in);
readFile(in);
closeFile(in);
return 0;
}
With that said, you might consider using a std::map to track your frequencies, rather than using an int[] array. And using operator>> to read whole words at a time:
#include <map>
...
void readFile(ifstream &in)
{
//store the frequency of the letters
map<char, int> letters;
//declare variables
string word;
int wordCount = 0;
//get letters until we reach end of file
while (in >> word)
{
++wordCount;
//for(size_t idx = 0; idx < word.size(); ++idx)
//{
// char ch = word[idx];
for(char ch : word)
{
//change to lowercase
ch = static_cast<char>(tolower(static_cast<unsigned char>(ch)));
if (ch >= 'a' && ch <= 'z')
letters[ch]++;
}
}
//output
//num words
cout << wordCount << " words" << endl;
//count how many of each letter there are & print to screen in alphabetical order
//for (map<char, int>::iterator iter = letters.begin(); iter != letters.end(); ++iter)
//{
// cout << iter->second << " " << iter->first << endl;
//}
for (auto &elem : letters)
{
cout << elem.second << " " << elem.first << endl;
}
}
I am trying to remove the spaces from a string to validate a Palindrome phrase. I have looked up other methods, but my professor literally copy and pasted the remove space for loop in our instructions but I can't get it to work and he says he doesn't want us going to the internet for help. I am trying to remove spaces from a phrase like "too hot to hoot" to validate it. I can get my program to work with single words like "bob", but not phrases.
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
char input[100];
cout << "Please enter a word/phrase: ";
cin >> input;
for (int i = 0; i < strlen(input); i++)
{
while (s[i] == ' ')//getting "s" is undefined error
s.erase(i,1);
}
int i = 0;
int j = strlen(input)-1;
bool a = true;
for (i = 0; i < j; i++)
{
if (input[i] != input[j])
{
a = false;
}
j--;
}
if(a)
{
cout << input << " is a Valid Palindrome." << endl;
}
else
{
cout<< input << " is not a Valid Palindrome." << endl;
}
system("pause");
return 0;
}
Maybe you have not copy the result from temporary variable 's'. So, the modified codes should be:
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <cstring>
using namespace std;
int main(int argc, char *argv[])
{
char input[100];
cout << "Please enter a word/phrase: ";
fgets(input, 100, stdin);
string s(input); // define a temporary variable 's'
int i = 0;
while (i < s.length())
{
if (s[i] == ' ' || s[i] == '\n')
{
s.erase(i, 1); // erase from variable 's', other then 'input'
continue;
}
i++;
}
// copy result from 's' to 'input'
sprintf(input, "%s", s.c_str());
int j = strlen(input) - 1;
bool a = true;
i = 0;
for (i = 0; i < j; i++)
{
if (input[i] != input[j])
{
a = false;
}
j--;
}
if (a)
{
cout << input << " is a Valid Palindrome." << endl;
}
else
{
cout << input << " is not a Valid Palindrome." << endl;
}
system("pause");
return 0;
}
This question already has answers here:
How can I print a list of elements separated by commas?
(34 answers)
Closed 6 years ago.
This is when going through a list of integers in order seperated by commas and I only print one instance of an integer even where there are more than one seperated by commas. (CodeEval challenge https://www.codeeval.com/open_challenges/29/)
My problem is I am trying to do this in linear time without any external storage. And I can't have a comma at the end (e.g. 1,3,4,6,). The solutions I found online all use some list to store the integers and then they do a print.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
string str = "1,2,2,3,3,3,4,4";
char c;
int num = -1;
for (int i = 0; i < str.length(); ++i) {
if (str[i] == ',') continue;
else {
c = str[i];
if ((c - '0') != num) {
num = c - '0';
cout << num << ",";
}
}
}
cout << endl;
return 0;
}
One of the solution is to use boolean flag:
bool first = true;
for( ... ) {
if( first ) first = false;
else std::cout << ',';
std::cout << data;
}
if (i == str.length() - 1)
{
cout << num;
}
else
{
count << num << ",";
}
Or you could print a backspace at the end of the string processing:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
string str = "1,2,2,3,3,3,4,4";
char c;
int num = -1;
for (int i = 0; i < str.length(); ++i) {
if (str[i] == ',') continue;
else {
c = str[i];
if ((c - '0') != num) {
num = c - '0';
cout << num << ",";
}
}
}
cout << '\b';
cout << endl;
return 0;
}
Here is my code thus far, I think its doing its job right and i believe the problem is with my arrays.
#include <iostream>
#include <cctype>
#include <fstream>
using namespace std;
const char FileName[] = "text.txt";
int main()
{
string line;
ifstream inMyStream(FileName);
int c;
int upperCaseCount[26] = { 0 };
int lowerCaseCount[26] = { 0 };
char oneLetter;
if (inMyStream.is_open())
{
while (getline(inMyStream, line))
{
c += line.length();
}
for (unsigned n = 0; n < line.length(); ++n)
{
oneLetter = char(line[n]);
if (oneLetter >= 'A' && oneLetter <= 'Z')
{
upperCaseCount[int(oneLetter) - 'A']++;
}
else if (oneLetter >= 'a' && oneLetter <= 'z')
{
lowerCaseCount[int(oneLetter) - 'a']++;
}
}
}
inMyStream.close();
cout << "Uppercase Characters: " << upperCaseCount << endl;
cout << "Lowercase Characters: " << lowerCaseCount <<endl;
cout << "Digits: " << c << endl;
return 0;
}
Here's the output I'm getting--->
C:\Users\House\Desktop\Lab11>test
Uppercase Characters: 0x28fcf4
Lowercase Characters: 0x28fd5c
Digits: 1959532772
C:\Users\House\Desktop\Lab11>
I see two issues (there is another big one that I left for you to debug).
You need to initialize the variable c to some useful starting value (perhaps 0).
You need to iterate over your arrays to print their contents. The odd looking outputs you currently get are addresses, not the array contents.
Here is a Working example for counting upperCases lowerCases and numbers
#include <iostream>
#include <cctype>
#include <fstream>
using namespace std;
const char FileName[] = "text.txt";
int main()
{
string line;
ifstream inMyStream(FileName);
int c=0;//counts digits
int upperCount=0;//counts uppercases
int lowerCount=0;//counts lowercases
char oneLetter;
if (inMyStream.is_open())
{
while (getline(inMyStream, line))
{
for (unsigned n = 0; n < line.length(); ++n)
{
oneLetter = line[n];
if (oneLetter >= 'A' && oneLetter <= 'Z')
{
upperCount++;
}
else if (oneLetter >= 'a' && oneLetter <= 'z')
{
lowerCount++;
}
else if (oneLetter >= '0' && oneLetter <= '9'){
c++;
}
}
}
}
inMyStream.close();
cout << "Uppercase Characters: " << upperCount << endl;
cout << "Lowercase Characters: " << lowerCount <<endl;
cout << "Digits: " << c << endl;
return 0;
}
hope it helped ;)
I am using this program to implement Mono alphabetic cipher. The problem i am getting is when i input plain text it doesn't get out of the loop when condition is met which is pressing the enter key.Here is my code.
int main()
{
system("cls");
cout << "Enter the plain text you want to encrypt";
k = 0;
while(1)
{
ch = getche();
if(ch == '\n')
{
break; // here is the problem program not getting out of the loop
}
for(i = 0; i < 26; i++)
{
if(arr[i] == ch)
{
ch = key[i];
}
}
string[k] = ch;
k++;
}
for(i = 0;i < k; i++)
{
cout << string[i];
}
getch();
return 0;
}
Here the problem is probably the fact that getche() (unlike getchar()) just returns the first character when there are more then one inputed and you are on windows (othewise you wouldn't use cls) then the EOL is encoded with \r\n.
What happens is that getche() returns \r so your break is never actually executed. You should change it to getchar() even because getche is a non standard function.
You can even try to look for \r instead that \n in your situation but I guess the \n would remain in the buffer causing problems if you need to fetch any additional input later (not sure about it).
Relying on old C libraries in C++ is yucky. Consider this alternative:
#include <iostream>
#include <string>
using namespace std; // haters gonna hate
char transform(char c) // replace with whatever you have
{
if (c >= 'a' && c <= 'z') return ((c - 'a') + 13) % 26 + 'a';
else if (c >= 'A' && c <= 'Z') return ((c - 'A') + 13) % 26 + 'A';
else return c;
}
int main()
{
// system("cls"); // ideone doesn't like cls because it isnt windows
string outstring = "";
char ch;
cout << "Enter the plain text you want to encrypt: ";
while(1)
{
cin >> noskipws >> ch;
if(ch == '\n' || !cin) break;
cout << (int) ch << " ";
outstring.append(1, transform(ch));
}
cout << outstring << endl;
cin >> ch;
return 0;
}
I would do something like the fallowing which uses standard C++ I/O.
#include <iostream>
#include <string>
using namespace std;
// you will need to fill out this table.
char arr[] = {'Z', 'Y', 'X'};
char key[] = {'A', 'B', 'C'};
int main(int argc, _TCHAR* argv[])
{
string sInput;
char sOutput[128];
int k;
cout << "\n\nEnter the plain text you want to encrypt\n";
cin >> sInput;
for (k = 0; k < sInput.length(); k++) {
char ch = sInput[k];
for(int i = 0; i < sizeof(arr)/sizeof(arr[0]); i++)
{
if(arr[i] == ch)
{
ch = key[i];
break;
}
}
sOutput[k] = ch;
}
sOutput[k] = 0;
cout << sOutput;
cout << "\n\nPause. Enter junk and press Enter to complete.\n";
cin >> sOutput[0];
return 0;
}