why I am getting i at the end of char array? - c++

#include<iostream>
#include<string.h>
using namespace std;
int main() {
int n;
cin>>n;
char code[n];
cin.ignore();
cin.getline(code, n);
int j=0;
for(int i=0; i<n; i++) {
if((code[i]>='A' && code[i]<='Z') || (code[i]>='a' && code[i]<='z')) {
code[j] = code[i];
j++;
}
}
code[j] = '\0';
cout<<code;
return 0;
}
input :
10
Ajith##
Expected output :
Ajith
Acutal output I'm getting :
Ajithi
why I am getting i at end of array ?
I need to print only alphabets ignoring numbers and special symbols. please help me on this

You tell the program that the input will be ten characters, including null-terminator.
Then you input only seven characters. With the null-terminator that leaves two uninitialized elements of the array, and those two elements will have indeterminate values.
Your loop still uses all ten characters, and using indeterminate values in any way leads to undefined behavior.
What is likely happening is that there's some data after the null-terminator that your program believes is characters.
The solution is std::string and only iterating over the actual length of the string, copying to another std::string.

Related

I am writing a code for palindrome for integer, Why are my strings not comparing to be equal even when they are the same

1.Palindrome code using strings
#include<iostream>
using namespace std;
int main()
{
int t,n;
cin>>t;
while(t--)
{
cin>>n;
string num=to_string(n);
string rev;
//Reversed the string using for loop
for(int i=num.length();i>=0;i--)
{
rev+=num[i];
}
//Checking the strings if they are same
cout<<num<<" "<<rev<<endl;
if(num.compare(rev)==0)
cout<<"wins";
else
cout<<"loses";
}
return 0;
}
2.Output for n=101
101 101
loses
I tried to string method on a separate integer and compare it with other string and it worked.
I don't understand why is the compare method not returning 0.
You access num out of bounds since i = num.length() points at one character passed the last character in the string. It therefore access the terminating \0 character and that's the first character you'll copy and that's why the strings won't match.
Possible correction:
for(size_t i = num.length(); i--;) {
rev += num[i];
}
An alternative, less error prone, solution would be to create rev by using reverse iterators from num:
std::string rev(num.rbegin(), num.rend());

Number of substrings starting and ending with '1' [duplicate]

This question already has answers here:
Getline keeps on getting newline character. How can I avoid this?
(7 answers)
Closed 2 years ago.
I'm trying to find the number of substrings that start and end with '1' where input string are numbers like 1111, 10001 etc. Given code does not show correct output but if I replace getline with cin as the input method the code works fine. It also works if I skip input of n (n is the length of the string to be entered) and use i<str.length() in for loop. Why does this happen?
#include <iostream>
#include <string>
using namespace std;
int main(){
int n;
cin>>n;
string str;
getline(cin,str);
int c=0;
for(int i=0;i<n;i++)
if(str[i]=='1')
c++;
c=c*(c+1)/2;
cout<<c;
return 0;
}
This is because getline reads all characters after n until the end of the line including spaces. So the length of your str will be equal to n+1 because of the space in the beginning.
How to fix (for example): for(int i = 1; i < n + 1; i++)
Possible issues with the shared code are:
Collecting input in variable ‘n’ first and then assigning it to a string variable via getline() seems redundant. The expected work can be done with the usage of single getline() statement : “getline(cin,str);”
The usage of variable ‘n’ in the for loop: the variable ‘n’ is to get the length of the input string (so that the loop can compare all elements of the string with number ‘1’. as per the shared code you are trying to execute the for loop for ‘n’ numbers of time which I believe is not the expectation here.)
e.g: if the string input is “111”, then the loop will get executed for 111 times where it should run for 3 times (please correct if my understanding of the motive of the code is different here 😊)
Present loop condition check will surely give the “string subscript out of range” assertion failure.
int n;
cin >> n;
string str;
getline(cin, str);
int c = 0;
for (int i = 0; i < n; i++)
{ }
As per my understating , above code lines can be replaced by below chunk of code.
string str;
getline(cin, str);
int c = 0;
int n = str.size();
for (int i = 0; i < n; i++)
{}

string is not printing in c++ outside the a for loop

