C++ "Same Letter" code doesn't work properly - c++

#include <iostream>
#include <string>
using namespace std;
static char sentence[100];
void sameletter(char sentence[100])
{
int meter=0;
char letter;
cout<<"Enter the letter you want to find in this sentence : ";
cin>>letter;
for(int i=0; sentence[i] != '\0'; i++)
{
if(sentence[i]==letter)
{
meter++;
}
}
cout<<letter<<" letter used "<<meter<<" time(s)."<<endl;
}
int main()
{
cout<<"Enter Sentence : ";
cin>>sentence[100];
gets(sentence);
sameletter(sentence);
}
This is code i wrote. But for some reason it never includes the first letter to the end result. For example lets say i write "We love stack overflow" and i wanted how many times this sentence has the letter "w" so i hit w and it only shows : "w letter used 1 many time(s)." instead of 2. other letters like "o" works perfectly so it's only a problem about the first letter :/ can someone help me about it ?
Thanks !

This line:
cin >> sentence[100];
will read a single character into the 100th index of sentence, which invokes underfined behavior.
Also, gets has been removed from c++, and you should no longer use it.
Instead, you should use getline:
int main()
{
std::cout<<"Enter Sentence : ";
std::getline(std::cin, sentence);
sameletter(sentence);
}
Also, avoid using namespace std;, it's bad practice.
There's no reason for sentence to be static, or global.
Also, you could just use std::string, instead of char arrays. It will make your life easier. e.g. your loop could be replaced by an algorithm:
int meter = std::count_if(sentence.begin(), sentence.end(),
[=] (unsigned char c) {
return std::tolower(c) == std::tolower(letter);
});

Related

C++ Cin input to array

I am a beginner in c++ and I want to enter a string as character by character into an array , so that I can implement a reverse function .. However unlike C when the enter is hit a '\n' is not insterted in the stream.. how can I stop data from being entered ?
my code is :
#include<iostream>
#include<array>
#define SIZE 100
using namespace std;
char *reverse(char *s)
{
array<char, SIZE>b;
int c=0;
for(int i =(SIZE-1);i>=0;i--){
b[i] = s[c];
c++;
}
return s;
}
int main()
{
cout<<"Please insert a string"<<endl;
char a[SIZE];
int i=0;
do{
cin>>a[i];
i++;
}while(a[i-1]!= '\0');
reverse(a);
return 0;
}
When you read character by character, it really reads characters, and newline is considered a white-space character.
Also the array will never be terminated as a C-style string, that's not how reading characters work. That means your loop condition is wrong.
To begin with I suggest you start using std::string for your strings. You can still read character by character. To continue you need to actually check what characters you read, and end reading once you read a newline.
Lastly, your reverse function does not work. First of all the loop itself is wrong, secondly you return the pointer to the original string, not the "reversed" array.
To help you with the reading it could be done something like
std::string str;
while (true)
{
char ch;
std::cin >> ch;
if (ch == '\n')
{
break; // End loop
}
str += ch; // Append character to string
}
Do note that not much of this is really needed as shown in the answer by Stack Danny. Even my code above could be simplified while still reading one character at a time.
Since you tagged your question as C++ (and not C) why not actually solve it with the modern C++ headers (that do exactly what you want, are tested, save and work really fast (rather than own functions))?
#include <string>
#include <algorithm>
#include <iostream>
int main(){
std::string str;
std::cout << "Enter a string: ";
std::getline(std::cin, str);
std::reverse(str.begin(), str.end());
std::cout << str << std::endl;
return 0;
}
output:
Enter a string: Hello Test 4321
1234 tseT olleH

Count letters in String without using strlen()

I created a program that the user enters a string. But i need to count how many letters are in the string. The problem is im not allowed to use the strlen()function. So i found some methods but they use pointers but im not allowed to use that yet as we havent learned it. Whats the best way to do this in a simple method? I also tried chars but i dont have luck with that either.
#include <iostream>
using namespace std;
string long;
string short;
int main()
{
cout << "Enter long string";
cin >> long;
cout << "Enter short string";
cin >> short;
return 0;
}
I need to get the length of long and short and print it.
I am trying to use it without doing strlen as asked in some previous questions.
Do you mean something like this?
//random string given
int length = 1;
while(some_string[length - 1] != '\0')
length++;
Or if you don't want to count the \0 character:
int length = 0;
while(some_string[length] != '\0')
length++;
You can count from the beginning and see until you reach the end character \0.
std::string foo = "hello";
int length = 0;
while (foo[++length] != '\0');
std::cout << length;
If you use standard cpp string object I think the best way to get length of your string is to use method:
long.size();
It gives you number of characters in string without end string character '\0'. To use it you must include string library :
#include <string>
If you decide to use char table you can try method from cin:
char long_[20];
cout << "Enter long string\n";
int l = cin.getline(long_,20).gcount();
cout << l << endl;
gcount()

