Cout giving garbage output when looping through a const char - c++

When executing the following code I get what I expect plus some unexpected output:
#include <iostream>
using std::cout;
using std::endl;
int main()
{
const char ca[] = {'h', 'e', 'l', 'l', 'o'};
const char *cp = ca;
while (*cp)
{
cout << *cp << endl;
++cp;
}
}
Output:
h
e
l
l
o
ⁿ
■
m
What are the last remaining characters? Is there something in the const char array that is not being accounted for?

while (*cp)
This loop ends when cp points to a null character.
const char ca[] = {'h', 'e', 'l', 'l', 'o'};
The array does not contain the null character.
Therefore the loop iterates over the array, and outside of its bounds. The behaviour of accessing an array outside of its bounds is undefined.

The while loops until *cp equal 0.
This fix:
#include <iostream>
using std::cout;
using std::endl;
int main()
{
const char ca[] = { 'h', 'e', 'l', 'l', 'o', '\0' }; // <-- add '\0'
const char* cp = ca;
while (*cp) // loop until *cp equal '\0'
{
cout << *cp << endl;
++cp;
}
}
Or this:
#include <iostream>
using std::cout;
using std::endl;
int main()
{
const char ca[] = { "hello" };
const char* cp = ca;
while (*cp)
{
cout << *cp << endl;
++cp;
}
}

Related

Output confusion

Shouldn't the output be: Heo Word? as it will print the letter as long as they aren't 'l', but the output I get is: eo World?
#include <iostream>
using namespace std;
int main() {
char str[] = "Hello World\n";
char* p = str;
while ( *p++ ) {
if ( *p != 'l' )
cout << *p;
}
}
The code in the while loop condition already increments the pointer value
while ( *p++ )
thus the check inside the loops scope
if ( *p != 'l' )
always misses the 1st character.
The easiest and most comprehensible way to rewrite this loop is probably
char str[] = "Hello World\n";
for (char*p = str; *p; ++p) {
if ( *p != 'l' )
cout << *p;
}
Working online example.

"in" list equivalent in c++ [duplicate]

This question already has answers here:
How to find out if an item is present in a std::vector?
(18 answers)
Closed 6 years ago.
Suppose I have a vector in c++ as v = ('a','e','i','o','u'). I want to check whether a string is a vowel or not by simply checking if the character is in the vector v or not. I don't want any code for that as I myself know that , I am looking for a function or a keyword in c++ which is equivalent of below in python :
list = ['a', 'e', 'i', 'o', 'u']
if str in list:
#do stuff
PS : Also let me know if nothing equivalent to this exists.
Useful Link:
find Algorithm
Example is
#include <iostream>
#include <algorithm>
#include <vector>
#include <iterator>
int main()
{
int n1 = 3;
int n2 = 5;
std::vector<int> v{0, 1, 2, 3, 4};
auto result1 = std::find(std::begin(v), std::end(v), n1);
auto result2 = std::find(std::begin(v), std::end(v), n2);
if (result1 != std::end(v)) {
std::cout << "v contains: " << n1 << '\n';
} else {
std::cout << "v does not contain: " << n1 << '\n';
}
if (result2 != std::end(v)) {
std::cout << "v contains: " << n2 << '\n';
} else {
std::cout << "v does not contain: " << n2 << '\n';
}
}
I would suggest a best way of doing it as :-
std::unordered_set<char> vowels = {'a', 'e', 'i', 'o', 'u'};
for ( auto c : str ) // str is string you want to search
{
if(vowels.find(c) != example.end()) {
std::cout << "We have string with vowels\n";
}
}
If you have a vector of items, see the question linked in the comments.
However, if you want to find a single character in a list of characters, it may be just as fast and simple to use an std::string and find or find_first_of:
std::string vowels = "aeiou";
char c = 'e';
bool isVowel = vowels.find_first_of(c) != std::string::npos;

How do I swap chars of a whole sentence with user input in C++?

