Strange output on input to char* with different compiler - c++

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.

Related

string uppercasing adds junk to the end of char array

I am learning c++, I write some code to convert a string to uppercase and display it. I assign a string str with "asdf" and then create a char array pointer and allocate a length same as that of the string.
But after I assign indices of char array with uppercase chars when I try to display char array there are many junk characters appended to the end. Why does this happen as I have only allocated the char array with a size = "length of string" then how does char array have junk chars at the end even after the actual allocated size.
string str{ "asdf" };
char* str_c = new char[str.length()];
for (int i = 0; i < str.length(); i++) {
str_c[i] = toupper(str[i]);
}
cout << str_c; // displays ASDF²▌r┐│w²A∙
Your char array needs to be one character longer than the length of the string, for the null terminator
string str{ "asdf" };
char* str_c = new char[str.length() + 1];
for (int i = 0; i < str.length(); i++) {
str_c[i] = toupper(str[i]);
}
str_c[str.length()] = '\0';
cout << str_c; // displays ASDF
In C-style strings (char*) the length of the string is not stored in memory. Thus, it must use some other way to determine where the string ends. The way it does that is by assuming that the string is all the bytes until the byte that is equal to zero (so-called null-terminator).
Without explicitly allocating an extra byte for the null terminator, and setting it, your string continues with the garbage that happens to be after the bytes you have allocated until it encounters (accidentally) the nearest 0.

Why does this array of characters contain memory that is not populated?

I have an array of characters that consists of 5 spaces. I am trying to fill it with characters using a for loop. However, the array contains several spaces full of garbage when the loop is finished. In this example, it should produce an array that results as 'aaaaa', but it instead comes out looking something like 'aaaaaýýýý««««««««þîþîþ'. Why does this occur? How do I prevent the unused memory spaces from being included in the array?
char* array = new char[5];
for (int j = 0; j < 5; j++)
{
array[j] = 'a';
}
The array doesn't contain anything other than the 5 a characters you've put into it. Proof:
char* array = new char[5];
for (int j = 0; j < 5; j++)
{
array[j] = 'a';
}
for (int j = 0; j < 5; ++j)
{
std::cout << array[j];
}
However, my guess is that you were actually viewing the array value using an output like a string (or perhaps inside a debugger). Something like this:
std::cout << array;
In this case, the char* is treated as a NUL-terminated string. Which means it expects that all characters until a NUL-character are part of the string. Since your array doesn't have one, it's just outputting random memory following your array, until a NUL character is encountered.
If you want to treat your array like a string, you need extra space for the NUL terminator:
char* array = new char[6];
for (int j = 0; j < 5; j++)
{
array[j] = 'a';
}
array[5] = 0;
However, if you actually want a string, you should use std::string and not char *. C++ is not C.
Your array actually is "aaaaa", however it contains no terminating zero byte (ASCII NUL character), so the character string extends over whatever happens to reside in the memory just beyond the array's end.

C++ Assigning Output of For Loop to a Variable

I have a for loop that returns the user's input backwards. They enter a string, and the loop reverses it. Here's what it looks like:
string input; //what user enters
const char* cInput = input.c_str(); //input converted to const char*
for(int i = strlen(cInput) - 1; i >= 0; i--)
cout << input[i]; //Outputs the string reversed
Instead of having cout << input[i], how can I set input[i] as the value of a new string? Like I want to have a string called string inputReversed and set it equal to input[i].
In other words, if input == hello, and input[i] == olleh, I want to set inputReversed equal to olleh.
Is this doable? Thanks!
string inputReversed(input.rbegin(), input.rend());
Just declare the output string and append to it, either with += or the append member function:
string inputReversed;
for(int i = input.size() - 1; i >= 0; i--)
inputReversed += input[i]; // this
// inputReversed.append(input[i]); // and this both do the same thing
Note that you don't need c_str and strlen, you can simply use the size or length member function.
You can also make the code more readable by using std::reverse:
string inputReversed = input;
std::reverse(inputReversed.begin(), inputReversed.end());
Or std::reverse_copy, since you're making a copy of the original string anyway:
string inputReversed;
std::reverse_copy(input.begin(), input.end(), std::back_inserter(inputReversed));
If i understand what you are asking you want to have a variable to store the reversed string and output that?
If so you can just do this
string input, InputReversed;
//what user enters
const char* cInput = input.c_str(); //input converted to const char*
for(int i = strlen(cInput) - 1; i >= 0; i--){
InputReversed += input[i];
}
cout << InputReversed; //Outputs the string reversed
Going off of this thread may help you.
How do I concatenate const/literal strings in C?
It seems like what you want is to create a new string which at the end of the loop will contain the backwards input.
string input; //what user enters
const char* cInput = input.c_str(); //input converted to const char*
char inputReversed[len(input)];
for(int i = strlen(cInput) - 1; i >= 0; i--)
output = strcpy(output, input[i]); //Outputs the string reversed

Reverse char string with pointers

I need reverse my char string only with pointers. How can I do this? My code:
// this cannot be modified !!!
char s[10] = "abcde";
char *pS;
// my code
pS = new char;
int count = 5;
for (int i = 0; i < 10; i++)
{
if (s[i] != '\0') // not null
{
pS[count - 1] = s[i];
count--;
}
}
cout << "Reversed = " << pS;
Sometimes if works fine, I see only 5 chars, they are reversed. But sometimes I see some extra chars (looks like temp symbols). Where I miss something? Thank you!
your char array "s" contains 10 chars, but you only initialize the first 6 chars of that array with "abcde" and the \0 terminator.
When you loop over the complete array, you access not initialized chars.
I also see, that you try to write to memory, which you didn't allocate.
You only allocate memory for 1 char for you "pS" pointer, but you try to access it's memory like it is an array of chars in your for-loop.
Instead of using hardcoded:
int count = 5;
you also could use the string function strlen() to determine the length of the c-string.
Edited (untested code):
char s[10] = "abcde";
char pS[10];
for (int i = 0; i < strlen(s); i++)
{
if (s[i] == '\0') // not null
{
// stop loop, as soon as you reach the end of the original string
break;
}
pS[strlen(s) - 1 - i];
}
// now add the termination char \0 to your pS array
pS[strlen(s)] = '\0';
cout << "Reversed = " << pS;
Just giving you the hint how to reverse the string using pointers:
Take two pointers front and rear where front is pointing to first char of string and rear is pointing to last char of string.
Check if front is less than rear
If yes, swap the value of first and last character. If no , just print the string.
Increment front pointer and decrement rear pointer
Repeat from step 2.
After reading another book I fully understand pointers and how to correctly allocate memory. Here is my final code which correctly reverse array of char string (I don't need universal code, just working example + without std methods for reversing):
// not edited part - based on exercise (I mean I cannot change pS to char[5] etc.
char s[10] = "abcde";
char *pS;
pS = new char[strlen(s) + 1]; // allocate correct memory size based on string size
cout << "Size is " << sizeof(pS) << endl; // just for testing
int count = strlen(s); // for iteration
pS[count] = '\0'; // last symbol must be '\o' (thanks to Mr.Yellow)
for (int i = 0; i < 10; i++) // 10 because array of char still has 10 elements
{
if (s[i] != '\0') // looks like "not garbage memory"
{
count--;
pS[count] = s[i]; // set correct value
}
}
cout << "Reversed = " << pS << endl;
Thank you to all who helps me!

why puts() not printing anything

#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!