C++ Pointer Char - c++

I'm new to C++ and I'm now learning about pointers. I'm trying to understand this program:
#include <iostream>
int main() {
char *text = "hello world";
int i = 0;
while (*text) {
i++;
text++;
}
printf("Char num of <%s> = %d", text, i);
}
It outputs:
Char num of <> = 11
But why not this:
Char num of <hello world> = 11

As your increase text until it points to '\0',
the string printed is empty.

You changed the value of text before printing it out:
#include <iostream>
int main() {
// text starts pointing at the beginnin of "hello world"
char *text = "hello world"; // this should be const char*
int i = 0;
while (*text) {
i++;
// text moves forward one character each time in the loop
text++;
}
// now text is pointing to the end of the "hello world" text so nothing to print
printf("Char num of <%s> = %d", text, i);
}
The value of a char pointer (like text) is the location of the character that it is pointing to. If you increase text by one (using text++) then it points to the location of the next character.
Not sure why you #include <iostream> but use printf(). Typically in C++ code you would do this:
std::cout << "Char num of <" << text << "> = " << i << '\n';
A working example of what you are trying to do:
int main()
{
const char* text = "hello world"; // should be const char*
int length = 0;
for(const char* p = text; *p; ++p)
{
++length;
}
std::cout << "Char num of <" << text << "> = " << length << '\n';
}

First of all - don't use char-string in c++! Use std::string.
Your while loop continues until it reach zero which is the string termination, so %s is just an empty string. The '<' and '>' is still printed even if the string is empty.
Your text pointer start as the following chars:
'h','e','l','l','o',' ','w','o','r','l','d','\0'
After the first loop, text points to:
'e','l','l','o',' ','w','o','r','l','d','\0'
After second loop, text points to:
'l','l','o',' ','w','o','r','l','d','\0'
And so on.
The while-loop continues until text points to '\0' which is just an empty string, i.e. "".
Consequently %s doesn't print anything.
In c++ do:
int main() {
std::string text = "hello world";
cout << "Char num of <" << text << "> = " << text.size() << std::endl;
}

text is a pointer to a char. So when you increment the pointer you make it to point to the next element. The end of a string in C is delimited by the null character. So you are incrementing the pointer until it points to the null character. After that, when you call printf it doesn't print anything because it prints characters until reaches the null character but it is already at the null character.
This could be a quick fix:
#include <stdio.h>
int main() {
char *text = "hello world";
int i = 0;
while (*text) {
i++;
text++;
}
printf("Char num of <%s> = %d", text-i, i);
}

After the loop pointer text points to the terminating zero of the string literal because it is increased in the loop.
Also function printf is declared in header <cstdio> And string literals in C++ have types of constant arrays (Though in C they have types of non-constant arrays. Nevertheless in the both languages you may not change string literals)
You can rewrite the program either like
#include <cstdio>
int main() {
const char *text = "hello world";
int i = 0;
while ( text[i] ) ++i;
std::printf("Char num of <%s> = %d\n", text, i);
}
Or like
#include <cstdio>
int main() {
const char *text = "hello world";
int i = 0;
for ( const char *p = text; *p; ++p ) ++i;
std::printf("Char num of <%s> = %d\n", text, i);
}
Also it is better instead of C function printf to use standard C++ stream operators.
For example
#include <iostream>
int main() {
const char *text = "hello world";
size_t i = 0;
for ( const char *p = text; *p; ++p ) ++i;
std::cout << "Char num of <" << text << "> = " << i << std::endl;
}

Related

How to concatenate strings in an output function?