c++ word count(as words we take every possible variable name)

I was asked to make a program that reads a cin could be text and then counts the words in it(i need to count as a word every name that can be accepted as a variable name ex _a,a1) my problem is that my code works for only one byte. if its more than one the sum is always 0.The only thing i think i can have wrong is that i didn't put the string into an array but a friend of mine told me i don't need to do so.below is my code:
#include<iostream>
#include<string>
#include<stdio.h>
using namespace std;
int main(){
int sum=0;
bool z= false; //z is just a switch to see if we are inside a word\n
string s;
cout<<"Insert text: ";
getline(cin,s); //here we get the string\n
int n=s.length()-1; //for some reason i==(s.length-1) put a warning$
for(int i=0;i==n;i++){ //here we check each byte to see what it contai$
cout<<s[i];
if(isalpha(s[i]) || s[i]=='_'){ //to enter a word we need a let$
z=true;
sum++;}
if(z==true){ // if we are in a word we can have numbers as w$
if(!isalnum(s[i]) && s[i]!='_'){
z=false;}} // exit the current word and go$
if(s[i]==EOF){ // the end\n
break;}}
cout<<"Number of words is: "<<sum<<endl; // the real end\n
return 0;
}
This is so much easier than the code you have provided. We can do this with the STL using an istream iterator. If you choose to use C++ and not C, then you should take advantage of the standard library.
#include <iostream>
#include <string>
#include <vector>
#include <iterator>
using namespace std;
int main(){
vector<string> words((istream_iterator<string>(cin)), istream_iterator<string>());
for(int i = 0; i < words.size(); i++)
cout << words[i] << '\n';
return 0;
}
Check your for loop.. it runs as long as the second statement is true.. when is it true that i==n? only at the very last byte.. change this to i<=n instead.
First of all you don't need dont use getline because it is insecure, use cin instead. Also you do not need the and use cin instead of getline. Also if getline is used with an array it could pose a serious problem and could be exploited via stack overflow. Sorry I cant help much what you were asking but I just wanted to give you a heads up.

String won't print

I've been doing programming challenges on coderbyte and while doing one, ran into an issue. I want to isolate a word from a string, do some checks on it and then move to another word. The code I'm going to post is supposed to take only the first word and print it out on the screen. When I run it, it doesn't print anything. I thought that maybe I did something wrong in the while loop so I did a simple test. Let's say my input is "This is a test sentence" and instead of word (in cout), I type word[0]. Then it prints "T" just fine. Can you find what the problem is?
#include <iostream>
#include <string>
using namespace std;
int Letters(string str) {
int i=0;
int len=str.length();
string word;
while(i<len){
if(isspace(str[i])){word[i]='\0'; break;}
word[i]=str[i];
i++;
}
cout<<word;
return 0;
}
int main() {
int test;
string str;
getline(cin, str);
test=Letters(str);
return 0;
}
string word;
is default constructed, which is empty initially. Inside while loop, you tried to do:
word[i] = str[i];
It means you tried to access memory that has not been allocated,resulting in undefined behavior.
Try:
word.append(str[i]);
You can use simpler way to get words from input in C++. It will help you to avoid errors in the future.
#include <iostream>
using namespace std;
int main()
{
string word;
while(cin >> word)
{
// "word" contains one word of input each time loop loops
cout << word << endl;
}
return 0;
}

std::getline does not work inside a for-loop

