I am new in C++.
I encountered in question to find the vowels(i.e. "a","e","i","o","u") in a sub string,
and then I was thinking about change the driver function to get user input.
Unfortunately, this code did not generate execution file in Visual Studio Code nor any error messages.
Any help would be highly appreciated.
FYI, the function code was from GeeksforGeeks.
Thanks!
#include <stdio.h>
#include <string>
using namespace std;
// return true if x is vowel
bool isVowel(char x){
// function to check if x is in vowel or not
return (x == 'a' || x == 'e' || x =='i' || x == 'o' || x=='u');
}
void(FindSubString(std::string str)){
set<char> hash; // to store vowel
// outer loop picks starting characters
// and inner loop picks for ending characters
int n = str.length();
for (int i =0; i<n; i++){
for (int j = i; j <n; j++){
// if current position is not vowel,
// then no more possible string starting from str[i]
if (isVowel(str[j])==false)
break;
// if vowel, insert into hash
hash.insert(str[j]);
//if all vowels are present in current substring
if (hash.size()==5)
cout << str.substr(i, j-i+1) << " ";
}
hash.clear();
}
int main()
{
string str = getstring("insert a string: %s\n", stdin);
FindSubString(str);
return 0;
}
}
So, as mentioned in the comments, there are a number of fatal compiler errors in your code (when I run it through Visual Studio's C++ compiler as is, I get 7 errors - so I'm not sure how you are seeing none).
First, you have a missing closing brace (}) at the end of that function (seemingly, it is after the body of main, instead). Moving the } from the very end of the code to its proper place at the end of the FindSubString function will fix that. (This may be a copy-paste error, or you may be trying to define main inside FindSubString, but that's not allowed in C++.)
Second, you have the wrong and missing header files. Generally, for C++ programs, you should use the <iostream> header rather than <stdio.h>. The latter is generally used for C programs; however, it can be used in C++, but you'll need <iostream> if you want to use std::cout and std::cin. (I'm not sure if this is part of the Standard, but many implementations automatically include stdio.h when you include iostream.) You also need to #include <set> to make use of the std::set container.
And, the last of the fatal errors is your call to getstring. This is not a standard library function. So, you can either define this yourself, or just use the code in the main function below:
int main()
{
string str;
cout << "insert a string: ";
cin >> str;
// string str = getstring("insert a string: %s\n", stdin);
FindSubString(str);
return 0;
}
There is also a 'peculiarity' (though not actually an error, as my first version of this answer suggested) in the way you define your FindSubString function, with the 'extra' (unneeded, and very confusing) set of parentheses. It should be just this:
void FindSubString(std::string str)
{
However, even with all these errors fixed, your code does not work! This is because of a flaw in your logic, in the inner for loop of your FindSubString function. As you have it, that loop will terminate (because of the break; statement) on the first occurrence of a non-vowel.
You should, instead, check if the test letter is a vowel, and insert into the hash set if so. I'm not entirely sure what your definition of a sub-string is, but this code does something approaching what I think you want (feel free to clarify your goal, or correct my assumption):
void FindSubString(std::string str)
{
set<char> hash; // to store vowel
int n = str.length();
for (int i = 0; i < n; i++) {
for (int j = i; j < n; j++) {
if (isVowel(str[j])) hash.insert(str[j]); // if vowel, insert into hash
//if all vowels are present in current substring
if (hash.size() == 5)
cout << str.substr(i, j - i + 1) << " ";
}
hash.clear();
}
}
The code shown will find all substrings containing the five vowels.
Sample input:
facetiously
Output:
facetiou facetious facetiousl facetiously acetiou acetious acetiousl acetiously
Related
So this is for some homework I am working on.
I've been working on this for days now. I need to print a letter triangle,
example
a
aa
aaa
to a file I create in the code. I have gotten the triangle part down using a for loop but cannot figure out how to get it into a file. here is what I have so far.
#include <iostream>
#include <fstream>
using namespace std;
char loop()
{ for (int i = 1; i <=15; i++){
for (int j = 1; j <= i; j++){
cout << "a";
}
cout << endl;
}
}
int main()
{
ofstream week2 ("week2assignment.txt");
if (week2.is_open()){
char result = loop();
{
week2 << loop() + "\n";
}
}
week2.close();
else cout << "file wasnt created";
return 0;
}
This is my first post on here and I am in my second week of learning C++ so any help would be appreciated immensely. Thank you all in advance.
You just need to replace cout with week2 everywhere, since cout is the terminal and week2 is your file.
Given the current structure of your code, where you write to cout in a function, you'll need to pass week2 as an argument to that function to use it there.
First of all, don't build a habit of using using namespace std
std::endl will put a linebreak, but it will also flush your stream. Put easily, outputting something is a really costly (=takes a long time) action in regard to other actions. To account for this, streams are buffered and once the buffer is full it will be flushed automatically. When you use std::endl the buffer might be flushed prematurely and this will tank performance. This is of course not really an issue in this small exercise, but I think it's still good to know. You can use \n instead. Although it might not look like it, it will provide a platform independend linebreak and should virtually always be used instead of std::endl.
Then consider what your function loop should do. Right now, you said it has return type char but it's not returning something. Therefore you should correct this and specify that this function is not returning anything, but just performing an action, hence return type void.
As suggested by John Zwinck, if you pass the stream as an argument, your function becomes more powerful and works with any kind of outgoing stream (i.e. std::ostream).
We can make the function even more generic, but I'll leave it to you to understand the code (if not, feel free to post a comment for clarification). Please note also, that loop is not a descriptive name. I have no idea what loop does. Always give your functions a name that makes it clear what they are doing.
#include <iostream>
#include <fstream>
void print_letter_triangle(std::ostream& out, char c = 'a', int count = 15)
{
for( int i = 0; i < count; i++ ){
for( int j = 0; j < i; j++ )
{
out << c;
}
out << '\n';
}
}
int main()
{
// for testing purposes
print_letter_triangle(std::cout);
print_letter_triangle(std::cout, 'b');
print_letter_triangle(std::cout, 'c', 7);
std::ofstream week2("week2assignment.txt");
if( week2.is_open() )
{
print_letter_triangle(week2);
week2.close();
}
else
{
std::cout << "Error: File wasn't created.\n";
}
return 0;
}
Lastly: Try to build an early habit of how you want to format your code, positions of curly braces, spaces around operators. Right now it was a little bit inconsistent (which might as well have been caused by putting it on StackOverflow).
There are a couple more nitpicks one can offer (for example, I changed the loop to start from 0 and used the < instead of the <= operator, you can convince yourself that this does not change the number of loop iterations. However, it is common in programming languages to start from 0 (as counter-intuitive as that might be at first). Finally, since negative counting values do not make sense in this loop, one might change int to unsigned int, but I felt that might have been a little too much. Feel free to do so on your own, if you wish).
I suggest you use this code:
#include <iostream>
#include <fstream>
using namespace std;
const char* loop()
{ for (int i = 1; i <=15; i++){
for (int j = 1; j <= i; j++){
return "a";
}
return "\n";
}
}
int main()
{
ofstream week2 ("week2assignment.txt");
week2 << loop() << "\n";
return 0;
}
You must return a value from your loop() function.
For my homework, part of what I need to do is take a phrase from the user, and from there take only the letters in the phrase, ignoring numbers, spaces, and special characters. Once I find letters in the string, I need to store them into a separate variable. However, I can't get that variable to store anything outside of the if statement that looks for letters.
#include<iostream>
#include<string>
using namespace std;
int main()
{
string line, temp;
cout << "Enter phrase to check: ";
getline(cin, line);
for(int i = 0; i < line.size(); i++)
{
if((line[i] > 64 && line[i] < 91) || (line[i] > 96 && line[i] < 123))
{
temp[i] = line[i];
}
}
cout << temp;
return 0;
}
When I run the program, temp outputs nothing. But I know the if statement is correctly finding letters, from making it print line[i] inside the if statement.
your temp variable is an empty string. temp[x] is telling the compiler to change the x-th character of that string(which doesn't make any sense, as the string doesn't have any characters!). You're lucky(or unlucky) that you aren't getting any Segmentation faults(crashes).
Just use the += operator:
temp += line[i];
Try
temp.push_back(line[i]);
It will work.
The way you're currently doing it (temp[i] = line[i];) means that each non special character in line will be placed at the same index in temp. This should usually fail since temp (a string) does not resize on indexing.
For changing the size of a string, there exists a function called string::push_back as detailed here.
Instead of indexing using temp[i], you would instead use temp.push_back(line[i]);
This function allows the string to resize itself to accommodate the new char if need be and won't throw a segmentation fault.
NB: std::string::push_back is designed to append a single char to a string. There exist multiple other ways of doing this, including Nikita Demodov's answer which shows the use of the += operator which is much more lenient and will allow appending of other strings etc. push_back is most common to the std::vector where it is used to append single items to the list.
Not a homework question.
I am self learning.
I have to remove consecutive characters in a string by recursion. However the program I made is not working for inputs containing duplicates. It is goining in infinite recursion and hence gives segmentation fault. However it is working for inputs which doesn't have consecutive duplicates in them. I have tried debugging in Eclipse Ide but things get weird when I debug. (I know how to debug) but I can't figure out the things are different when I debug and when I run. I will give you example after my code.
#include <iostream>
#include <cstring>
using namespace std;
void removeConsecutiveDuplicates(char *input) {
int l = strlen(input);
if(l == 0) {
return;
}
if(input[0] != input[1]) {
removeConsecutiveDuplicates(input+1);
return;
}
int i = 1;
for(; input[i] != '\0'; ++i) {
input[i-1] = input[i];
}
input[i] = '\0';
removeConsecutiveDuplicates(input);
}
int main(void) {
char ch[1000];
cin >> ch;
cout<<"The String Before Removing Duplicates : "<<ch<<endl;
removeConsecutiveDuplicates(ch);
cout<<"The String After Removing Duplicates : "<<ch<<endl;
return 0;
}
When I am debugging this code I and seeing the variable l value it is 16. This doesn't happen while running. What I am missing here?
This line :
input[i] = '\0';
doesn't do anything (input[i] already has that value, because that was the end condition for the loop). You then call the removeConsecutiveDuplicates function recursively, but the length of the string is still the same, so you'll keep making recursive calls until a stack overflow happens.
Instead, you need to make the string length smaller :
input[i - 1] = '\0';
to avoid this infinite recursion.
To pass your self-assigned homework problem :), explain why the following line never has any effect in your code:
input[i] = '\0';
In your function, change this:
input[i] = '\0';
to this:
input[i-1] = '\0';
since you have chopped away a character, thus you should decrease the size of your string.
Without that, you wouldn't reduce the size, thus looping over and over again the same size, without it changing, would result in an infinite loop (since the size wouldn't change).
I suggest you use an std::string next time, since this is C++.
Sorry for the title, but I really have no idea what the problem is. The code looks like that (here it has no sense, but in the bigger project is has, so please, do not ask "why do you want to do....")
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
string sort (string slowo){
string litery = slowo;
for (int i=0; i<litery.length()-1; i++)
for (int j=0; j<litery.length()-1; j++)
if (litery[j]>litery[j+1])
swap(litery[j], litery[j+1]); // (3)
return litery;
}
int main()
{
fstream wordlist;
wordlist.open("wordlist_test",ios::in);
vector<string> words;
while (!wordlist.eof()){ // (4)
bool ok = true;
string word;
getline(wordlist,word);
string sorted = sort(word);
if (ok){
cout<<word<<endl; // (1)
words.push_back(word);
}
}
for (int i = 0; i<words.size(); i++){
cout<<words[i]<<endl; // (2)
}
}
There are for words in file "wordlist_tests". Program at the end should just write them to vector and write what's in vector into standard output. The problem is:
however line(1) proves that all words are ok
vector appears to be
empty in line (2)
now iteresting (probably just for me) part:
there are two ways to make it right:
I can just remove line(3) (however, if I am right, as the variable is passed to sort function through the value, it just swap two letters in independent variable; it has nothing to do with my vector), or:
I can change condition in while loop (4).
for example just like this:
int tmp = 0;
while (tmp < 5){
tmp++;
/..../
What is wrong with this code? What should I do write these words down to vector but still sort them and using this while loop? I cannot find the connection between this things (ok, I see that connection is variable word, but I do not know in what way). Any help appreciate.
What happens in swap() if one of the words is the empty sting ""?
If this happens, litery = "".
The condition in the loops will be to iterate from 0 to (unsigned) 0 - 1, which is a very large number.
You'll then execute if (litery[0] > litery[1])
litery[1] will access beyond the end of the empty string, which causes undefined behavior.
Let's fix this:
The common fix for this, is to iterate from 1 to string.length(). Here's an example:
string sort (string litery){
for (int i=1; i<litery.length(); i++)
for (int j=1; j<litery.length(); j++)
if (litery[j-1]>litery[j])
swap(litery[j-1], litery[j]);
return litery;
}
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