why puts() not printing anything - c++

#include<iostream>
//#include<stdio.h>
using namespace std;
int main()
{
char mystr[20],rev[20];
int i,c=0;
cout<<"Enter a String: ";
gets(mystr);
for (i=0;mystr[i]!='\0';i++);
for (int j=i;j>=0;j--)
{
rev[c]=mystr[j];
c++;
}
cout<<"Reverse is: ";
puts(rev);
return 0;
}
Why puts() not printing anything?
if i use for loop to print string rev output is correct but why puts is not giving correct output?

Because first symbol of rev is \0 after your reverse operation, and puts considers a string as a null-terminated. So, it sees that first byte is null and stops immediately.
You may modify your loops this way:
for (i = 0; mystr[i] != '\0'; i++);
rev[i] = '\0';
for (int j = i-1; j>=0; j--)
{
rev[c] = mystr[j];
c++;
}

One problem is that the rev array is a local and it is not initialized; this means the resulting string is not guaranteed to have the needed terminating \0.
You can fix that adding a rev[c]='\0' before calling puts.
Also you need to start from the character before the \0 in the input string, otherwise the output will start with a '\0' and the puts function will stop right there.

puts() writes the \0 (null) terminated string to the standard output (stdout) and appends a newline character ('\n'). As rev is having the \0 char at 0th position, puts() prints nothing.
you can use below code to revers a char array.
int lenth = strlen(mystr);
int pos = lenth-1; // one posation before \0 char
int i = 0
for (; i <= pos; i++)
{
rev[i] = mystr[pos-i];
}
rev[i] = '\0';
or
int lenth = strlen(mystr);
int start = 0;
int end = lenth-1; // one posation before \0 char
for (; start < end; start++, end--)
{
char t;
t = mystr[start];
mystr[start] = mystr[end];
mystr[end] = t;
}
Hope it helps!

Related

reverse string in c++ using char array

I tried to reverse a string using char array but in the output it prints some garbage value, I am unaware of that what is the cause plus it is only happening in large strings.
my code
string reverseWord(string str){
int j = 0, n=0;
n = str.length();
char t[n]={0};
for(int i=n-1;i>=0;i--)
{
t[j]=str[i];
j+=1;
}
return t;
}
input = APFGMRZXIFPSXKOQDRRQJBBZ
output = ZBBJQRRDQOKXSPFIXZRMGFPAB#
I want to know the reason behind # these two garbage values
Using online IDE of gfg.
C-style strings must be terminated by a null-character '\0'.
Instead of using Variable-Length Array, which is not in the standard C++, you should directly allocate string because you are returning that. (assuming that string here means std::string)
string reverseWord(string str){
int j = 0, n=0;
n = str.length();
string t(n); // allocate string instead of VLA
for(int i=n-1;i>=0;i--)
{
t[j]=str[i];
j+=1;
}
return t;
}

Can I store a string in character array but reverse order, such that 0(index) points to last character in string?

I started to learn to program and I'm trying to store a string into a character array but in reverse order, such that array index position 0(zero) points to the last character in the string. I tried using for loops in different terms but getting the desired output. I want to solve this problem in C++.
Here is the code that I'm stuck on,
#include <iostream>
using namespace std;
int main()
{
char str[maxn];
string entstr;
cin>>entstr;
int len = entstr.length();
cout<<len<<endl;
for(int i = 0 ; i < len ; i++) //this makes \n no sense//
for(int j = len-1 ; j >= 0 ; j--)
str[i] = entstr[j];
for(int i = len-1 ; i >= 0 ; i--)
cout<<"Straight for array "<<i<<" "<<str[i]<<endl;
return 0;
}
OUTPUT:
sachin
6
Straight for array 5 s
Straight for array 4 s
Straight for array 3 s
Straight for array 2 s
Straight for array 1 s
Straight for array 0 s
I guess you don't wanna use std::reverse mentioned in the comments because you want to practice your algorithmic skills.
You can help yourself with this short program. It uses std::malloc to allocate a char array of the size of the input string. Then, you just need to loop backward through the character of the string and store it into your array.
I recommend you to follow (write it down on a paper) the values of i and len-1-i inside the loop. It will help you to understand how index works.
#include <iostream>
using namespace std;
int main()
{
string entstr;
cin >> entstr;
int len = entstr.length();
char* charArray = (char*) malloc (len);
for(int i = 0; i < len; i++)
{
charArray[i] = entstr[len-1-i];
}
cout << "charArray contains: ";
for(int j = 0; j < len; j++)
{
cout << charArray[j];
}
return 0;
}
Good luck!
I don't think there is any use for two loops. Just start the string from the front and your array from len-1 (just the way you did in the for loop for printing). You can take whatever length you want your char array to be.
#include <iostream>
using namespace std;
int main()
{
char str[100]; //put whatever you want the length of the char array to be
string entstr;
cin>>entstr;
int len = entstr.length();
cout<<len<<endl;
for(int i = 0 ; i < len ; i++)
{
str[len-1-i]=entstr[i];
}
for(int i = len-1 ; i >= 0 ; i--)
cout<<"Straight for array "<<i<<" "<<str[i]<<endl;
return 0;
}
You can use two pointers too for the same i.e. one starting from the front and one from the end (if you get confused)
for(int i = 0, j=len-1 ; i < len ; i++, j--)
{
str[j]=entstr[i];
}

