Why is c++ treating the space bar as null ('\0')? - c++

my professor asked us to determine the number of vowels in userString without a call to the library.
I am using '\0' in a for loop to figure out when will the string the user input will come to an end because I don't know the exact size they are going to input for the string. I am a beginner programmer so please don't give me complcated answer! thanks.
I have for(int i = 0; userString[i] != '\0'; i++)
but the program is treating the space bar as a null character too so
I get a problem in the output,
if I have a space in the commend line is treats it as a null and terminates the proram
loop at the pictue of the 2 different outputs for refrence.
As you can see in output 1
When i have "MianJalal" I get 9 in the terminal but for
output 2 When I have "Mian Jalal" (with a space), it treats the space as null and gives me 4, I am aware that '\0' is space in the special chartacer in c++ but it's also null, how can I tell the program i mean null not space?
this is my code,
#include <iostream>
using namespace std;
int main()
{
int numOfVowels = 0;
int length = 0;
char userString[50]; // The string the user will input
cout << "Enter a sentence to find out how many vowels are in the sentence" << endl;
cin >> userString;
for(int i = 0; userString[i] != '\0'; i++) // '\0' means null in a string in c++; if a user doesn't use a index in a char string
{ // the program will know it's a null in syntax '\0'
if(userString[i] == 'A' or userString [i] == 'a' or userString[i] == 'i')
{
numOfVowels++;
}
length++;
}
cout << length << endl;
return 0;
}

The problem is that the operator >> uses the space as a delimiter. So when reading userString it stops at the first space. To avoid this a method could be to use istream::getline (char* s, streamsize n ) function, that reads the entire line up to the '\n' character, or the supplied size limit.
#include <iostream>
using namespace std;
int main()
{
int numOfVowels = 0;
int length = 0;
char userString[50]; // The string the user will input
cout << "Enter a sentence to find out how many vowels are in the sentence" << endl;
cin.getline(userString, sizeof(userString));
for(int i = 0; userString[i] != '\0'; i++) // '\0' means null in a string in c++; if a user doesn't use a index in a char string
{ // the program will know it's a null in syntax '\0'
if(userString[i] == 'A' or userString [i] == 'a' or userString[i] == 'i')
{
numOfVowels++;
}
length++;
}
cout << length << endl;
return 0;
}

Related

Code outputs random symbols, i'm unsure what is wrong

I've made a program that shortens full names to initials, and removes any spaces between what has been entered. It did work before but now it prints the initials but also random symbols? I can't really figure out why it's doing it. I'm new to programming also.
This is my code:
// This code removes the spaces from the inputted name
char *removeSpaces(char *str)
{
int i = 0, j = 0;
while (str[i])
{
if (str[i] != ' ')
str[j++] = str[i];
i++;
}
str[j] = '\0';
return str;
}
// This code takes the users name, and shortens (sh) it
int main(void) {
char str[100],sh[20];
int j=0;
cout<<"Enter Full Name :";
cin.getline(str,30);
for(int i=0;i<strlen(str);i++)
{
if(i==0){
sh[j]=str[i];
sh[++j]=' ';
}
else if(str[i]==' '){
sh[++j]=str[i+1];
sh[++j]=' ';
}
}
// This then takes the remove spaces code, and prints the initials with a new line
cout << removeSpaces(sh) <<endl;
cout << "\n" <<endl;
return 0;
}
Picture of the output
You are missing adding string terminator character ('\0') to string sh. Below is the program.
#include <stdio.h>
char *removeSpaces(char *str)
{
int i = 0, j = 0;
while (str[i])
{
if (str[i] != ' ')
str[j++] = str[i];
i++;
}
str[j] = '\0';
return str;
}
// This code takes the users name, and shortens (sh) it
int main(void) {
char str[100],sh[100];
int j=0;
cout<<"Enter Full Name :";
cin.getline(str,30);
for(int i=0;i<strlen(str);i++)
{
if(i==0){
sh[j]=str[i];
sh[++j]=' ';
}
else if(str[i]==' '){
sh[++j]=str[i+1];
sh[++j]=' ';
}
}
sh[j+1] = '\0';
// This then takes the remove spaces code, and prints the initials with a new line
cout << removeSpaces(sh) <<endl;
cout << "\n" <<endl;
return 0;
}
Enter Full Name :ra me ge
rmg
You have missed out a line (I guess) after the for loop in your main function, which means your string is potentially not null-terminated.
Using the same (correct) logic you have in your removeSpaces function, just add this line immediately after the for loop in main:
sh[++j] = '\0';
You don't terminate sh with \0 after you're done, yet removeSpaces() expects a null character at the end of the string. Because of this, removeSpaces() could go past your intended boundary.
Just add this line after your for in main():
sh[++j] = '\0\;
Word of warning: You should always make sure that j is < 20 (the size of sh) before you set it. Otherwise, you could go past the boundary of sh. That could also become a source of problems.

I need to return number of words in c sting after taking user input

