function not returning value I want - c++

I want to be able to to take the user input and assign the given letter a value. I think I got that part down, now the problem is returning the value.
#include <iostream>
#include <string>
using namespace std;
int ch2n(string word);
int main()
{
string inputWord;
cout << "Type Word: ";
cin >> inputWord;
cout << ch2n(inputWord);
}
int ch2n(string word)
{
int total = 0;
for(int i = 0;i != word.size(); i++)
{
if(word.find(i) == 'a' || word.find(i) == 'A')
{
total += 1;
}
}
return total;
}
when I declare the total to 0, the return is always 0, but when I don't declare it, I get a return value of 229.... etc random number.

I think word.find(i) is probably not what you want to call there. To access a specific character within the string, use square brackets, i.e.: word[i] instead of word.find(i).

If you don't initialize it (set its value), using it is undefined behaviour and can return any random value - including 0
types without constructor, like int will just allocate space and have an undefinedd value, generally based on whatever happens to be in that location from prior use.
word.find does not do what you think it does, it is searching for i in word
You want to just use word[] :
if(word[i] == 'a' || word[i] == 'A')
Also, you might want to put std::endl at the end of your cout lines

The reason your result is random if you don't declare it to be 0 is because c++, and c for that matter, do not initialize data. If you declare a variable, like total, the initial value is whatever happens to be in that place in memory. It could really be anything. Always initialize the value of a variable.
I think the reason you're not returning anything meaningful is because you're using find wrong. std::string::find does not return a boolean, if returns a position. Therefore, you want to check if against a string position which says "The character does not exist in this string." That is std::string::npos. So, you will want:
if(word.find('a') != string::npos || word.find('A') != string::npos){
total += 1;
}

Related

What's the difference between these two given examples

I'm a beginner in C++ and programming itself actually. I just want to ask, What's the difference between these 2 examples. What is the difference between "len = strlen(str1)-1" and "i = strlen(str1)-1"
Top part of the code will be like this:
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
char str1[20],str2[20];
int c, i ,j, len;
cout<<"Enter a word: ";
cin.getline(str1, 20);
Example 1:
//reverse
for (i = strlen(str1)-1, j = 0; i >= 0; i--, j++){
str2[j] = str1[i];
}
//compare string
c = strcmp(str1, str2);
/*This does not work because the value of 'c' will be -1 if the input
is "lol" which is palindrome*/
and Example 2:
//reverse
len = strlen(str1)-1;
for (i = len, j = 0; i >= 0; i--, j++){
str2[j] = str1[i];
}
//compare string
c = strcmp(str1, str2);
/*This does work in other hand, because of the variable "len"*/
the rest of the code will be like this
if(c == 0){
cout<<"It is a Palindrome";
}
//if the value of C is !=0
else{
cout<<"It is not a Palindrome";
}
}
Why is that? Thanks in advance for those who will answer. :)
Both examples are same except first uses an extra variable len.
This code is actually reversing the string. If str1 contains "123" then str2 will contain "321".
Function strlen(str1) returns the length of str1 but in C++ index of Arrays start from 0 that is why the last element index will be one less than length, hence strlen(str1) - 1.
UPDATE
Even with updated information the answer to first question remains same that both examples are same in nature. Difference in results is a mare co-incident due to a reason explained below.
char str1[20],str2[20];
This code creates two array of 20 char but not initialized. This means the initial values can be random.
Now when you call cin.getline(str1, 20); it not only writes the string you entered but adds a terminating '\0' character at the end of it. Our reversing logic only reverse the string but does not insert terminating '\0' at the end of str2 which means str2 is much longer (until it finds a '\0') than str1. Due to this they never compare correctly.
A simple solution to this issue can be zero-filling the arrays before using them and in C++ there is a simple way to do that:
char str1[20] = { 0 }, str2[20] = { 0 };
It is always a good practice to zero-fill your arrays if you are going to use then as strings.

Finding letters in a string while ignoring everything else

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.

Failed to generate executive file in Visual Studio Code 2019

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

C++ String as an array in function, keeps getting an error message