Trying to add digits times their index

I'm trying to add the digits times their index in order to create a hash, but this doesn't seem to give the correct output. Can anyone tell me what's wrong here?
int main(){
int i, hash=0, input;
char temp[30];
cin>>input;
itoa (input, temp, 10);
for(i=0; i<(sizeof(temp)/sizeof(*temp)); i++){
hash+=((temp[i])*i);
}
cout<<hash;
return 0;
}
It's because itoa() returns a C-String.
Every C-String is a buffer (just like temp[30]), but not every buffer is a C-String.
The C-String must contain characters from a list of valid things (alphanumerical + some symbols + etc) and MUST finish with the "string terminator" (the character '\0')
Your temp variable is not initialized (we could say it was born as a generic buffer, not a string yet), so after itoa() you will have your "number" converted to string (your buffer just became a C-String), but after the string terminator ('\0') you will have any trash, once you did not initialized it!
Your buffer will be like this:
temp[30] = { '1', '2', '3', '\0', ?, ?, ?, ..., ? }
The ?'s could be anything...
Because you loop over the whole buffer temp[30] you will be making a sum of different things all the time.
Solution 1: Initialize char temp[30] = { 0 } (a little stupid, but valid)
Solution 2: Loop up to the "length" of the C-String temp, instead of the whole buffer (this
one makes more sense!)
This this:
size_t length( strlen( temp ) );
for ( size_t i( 0 ); i < length; i++ )
{
hash += (int)i * temp[ i ];
}
Yes, you are hashing all the 30 bytes of temp[30] instead of hashing only the ascii representation of the integer number you are reading from stdin.
I think this is closer to what you want:
#include <iostream>
using namespace std;
int main() {
int hash = 0;
// Read input from stdin
std::string input;
std::cin >> input;
// Make sure it contains only numbers
if (input.find_first_not_of("0123456789") != std::string::npos) {
std::cout << "Input doesn't contain only digits" << std::endl;
return 1;
}
for (int i = 0; i < input.size(); i++) {
hash += (input[i] - '0') * i;
}
std::cout << hash << std::endl;
return 0;
}
That temp[] buffer is not completely filled by itoa(), so you will be hashing garbage if you loop over i=0 to (sizeof temp)-1. Try:
for (size_t i=0, n=strlen(temp); i<n; ++i)
{
hash += (int)i*temp[i];
}
You'll need <cstring> included to define strlen().
On second thought, the no-<cstring> approach is probably better:
for (int i=0; temp[i] != 0; ++i)
{
hash += i*temp[i];
}
That eliminates the (int) cast too.

I am getting a bunch of extra chars when i try to reverse a cstring in c++

The string entered by the user appears to be reversed but it is also followed by a bunch of garbage chars. Here is my reverse function:
void reverse(char str[])
{
char reversed[MAX_CHAR];
for(int i = 0; i < strlen(str); i++)
{
reversed[i] = str[strlen(str) - i - 1];
}
cout << reversed << endl;
}
You need to end your string with the NULL character '\0', ASCII value 0.
Try this:
void reverse(char str[]) {
char reversed[MAX_CHAR];
int len = strlen(str);
for(int i = 0; i < len; i++) {
reversed[i] = str[len - i - 1];
}
reversed[len] = '\0'; // Add this
cout << reversed << endl;
}
This is how C and C++ know where the end of the string is.
Read more about Null-terminated character sequences:
http://www.cplusplus.com/doc/tutorial/ntcs/
http://en.wikipedia.org/wiki/Null-terminated_string
you can solve this in 2 ways either by
a) initializing reversed array with null chars
char reversed[MAX_CHAR] = {0};
b) adding null character by end of the reversed string.
reversed[strlen(str)] = '\0';

Strange output on input to char* with different compiler

I have declared and initialized a string in char* like below:
int length;
cout<<"Enter string length: ";
cin>>length;
char* str = new char[length];
cout<<"Enter your string here:";
for(int i = 0;i < length;i++)
cin>>str[i];
cout<<str<<endl;
Compile using DevC++, it give me what I type there, but in Visual C++ it print out string with some random character at the end.For example; I type "hello" Visual C++ give me:"hello ^^&*(Y&".Can someone explain to me why does this happen ?
You're not null terminating the string. You need to assign a char array of length + 1 to allow room for the null character at the end of the string.
You're missing a null-terminator at the end of the string. I'm guessing non-VC++ compiler handles it somehow, but in VC++ you have to allocate length + 1 characters and then set last one to '\0'. Example:
char* str = new char[length + 1];
cout << "Enter your string here:";
for (int i = 0; i < length; i++)
cin >> str[i];
str[length] = '\0';
You're never terminating your string. Put str[length-1] = '\0';.
Or, better, you should allocate new char[length+1];.
IMHO...
Change this
for(int i = 0;i < length;i++)
cin>>str[i];
to
cin>>str;
No for loop required. You can read a string as a whole instead of char by char.
Alternately, if you want to read it char by char, you need a \0 to mark the end of the string because cout assumes that the string is terminated with a \0.
So essentially, you need
for(int i = 0;i < (length - 1);i++)
cin>>str[i];
str[i] = '\0'.
You read length -1 chars and the terminate it with \0.