I need to make a program that takes input from the user and then return the number of words entered to the string. I store user input in array char words[256]; I have a function called countWords. It loops though the array and if it encounters a space he counter is increased. if(words[i] == '\0') if the null character is reached the counter is stopped. It then return nSpaces + 1 to account for the first word.
But my output seems to produce the number of characters in the string instead. How can this be fixed.
#include <iostream>
#include <cstdlib>
using namespace std;
//Function Prototype
int countWords(char words[]);
int main(){
char words[256];
cout << "Enter a sentence: ";
cin.getline(words, 256);
int word_num = countWords(words);
cout << "The number of words in a string is: " << word_num << endl;
system("PAUSE");
return 0;
}
int countWords(char words[]){
int nSpaces = 0;
//unsigned int i = 0;
/*while(isspace(words[i])){
i++;
}*/
for (int i=0; i<256; i++){
if(isspace(words[i])){
nSpaces++;
// Skip over duplicate spaces & if a NULL character is found, we're at the end of the string
//while(isspace(words[i++]))
if(words[i] == '\0')
nSpaces--;
}
}
// The number of words = the number of spaces + 1
return nSpaces + 1;
}
The Output is:
Enter a sentence: Yury Stanev
The number of words in a string is: 7
You're not stopping the loop when you get to the null character. You're only testing for the null character inside the if(isspace(words[i])) block, but if the character is a space then it can't also be the null terminator. As a result, you're reading past the end of the input, and counting the spaces in the uninitialized part of the string.
int countWords(char words[]){
int nSpaces = 0;
for (int i=0; i<256 && words[i] != '\0'; i++){
if(isspace(words[i])){
nSpaces++;
}
}
// The number of words = the number of spaces + 1
return nSpaces + 1;
}
isspace counts new lines (\n), tabs (\t), \v, \f and \r.
Probably you want only white-spaces? Check for " " and "\t" only.

strspn Strange behavior under c++, why?

Here is a program I made:
#include <iostream>
#include <cstring>
using namespace std;
int main() {
char frase1 [100];
char frase2 [100];
cin >> frase1;
cin >> frase2;
char * parola1 = strtok (frase1, " .");
char * parola2 = strtok (frase2, " .");
int i;
i = strspn (parola1, parola2);
int j;
j = strspn (parola2, parola1);
cout << i << " " << j;
return 0;
}
It should ask for 2 sentences that will be stored into frase1 and frase2, then two tokenizers set two pointers to the first word of their respective array, then I should get back the values i and j, wich are ints given by the strspn function.
So when the terminal shows up should be able to put, for example, "veritas omnia vincit" and "vetirsa omnia vincit" and then get 7 7 as output.
Instead, I insert the first sentence and it returns the values of the strspn between the first and the second word of the first sentence (veritas, omnia).
This is an attempt at isolating a problem showing up in a bigger program wich I'll show you right away:
#include <iostream>
#include <cstring>
using namespace std;
void eliminaVocali (char [], char []);
int controlloAnagramma (char*, char []);
bool controlloParola (char[]);
int main() {
char frase [10];
cin >> frase;
cout << "yolo1";
char fraseCorretta [100];
cout << "yolo";
eliminaVocali(frase, fraseCorretta);
if (controlloParola(fraseCorretta)) cout << "TRUE!!";
else cout << "FALSE :(";
}
void eliminaVocali (char frase [], char fraseCorretta []){
int counter = 0;
for (int i = 0; i < 100; i++){
if (frase[i] != 'a' && frase[i] != 'e' && frase[i] != 'i' && frase[i] != 'o' && frase[i] != 'u'){
fraseCorretta[counter] = frase[i];
counter++;
}
}
}
bool controlloParola (char frase []){
char * parola = strtok (frase, " .");
if (controlloAnagramma (parola, frase) > 2) return true;
while (parola != NULL){
parola = strtok(NULL, " .");
if (controlloAnagramma (parola, frase) > 2) return true;
}
return false;
}
int controlloAnagramma (char * parola, char frase []){
int counter = 0;
char * check = new char [100];
check = frase;
char * parola2 = strtok (check, " .");
if (strlen(parola) == strlen(parola2) && strlen(parola) == strspn(parola, parola2) && strlen(parola) == strspn(parola2, parola)) counter++;
while (parola2 != NULL){
parola2 = strtok (NULL, " .");
if (strlen(parola) == strlen(parola2) && strlen(parola) == strspn(parola, parola2) && strlen(parola) == strspn(parola2, parola)) counter++;}
delete[] check;
return counter;
}
This program receive a sentence, delete all the vowels from it and then check if among the words newly formed there are 2 wich one is anagram of another.
eliminaVocali delete the vowels
controlloParola takes one word of the sentence at a given time and send it to controlloAnagramma
controlloAnagramma take the word and search into the whole sentence for an anagram
This program gives
1 [main] testingstuff 93304 cygwin_exception::open_stackdumpfile:
Dumping stack trace to testingstuff.exe.stackdump
Where testingstuff is the program name.
The problem should be into controlloAnagramma, where I use strlen and strspn.
Know fact that can be useful: Neither of the 2 yolo cout into the main is ever printed.
Please note this is a didactic program, I can only use c++ with <cstring>.
The question is, why does the strspn command behave this way? It should solve the big program. Thanks in advance.
EDIT:
cin >> frase1;
cin >> frase2;
Shoud be:
cin.getline(frase1, 100);
cin.getline(frase2, 100);
As #anton-savin pointed out.
Also
check = frase;
Should be
strcpy (check, frase);
Error persist anyway.
cin >> frase1;
cin >> frase2;
operator>> reads strings word by word, so frase1 becomes "veritas" and frase2 becomes "omnia". To read the input line by line use getline:
cin.getline(frase1, 100);
cin.getline(frase2, 100);