I have an assignment to create a simple string reader that asks user to enter a sentence, and fix the followings:
first, using function prototype of int splitSent(string sentence, string words[], int maxWords); where the function returns number of words in sentence, and 'maxWords'
if user's input starts with small letter, caplitalize it.
if user input contains the string, 'Computer Science', switch the strings to 'CS'
For the first task, I'm being forced NOT to use dynamic arrays, vectors, and any 'char' variable. Also, I must keep the given prototype.
I could definitely do it in main function using a single for-loop to figure out how many words are there, but the given task is driving me crazy with errors since I've never used string as array in function call, without using any char variable, vectors an so on.
In the code below I wrote, in the main function, do I have to calculate all the values in the main function before the function call to get it work? For now, it gives an error message saying
In function 'int main()':
[Error] expected primary-expression before ']' token
At global scope:
[Error] declaration of 'words' as array of references
[Error] expected ')' before ',' token
[Error] expected unqualified-id before 'int'
I got stuck here for many hours and there is nothing more I can get from googling anymore. Please advise.
#include <iostream>
#include <string>
using namespace std;
int splitSent(string sentence, string words[], int maxWords);
int main()
{
string sentence, words;
int maxWords;
cout << "Enter a sentence. (Maximum words allowed - 100)" << endl;
getline(cin, sentence);
splitSent(sentence, words[], maxWords);
return 0;
}
int splitSent(string sentence, string& words[], int& maxWords)
{
int temp = 0, count = 1;
for (int j = 0; j < sentence.length(); j++)
if (sentence[i] == ' ')
count++;
words[count];
maxWords == count;
for (int i = 0; i < sentence.length(); i++) {
if (sentence[i] == ' ')
temp++;
else if (sentence[i] != ' ')
words[temp] += sentence[i];
}
return (count);
}
There were some syntax errors and some logic problems.
I noticed you tried to pass words[] into the function.
It can be confusing when to use words and when to use words[].
When you are declaring it, use string words[], eg in the function definition's parameter list.
This is to tell the function what to expect.
When you pass it in, use words, because you're passing the entire thing.
Inside the function, use words[index] because you're referring to a specific element of the array.
You have to declare words as an array of string, not as a string.
You just pass the string array in directly, not by reference.
When you pass it directly, you're not passing a copy of the array, the compiler ensures the function has the address of the first element in the array, so there is no performance penalty and you are working on the original array - which is what you want.
Your function declaration at the top is different to the function definition further down.
They should both be the same - the declaration is the version you should use.
int splitSent(string sentence, string words[],int maxWords);
You wanted maxWords by reference but this shouldn't be modified in the function because it holds the size of the array.
It stops you from running past the end of the array.
Function splitSent ignores multiple spaces. It reads maxWords but doesn't update it.
It returns the actual number of words it finds.
This may be greater than maxWords but the words array is only written up to a length of maxWords.
// returns number of words in sentence
// updates words[], using `maxWords` to prevent writing past end of array
int splitSent(string sentence, string words[], int maxWords)
{
int word_index = 0;
int letter_count = 0;
//words[count]; // not sure what was intended by this statement
for (int i = 0; i<sentence.length(); i++) {
if (sentence[i] == ' ') {
// handles multiple spaces in a row
if (letter_count > 0) {
word_index++;
letter_count = 0;
}
}
else if (word_index < maxWords) { // check the word_index is within bounds of array
words[word_index] += sentence[i];
letter_count++;
}
}
if (letter_count > 0)
return (word_index + 1);
return (word_index);
}
int main( ) {
string sentence;
int const maxWords = 100; // constant integer, so compiler lets us use it to declare the size of the array
string words[maxWords]; // function expects an array of strings, so have to declare one
cout << "Enter a sentence. (Maximum words allowed - " << maxWords << ")" << endl;
getline(cin, sentence);
int wordCount = splitSent(sentence, words, maxWords);
return 0;
}

how do i save a string outside of for loop in C++

I am trying to write program that takes a string with symbols and numbers and only saves the alphabet, discarding everything else. I tried with a str.erase but I thought it was easier to use loop. Assuming everything is lower case,it works beautifully.copy_str should save the new string without the symbols, to see if it was done I displayed it. When it is inside the if-it shows correct string, but when I display it outside the for loop-nothing. :/
here is my code:
int main()
{
string str="am73$$ore r0ma!!!";
int size_str=str.size();
string copy_str;
for(int i=0;str[i]!='\0';i++)
{
if((str[i]>=97) && (str[i]<123))
{
copy_str[i]=str[i];
cout<<copy_str[i];
}
}
cout<<copy_str;
You should use isalpha, see here.
copy_str is uninitialized and you initialize only the positions where your if statement inside the loop is fulfilled. Add single chars using +=.
std::string src = "am73$$ore r0ma!!!";
std::string dst; // empty string
for ( size_t i = 0; i < src.size(); i++ )
{
if ( isalpha(src[i]) ){ dst += src[i]; }
}
std::cout << dst << std::endl;
The program is undefined since you're assigning to non-existent elements of an empty string.
Assigning to an element that doesn't exist does not make the string longer, it's invalid.
Since the program is undefined, anything can happen.
You can use push_back to expand the result:
if(str[i] >= 'a' && str[i] <= 'z')
{
copy_str.push_back(str[i]);
}
or +=:
if(str[i] >= 'a' && str[i] <= 'z')
{
copy_str += str[i];
}