Some languages have easy ways of doing this, but my question revolves in C and C++.
I wanna do something like this in Java:
public class sandbox {
public static void main(String[] args) {
System.out.println("Thank" + " you!");
}
}
And transfer it in C:
#include <stdio.h>
int main() {
/* The easiest way is like this:
char *text1 = "Thank";
char *text2 = " you";
printf("%s%s\n", text1, text2);
*/
printf("Thank" + " you."); // What I really want to do
}
How do I concatenate strings in a language like this?
You use just nothing:
puts ("Thank" " you.");
Concatenating strings is not that easy in C unfortunately, here's how to do it most succinctly:
char *text1 = "Thank";
char *text2 = " you";
char *text_concat = malloc(strlen(text1) + strlen(text2) + 1);
assert(text_concat);
text_concat = strcpy(text_concat, text1);
text_concat = strcat(text_concat, text2);
printf("%s\n", text_concat);
free(text_concat);
What I have understood from your question, hope the below solution will answer your question.
#include <stdio.h>
int main() {
char s1[100] = "Thank ", s2[] = "You";
int length, j;
// store length of s1 in the length variable
length = 0;
while (s1[length] != '\0') {
++length;
}
// concatenate s2 to s1
for (j = 0; s2[j] != '\0'; ++j, ++length) {
s1[length] = s2[j];
}
// terminating the s1 string
s1[length] = '\0';
printf("After concatenation: %s",s1);
return 0;
}
In C++, you can easily concatenate two string it by adding two string with a + operator.
#include <iostream>
using namespace std;
int main()
{
string s1, s2, result;
cout << "Enter string s1: ";
cin>>s1;
cout << "Enter string s2: ";
cin>>s2;
result = s1 + s2;
cout << "After concatenation: = "<< result;
return 0;
}
This is a concatenation, but is a constant or compile time concatenation, you can't concatenate strings like that, but in case you need to split a string constant in multiple parts is ok:
...
printf("Thank" " you."); // What I really want to do
...
For dynamic, runtime concatenation you need strcat like
strcat(text1, text2);
First you must assure that you have enough memory in target string, see this link http://www.cplusplus.com/reference/cstring/strcat/
Ok, that was the C way, but C++ has STL with std::string
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str1 = "hello ", str2 = "world";
cout<< str1 + str2<< endl;
return 0;
}
It is not possible in C to do something like printf("Thank" + " you."); because C doesn't support Operator Overloading Unlike C++. You can refer Is it possible to overload operators in C?

How do I concatenate strings with chars in C++?