I'm trying to collect user's input in a string variable that accepts whitespaces for a specified amount of time.
Since the usual cin >> str doesn't accept whitespaces, so I'd go with std::getline from <string>
Here is my code:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
int n;
cin >> n;
for(int i = 0; i < n; i++)
{
string local;
getline(cin, local); // This simply does not work. Just skipped without a reason.
//............................
}
//............................
return 0;
}
Any idea?
You can see why this is failing if you output what you stored in local (which is a poor variable name, by the way :P):
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
int n;
cin >> n;
for(int i = 0; i < n; i++)
{
string local;
getline(cin, local);
std::cout << "> " << local << std::endl;
}
//............................
return 0;
}
You will see it prints a newline after > immediately after inputting your number. It then moves on to inputting the rest.
This is because getline is giving you the empty line left over from inputting your number. (It reads the number, but apparently doesn't remove the \n, so you're left with a blank line.) You need to get rid of any remaining whitespace first:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
int n;
cin >> n;
cin >> ws; // stream out any whitespace
for(int i = 0; i < n; i++)
{
string local;
getline(cin, local);
std::cout << "> " << local << std::endl;
}
//............................
return 0;
}
This the works as expected.
Off topic, perhaps it was only for the snippet at hand, but code tends to be more readable if you don't have using namespace std;. It defeats the purpose of namespaces. I suspect it was only for posting here, though.
Declare a character to get in the carriage return after you have typed in the number.char ws;int n;cin>>n;ws=cin.get();
This will solve the problem.
Using cin>>ws instead of ws=cin.get(),will make first character of your string to be in variable ws,instead of just clearing '\n'.
It's quite simple.
U jst need to put a cin.get() at the end of the loop.
Are you hitting enter? If not get line will return nothing, as it is waiting for end of line...
My guess is that you're not reading n correctly, so it's converting as zero. Since 0 is not less that 0, the loop never executes.
I'd add a bit of instrumentation:
int n;
cin >> n;
std::cerr << "n was read as: " << n << "\n"; // <- added instrumentation
for // ...
why this happens :
This happens because you have mixed cin and cin.getline.
when you enter a value using cin, cin not only captures the value, it also captures the newline. So when we enter 2, cin actually gets the string ā€œ2\nā€. It then extracts the 2 to variable, leaving the newline stuck in the input stream. Then, when getline() goes to read the input, it sees ā€œ\nā€ is already in the stream, and figures we must have entered an empty string! Definitely not what was intended.
old solution :
A good rule of thumb is that after reading a value with cin, remove the newline from the stream. This can be done using the following :
std::cin.ignore(32767, '\n'); // ignore up to 32767 characters until a \n is removed
A better solution :
use this whenever you use std::getline() to read strings
std::getline(std::cin >> std::ws, input); // ignore any leading whitespace characters
std::ws is a input manipulator which tell std::getline() to ignore any leading whitespace characters
source : learncpp website
goto section (Use std::getline() to input text)
hope this is helpful
Is n properly initialized from input?
You don't appear to be doing anything with getline. Is this what you want?
getline returns an istream reference. Does the fact that you're dropping it on the ground matter?
On which compiler did you try this? I tried on VC2008 and worked fine. If I compiled the same code on g++ (GCC) 3.4.2. It did not work properly. Below is the versions worked in both compilers. I dont't have the latest g++ compiler in my environment.
int n;
cin >> n;
string local;
getline(cin, local); // don't need this on VC2008. But need it on g++ 3.4.2.
for (int i = 0; i < n; i++)
{
getline(cin, local);
cout << local;
}
The important question is "what are you doing with the string that gives you the idea that the input was skipped?" Or, more accurately, "why do you think the input was skipped?"
If you're stepping through the debugger, did you compile with optimization (which is allowed to reorder instructions)? I don't think this is your problem, but it is a possibility.
I think it's more likely that the string is populated but it's not being handled correctly. For instance, if you want to pass the input to old C functions (eg., atoi()), you will need to extract the C style string (local.c_str()).
You can directly use getline function in string using delimiter as follows:
#include <iostream>
using namespace std;
int main()
{
string str;
getline(cin,str,'#');
getline(cin,str,'#');
}
you can input str as many times as you want but one condition applies here is you need to pass '#'(3rd argument) as delimiter i.e. string will accept input till '#' has been pressed regardless of newline character.
Before getline(cin, local), just add if(i == 0) { cin.ignore(); }. This will remove the last character (\n) from the string, which is causing this problem and its only needed for the first loop. Otherwise, it will remove last character from the string on every iteration. For example,
i = 0 -> string
i = 1 -> strin
i = 2 -> stri
and so on.
just use cin.sync() before the loop.
just add cin.ignore() before getline and it will do the work
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
int n;
cin >> n;
for(int i = 0; i < n; i++)
{
string local;
cin.ignore();
getline(cin, local);
}
return 0;
}