I want to take input from user in
char input[200];
Then I want to swap each character of that input according to
a='y'; b='b'; c='j'; d='m'; e='x'; f='f'; g='w'; h='i';
i='v'; j='c'; k='l'; l='u'; m='t'; n='a'; o='k'; p='h';
q='d'; r='p'; s='s'; t='n'; u='z'; v='q'; w='e'; x='r';
y='o'; z='g';
For example if the input is
hello
The output will be
ixuuk
I want to code in C++ using for loops and arrays.
I suggest you use a lookup array:
char output = conversion[input_char];
You can simplify the array to 26 letters by using some arithmetic:
char output = conversion[input_char - 'a'];
The expression input_char - 'a' makes the letter a refer to the first slot in the conversion array.
Here's an example of the array:
static const char conversion[] =
{'b', 'y', 'c', 'k', 'f', /*...*/, 'a'};
Using the above code, if input is a, the output will be b. For input of b, the output will be y, and so on.
No need to swap. Remember that swapping changes values. I believe you want conversion or translation instead.
Here is a demonstrative program that shows how it could be done
#include <iostream>
#include <cstring>
#include <utility>
int main()
{
std::pair<const char *, const char *> cipher =
{
"abcdefghijklmnopqrstuvwxyz",
"ybjmxfwivclutakhdpsnzqerog"
};
const size_t N = 200;
char input[N];
input[0] = '\0';
std::cin.getline( input, sizeof( input ) );
std::cout << '\"' << input << '\"' << std::endl;
for ( char *p = input; *p; ++p )
{
if ( const char *q = std::strchr( cipher.first, *p ) )
{
*p = cipher.second[q - cipher.first];
}
}
std::cout << '\"' << input << '\"' << std::endl;
return 0;
}
The program output is
"Hello"
"Hxuuk"
You could also use functions tolower or toupper to convert initially characters of the source string to some case.
Solved the problem
#include <iostream>
#include <cstring>
#include <utility>
int main()
{
std::pair<const char *, const char *>
cipher ("abcdefghijklmnopqrstuvwxyz",
"ybjmxfwivclutakhdpsnzqerog");
const size_t N = 200;
char input[N];
input[0] = '\0';
std::cin.getline( input, sizeof( input ) );
std::cout << '\"' << input << '\"' << std::endl;
for ( char *p = input; *p; ++p )
{
if ( const char *q = std::strchr( cipher.first, *p ) )
{
*p = cipher.second[q - cipher.first];
}
}
std::cout << '\"' << input << '\"' << std::endl;
return 0;
}
Special thanks to #Vlad from Moscow
i suggest you use the nested loop.
create an array of strings having all the alphabets.
then create another array of strings having all the characters you want to change with the alphabets in the same order of the alphabets.
#include <iostream>
using namespace std;
int main()
{
string alphabets="abcdefghijklmnopqrstuvwxyz" ,
cipher="ybjmxfwivclutakhdpsnzqerog" , word , newword="" ;
cin>>word;
newword=word;
for(int i=0;i<26;i++)
{
for(int j=0;j<26;j++)
{
if(word[i]==alphabets[j])
{
newword[i]=cipher[j];
break;
}
}
}
cout<<newword;
return 0;
}

Copy and reverse char* in the C++