I've got a function which takes a string, let's call it
void print(std::string myString)
{
std::cout << myString;
}
I want to do something like
char myChar;
myChar = '{';
print("Error, unexpected char: " + myChar + "\n");
It doesn't work.
I tried something like
print(std::string("Error, unexpected char") + std::string(myChar) + std::string("\n) )
but then std::string(myChar) becomes whatever int the char represents, it's printed as an int and isn't printed as it's alphanumeric representation!
The function should be declared like:
void print( const std::string &myString)
{
std::cout << myString;
}
and called like:
print( std::string( "Error, unexpected char: " ) + myChar + "\n");
As for your comment:
as a follow up, would it have been possible to pass an anonymous
function returning a string as an argument to print()? Something like
print( {return "hello world";}
then you can do this as it is shown in the demonstration program:
#include <iostream>
#include <string>
void f( std::string h() )
{
std::cout << h() << '\n';
}
int main()
{
f( []()->std::string { return "Hello World!"; } );
return 0;
}
If you are using C++14, you can do this:
using namespace std::literals;
char myChar;
myChar = '{';
print("Error, unexpected char: "s + myChar + "\n"s);
You can convert any one and concat.
You can use str.c_str() to convert C++ string to C character array.
Or
Use std::string inbuilt constructor to convert C character array to C++ string.

difference between char and const char

# include <iostream>
# include <string.h>
using namespace std;
int main()
{
int a=10;
int b=20;
char op[10];
const char p='+';
cout<<"enter the operation"<<endl;
cin>>op;
if(!strcmp(op,p)==0)
{
cout<<a+b;
}
return 0;
}
compilation result
12 17 C:\Users\DELL\Documents\cac.cpp [Error] invalid conversion from 'char' to 'const char*' [-fpermissive]
I am a beginner. Please tell me what mistake have I done.
This isn't about the difference between char and const char, but between char [] and char.
strcmp expects two character arrays.
op is an array of (10) characters. Good: that's what strcmp expects.
p is a single character. Not good: strcmp needs a char array, and p isn't any kind of array, but a single character.
You can change p from a single char '+' to a char array "+", or compare only the 0th character of op, as suggested in a comment above.
there is no version of strcmp that takes a single character as a parameter but instead it takes two string and compares them.
if you want to compare a single char variable with a string you can compare it with the first element of string or with any other element:
#include <iostream>
#include <string>
int main()
{
char op[10] = "Hi";
const char p = '+';
// if( strcmp( op, p) ) // error cannot covert parameter 2 from char to const char*
// cout << "op and p are identic" << std::endl;
// else
// std::cout << "op and b are not identic" << std::endl;
if(op[0] == p)
std::cout << "op[0] and p are identic" << std::endl;
else
std::cout << "op[0] and p are not identic" << std::endl;
const char* const pStr = "Bye"; //constant pointer to constant character string: pStr cannot change neither the address nor the value in address
const char* const pStr2 = "bye"; // the same as above
// pStr++; //error
// pStr[0]++; // error
if( !strcmp( pStr, pStr2) )
std::cout << "pStr and pStr2 are identic" << std::endl;
else
std::cout << "pStr and pStr2 are Not identic" << std::endl;
return 0;
}

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;
}

Invalid Conversion Problem in C++

I have the following snippet:
string base= tag1[j];
That gives the invalid conversion error.
What's wrong with my code below? How can I overcome it.
Full code is here:
#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
#include <time.h>
using namespace std;
int main ( int arg_count, char *arg_vec[] ) {
if (arg_count < 3 ) {
cerr << "expected one argument" << endl;
return EXIT_FAILURE;
}
// Initialize Random Seed
srand (time(NULL));
string line;
string tag1 = arg_vec[1];
string tag2 = arg_vec[2];
double SubsRate = 0.003;
double nofTag = static_cast<double>(atoi(arg_vec[3]));
vector <string> DNA;
DNA.push_back("A");
DNA.push_back("C");
DNA.push_back("G");
DNA.push_back("T");
for (unsigned i=0; i < nofTag ; i++) {
int toSub = rand() % 1000 + 1;
if (toSub <= (SubsRate * 1000)) {
// Mutate
cout << toSub << " Sub" << endl;
int mutateNo = 0;
for (int j=0; j < tag1.size(); j++) {
mutateNo++;
string base = tag1[j]; // This fail
int dnaNo = rand() % 4;
if (mutateNo <= 3) {
// Mutation happen at most at 3 position
base = DNA[dnaNo];
}
cout << tag1[j] << " " << dnaNo << " " << base << endl;
//cout << base;
}
cout << endl;
}
else {
// Don't mutate
//cout << tag1 << endl;
}
}
return 0;
}
Why do I get an Invalid conversion from char to const char* when looping over a string?
The std::string operator [] returns a single char. string cannot be instantiated with a single char.
Use:
string base = string( 1, tag1[j] ) instead
Change it to
char base = tag1[j];
string tag1 = arg_vec[1];
tag1 is a string literal.
string base = tag1[j]; is initialized with a char instead of char *.
Try, char base = tag1[j];
There is no constructor for string that takes just a char (which is what tag1[j] is). You have a couple options:
string base; // construct a default string
base = tag1[j]; // set it to a char (there is an
// assignment from char to string,
// even if there's no constructor
or
string base( 1, tag1[j]); // create a string with a single char
Or as Josh mentioned, you can define base as a char since you're not performing any string operations on it anyway. If you decide to do this you'll need to change DNA to be a vector<char> (and change the initialization of DNA to using chars instead of strings).
One problem is that the error message says the program expects one argument when it actually requires two. You should probably follow the Unix conventions and show the required usage too (or instead):
if (arg_count != 3) {
cerr << "Usage: " << arg_vec[0] << " tag1 tag2";
return EXIT_FAILURE;
}
The names 'argc' and 'argv' are very conventional (and the only major alternative I've seen is 'ac' and 'av'). It might be worth sticking with that.