I've tried to separate A-Z character in a given string using c++ but the separated string is not printing in the output but if I shift the "cout" statement inside the for loop it printing the characters. I don't know why its happen. please let me know if I've done any mistake.
my code
#include<iostream>
using namespace std;
int main()
{
int t;
cin>>t; //number of test cases
while(t--)
{
string s,a,n;
int j=0,k=0;
char temp;
cin>>s; //getting string
for(int i=0; i<s.length(); i++)
{
if(s[i]>=65 && s[i]<=90) //checking for alphabets
{
a[j]=s[i];
j++;
cout<<a[j-1]<<endl;
}
else
{
n[k]=s[i];
k++;
cout<<n[k-1]<<endl;
}
}
cout<<endl<<a<<endl<<n; //this line is not printing
}
}
String a is empty after initialization (i.e. it has length 0). So you can't access/write any character using a[j], because this writes beyound the string's current bounds and yields undefined behaviour.
use...
a.push_back(s[i]);
to append a character at the end of the string.
Since a is empty at the beginning and, as other answer says, you are writing beyond the string's current bounds, you can resize it to the size of s by doing the following:
a.resize(s.size());
and, once you are done with the work, reduce its capacity to fit the actual size:
a.shrink_to_fit();
This way you won't have memory reallocations that you might have when using std::string::push_back.
Also, you can use isupper() function in your first if condition.
But first you have to initialize s[i] into char variable at first for loop and add #include<cctype> library. Like this:
char c = s[i];
if(isupper(c)){code}

Return value of function strlen()?

This is the definition of strlen i have goggled up.
strlen( ) function counts the number of characters in a given string and returns the integer value. It stops counting the character when null character is found.
Now according to me the strlen for "kshitij" should be = 7 i.e not including the null character because the function stops counting as and when it encounters the null character.
Therefore if I want to print the word "kshitij" and its reverse as many times as the letters in the word, then the correct code should be.
#include<iostream.h>
#include<stdio.h>
#include<conio.h>
#include<string.h>
int main()
{
char a[1000];
gets(a);
int len=strlen(a);
for(int i=0; i<= len ; i++)
{
for(int j=len ; j>=0; j--)
{
cout<<a[j];
}
cout<<" ";
}
getch();
return 0;
}
accordingly it provides the reasonably correct output.(Apart of spacing I don’t understand)
now I was curious to know what would it print if i did :
#include<iostream.h>
#include<stdio.h>
#include<conio.h>
#include<string.h>
int main()
{
char a[1000];
gets(a);
int len=strlen(a);
for(int i=0; i<= len ; i++)
{
for(int j=len -1 ; j>=0; j--)
{
cout<<a[j];
}
cout<<" ";
}
getch();
return 0;
}
which according to me should not produce the last letter which is "j" but what i see is that it produces the same output but 1 less spacing then before.
similarly i tried :
#include<iostream.h>
#include<stdio.h>
#include<conio.h>
#include<string.h>
int main()
{
char a[1000];
gets(a);
int len=strlen(a);
for(int i=0; i<= len - 1 ; i++)
{
for(int j=len ; j>=0; j--)
{
cout<<a[j];
}
cout<<" ";
}
getch();
return 0;
}
over here according to me the ouput should contain only " 7 - 1 = 6 " times the reverse string but the ouput almost the same.The -1 has no effect on the value of "len".
With all this on my plate , I feel that the strlen function must count the null character as well, wiz strlen (a)= 8 (including ‘\0’), but then I see only 7 outputs in the output window.
This leaves me wondering if the strlen function counts the null character as well or not, and if it does then it must show it as a space in the output window. I am unable to apprehend the complete concept, any help is appreciated?
I am new to programming please take it easy on me. Thanks :).
If you have a string with 7 characters, the array indexes of the printable characters go from 0 to 6, and strlen() will return 7. a[7] contains the null terminator character.
So if you start your loop from j = len, the first character it prints is the null character, then it will print the printable characters in the remaining iterations. If you start your loop from len-1, it will print only the printable characters.
The extra spacing you're seeing is that null character. On some operating systems, printing a null character has no visible effect, but on your system it apparently prints a space.
This
for(int i=0; i<= len ; i++)
with len == 7 will loop for 0, 1, 2, 3, 4, 5, 6, 7;
because the execution will happen as long as the condition i<= len is true.
It will stop executing when it that condition is not true anymore, which does not apply before i==8.
For i==8 no execution will occur, but for 1 through 7 and for 0, i.e. 8 times.
The idiom to make a loop with len executions is
for(int i=0; i< len ; i++)

Reason for this output?

I am trying to figure out the reason for false output. It works absolutely fine for all values from 0 to 10000 except for values ppp, pppp, qqq and qqqq. The output should be -3,-4,3 and 4 respectively. But on executing this code the output is -5,-5,5 and 6 respectively. Can anyone help me out in this ?
#include<iostream>
using namespace std;
int main()
{
string a;
int x=0;
cin>>a;
for(int i=0;i<10000;i++)
{
if(a[i]=='p')
x=x-1;
if(a[i]=='q')
x=x+1;
}
cout<<x<<endl;
return 0;
}
Thanks in advance.
Your code has undefined behavior unless you enter a string at least 10,000 characters long. The only element outside the string that you're allowed to access is a[a.size()], which returns a null character ('\0'). Anything beyond that is undefined.
Change your loop to:
size_t len = a.size();
for (int i = 0; i < len; i++)
so you don't go outside the string.