Reversing a String : Garbage Values

I have written a code to reverse a string
#include < iostream >
#include < cstring >
using namespace std;
string Reversal(char * s);
int main()
{
char str[25];
cout << "Enter a Name :";
cin.get(str, 25);
cout << "You have entered: " << str;
cout << "\nReversed : " << Reversal(str);
return 0;
}
string Reversal(char * s)
{
int count = strlen(s);
char temp[count];
for (int i = 0; i < count; i++)
{
temp[i] = * (s + (count - 1) - i);
}
return temp;
}
Have referred below link to make cin take whitespaces as input:
How to cin Space in c++?
But the output is showing a few junk characters ? Any suggestion why so?
When you implicitly construct a std::string from temp, the latter is expected to be NUL-terminated, which it isn't.
Change
return temp;
to
return std::string(temp, count);
This uses a different constructor, one that takes an explicit character count and doesn't expect temp to be NUL-terminated.
The last character in the temp array should be null-terminated. Make it 1 longer than the size of your input string. Make the last character the null character ('\0').
string Reversal(char *s)
{
int count=strlen(s);
char temp[count+1]; //make your array 1 more than the length of the input string
for (int i=0;i<count;i++)
{
temp[i]= *(s+(count-1)-i);
}
temp[count] = '\0'; //null-terminate your array so that the program knows when your string ends
return temp;
}
The null character specifies the end of the string. Usually it is a byte with all 0 bits. If you don't specify this as the last character of your temp array, the program will not know when is the end of your array of characters. It will keep including every character until it finds a '\0'.

c++ for loop is being skipped

What am I doing wrong with this small program.
I'm just starting to learn c++, and by all mean I can accept this as a moot question. I'm reading through the Prata c++ primer and it gave me a code example which takes a char array and uses strcmp() in a for loop which iterates sequentially through the ASCII code starting with '?' until a test char variable ==s a set value from another char.
Thinking I could outdo the book I tried to create a similar program which takes a char array and using a for loop will take a test char array and iterate through each value of the array until the two variables are equal.
I simplified the program to only take the first of each array in the for loop because I was experiencing a problem where the program seems to simply skip over the for loop and terminate.
Below are first the prata code snippet, followed by my piece of code. Any feedback (even abusive >_<) would be useful.
#include <iostream>
#include <cstring>
int main() {
using namespace std;
char word[5] = "?ate";
for (char ch = ‘a’; strcmp(word, "mate"); ch++) {
cout << word << endl;
word[0] = ch;
}
cout << "After loop ends, word is " << word << endl;
return 0;
}
My code (though maybe poorly done, I can accept that)
#include <iostream>
#include <cstring>
int main() {
using namespace std;
char word[5] = "word";
char test[5] = "????";
int j = 0;
int i = 0;
cout << "word is " << word << "\nTest is " << test << endl;
cout << word[0] << " " << test[0] << endl;
for (char temp = '?'; word[0] == test[0] || temp == 'z'; temp++) {
if ((word[i]) == (test[j])) {
test[j] = temp;
j++;
temp = '?';
}
test[j] = temp++;
cout << test << endl; //Added to see if the for loop runs through once,
//which is does not
}
return 0;
}
Your for loop never starts because your condition, shown here:
word[0] == test[0] || temp == 'z'
will always return false on its first pass. Since temp is initialized to '?' and word[0] (w) does not equal test[0] (?), your loop will never start.
Also, you've initialized temp to ? so, looking at an ascii chart, you'll see that there's a lot of non-alpha characters between ? and a lower case z.
Furthermore, within the for loop, you increment j (j++) but never touch i. Since you're reading chars from word with i as your index, test would end up being "wwww".
You seem to be confusing yourself so...
Lets break down what you're trying to do:
If you're iterating every character in a string, then checking each letter of the alphabet at that index, you're going to have two loops:
for(;;) {
for(;;) {
}
}
The first (iterating through each index in the string should end when the index reaches the end of the string (strings literals are terminated with a '\0'):
for(int i = 0; word[i] != '\0' && test[i] != '\0'; i++) {
for(;;) {
}
}
The second will check each letter of the alphabet (char temp = 'a' and temp++) against your given index in both word and test (word[i] != test[i];). If they're not equivalent, it will set the character of test at index i to temp until it finds the right letter. Putting it all together, you end up with this:
for(int i = 0; word[i] != '\0' && test[i] != '\0'; i++) {
for(char temp = 'a'; word[i] != test[i]; temp++) {
test[i] = temp;
}
}
Of course, if you were only going for results and not trying to teach yourself about loops and programming basics, this is all just a very roundabout way of simplay calling:
memcpy(temp, word, strlen(word));