I would like to copy reversed char* to the another char*. I miss one letter in the second line of the output.
I did:
#include <iostream>
using namespace std;
void cp(char *str2, char *str1){
char *pom1 = str1;
while(*pom1){
pom1++;
}
char* pom2 = str2;
while(*pom1 != *str1){
pom1--;
*pom2 = *pom1;
pom2++;
}
*pom2 = '\0';
}
int main()
{
char *str1 = "ppC", str2[10] = "Witaj";
cout << "Napis str2 "<< str2 << endl;
cp(str2,str1);
cout << "Napis str2 "<< str2 << endl;
cp(str2,"CJP");
cout << "Napis str2 "<< str2 << endl;
return 0;
}
and the output is:
Napis str2 Witaj
Napis str2 Cp
Napis str2 PJC
While it should be:
Napis str2 Witaj
Napis str2 Cpp
Napis str2 PJC
The bug is in this statement of the function
while(*pom1 != *str1){
There must be
while( pom1 != str1){
Take into account that string literals have type of constant arrays. So for example variable str1 has to be declared as
const char *str1 = "ppC";
Also the function should be declared as
void cp( char *str2, const char *str1 );
Also It will be useful to know that there is standard algorithm std::reverse_copy declared in header <algorithm>:)
There's reverse_copy in the stdlib
... and that it's used like:
template <typename CharT, size_t Ndest>
void cp(CharT (&dest)[Ndest], CharT const *src){
auto f = src, l = src + std::strlen(src);
assert(std::distance(f,l) < Ndest);
*(std::reverse_copy(f, l, dest)) = '\0';
}
So, see it Live On Coliru
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cassert>
template <typename CharT, size_t Ndest>
void cp(CharT (&dest)[Ndest], CharT const *src){
auto f = src, l = src + std::strlen(src);
assert(std::distance(f,l) < Ndest);
*(std::reverse_copy(f, l, dest)) = '\0';
}
#include <iostream>
int main()
{
char str1[] = "ppC";
char str2[10] = "Witaj";
std::cout << "Napis str2 "<< str2 << std::endl;
cp(str2, str1);
std::cout << "Napis str2 "<< str2 << std::endl;
cp(str2,"CJP");
std::cout << "Napis str2 "<< str2 << std::endl;
return 0;
}
Just use the Standard Library, std::reverse_copy() in this case:
std::reverse_copy( input , input + strlen( input ) , output );
copy paste solution
int len(const char *p) {
int c = 0;
while (*p != '\0')
{
c++;
p++;
}
return(c);
}
void cp(char *str2, const char *str1){
if(!(len(str2)<len(str1))){
const char *pom1 = str1;
while(*pom1){
pom1++;
}
char* pom2 = str2;
while( pom1 != str1){
pom1--;
*pom2 = *pom1;
pom2++;
}
*pom2 = '\0';
}
}

Unexpected output when I try to reverse a char*

#include<iostream>
#include<string>
using namespace std;
void reverse(char* str)
{
char *new_str = str;
while(*new_str != '\n'){
new_str++;
}
while(new_str != str){
cout << *new_str;
new_str--;
}
cout << *new_str;
}
int main()
{
char *str = new char[1024];
str = "hello world";
reverse(str);
}
When I try to run this I get some crazy output and my computer starts to beep. What am I doing blatantly wrong here?
The end of a C string is marked by the character '\0'. You used '\n' which is the newline character.
You mean apart from using the naked leaky new, the deprecated char* instead of const char* or even better std::string, not using a Standard Library algorithm std::reverse, mixing IO with your algorithm and including the entire namespace std (which might indirectly bring std::reverse() into scope) without putting your own reverse() inside its own namespace?
#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
// using namespace std; // for the brave, and drop the std:: in the next 3 lines
int main()
{
std::string str = "hello world"; // std::string instead of char*
std::reverse(begin(str), end(str)); // standard library algorithm
std::cout << str; // IO separate from algorithm
}
If you are only interested in how to code a reverse algorithm, here is one way to do it without relying on the fact that you have a null terminator:
template<class BidirIt>
void reverse(BidirIt first, BidirIt last)
{
while ((first != last) && (first != --last)) {
std::swap(*first++, *last);
}
}
The problem is that at first you assigned str the address of allocated memory and then reassigned it to point to string literal that has type const char[] in C++.
char *str = new char[1024];
str = "hello world";
This string literal has terminating zero char '\0'. It has no the new line char '\n'. So the function is invalid because it will try to access memory beyond the array searching the new line char.
The valid code could look the following way
#include <iostream>
using namespace std;
void reverse( const char* s )
{
const char *p = s;
while ( *p ) p++;
while ( p != s ) cout << *--p;
}
int main()
{
const char *s = "hello world";
reverse( s );
}
Or if you want to enter a string yourself interactively then main could look as
int main()
{
const size_t N = 1024;
char s[N];
cout << "Enter a statement: ";
cin.getline( s, N );
reverse( s );
}
correct your function :
void reverse(char* str)
{
char *new_str = str;
while(*new_str){ // use this instead of *new_ptr != '\n'
new_str++;
}
while(new_str != str){
cout << *new_str;
new_str--;
}
cout << *new_str;
}