Converting to uppercase in C++ - c++

Let's say you have:
const char * something = "m";
How would one make this uppercase, using toupper (or something else, if applicable)?
I want to use a char * instead of a string (I can use a string, but then I have to use str.c_str()).
So, how can I make char * something = "m"; contain "M"?

I find you choice of C strings disturbing.. but anyway.
You can't change a string literal (char *something). Try an array:
char something[] = "m";
something[0] = toupper(something[0]);
To change an entire string:
char something[] = "hello";
char *p = something;
while (*p) {
*p = toupper(*p);
p++;
}

As explained in the very famous C book - The C Programming Language by Kernighan & Ritchie in section 5.5 Character Pointers and Functions,
char amessage[] = "now is the time"; /* an array */
char *pmessage = "now is the time"; /* a pointer */
`amessage` is an array, just big enough to hold the
sequence of characters and `'\0'` that initializes it.
Individual characters within the array may be changed
but `amessage` will always refer to the same storage.
On the other hand, `pmessage` is a pointer, initialized
to point to a string constant; the pointer may subsequently
be modified to point elsewhere, but the result is undefined
if you try to modify the string contents.
OTOH, in C, to convert to upper case letters, you can use the following program as a reference.
#include <stdio.h>
#include <ctype.h>
int main(void)
{
int i=0;
char str[]="Test String.\n";
char c;
while (str[i]) {
c=str[i];
putchar(toupper(c));
i++;
}
return 0;
}
In C++
#include <iostream>
#include <string>
#include <locale>
using namespace std;
int main ()
{
locale loc;
string str="Test String.\n";
for (size_t i=0; i<str.length(); ++i)
cout << toupper(str[i],loc);
return 0;
}
EDIT: Adding pointer version (as requested by #John) for the C version
#include <stdio.h>
#include <ctype.h>
int main(void)
{
int i=0;
char str[]="Test String.\n";
char *ptr = str;
while (*ptr) {
putchar(toupper(*ptr));
ptr++;
}
return 0;
}
Hope it helps!

You can use the same algorithmic approach that you know for std::string for raw arrays:
char s[] = "hello world";
std::transform(s, s + std::strlen(s), s, static_cast<int(*)(int)>(std::toupper));
You cannot do this for immutable string literals (like const char * s = "hello world;") for obvious reasons, so you won't get around an additional allocation/copy for that.
Update: As Ildjarn says in the comment, it's important to note that string literals are always read-only, even though for historical reasons you are allowed to bind them to a pointer-to-mutable, like char * s = "hello world";. Any decent C++ compiler should slap you in the face if you attempt this, but it is valid C++ -- but any attempt to actually modify any element of s is undefined behaviour.

You can convert C-string to std::string and then use boost::to_upper to change string in place or boost::to_upper_copy to create upper case copy of the string. Here is the code example:
#include <iostream>
#include <boost/algorithm/string/case_conv.hpp>
int main ()
{
char const * s = "Test String.\n";
std::string str(s);
std::cout << boost::to_upper_copy(str).c_str() << std::endl;
return 0;
}
Hope this helps.

You could do:
#include <algorithm>
#include <iterator>
#include <ctype.h>
char test[] = "m";
std::transform(std::begin(test), std::end(test), std::begin(test), ::topper);
This applies the ::toupper function to character of the string. This is the ::toupper function in the global namespace that comes from C. std::toupper has multiple overloads and ::toupper looks more elegant than static_cast<int (*)(int)>(&std::toupper).

Related

cpp function returning garbage string value [duplicate]

I'm a newbie in C++ learning the language and playing around. I wrote a piece of code which behavior I don't understand. Could someone explain why the code below prints out random junk and not the first character of the first string in the list (that is a).
#include <iostream>
#include <vector>
#include <string>
#include <cstdlib>
#include <ctime>
#include <climits>
#include <stdio.h>
char* str2char(std::string str)
{
char cset[str.size()+1]; // +1 for the null character
for(int i = 0; i < str.size(); i++)
{
cset[i] = str[i];
}
cset[str.size()] = '\0';
return cset;
}
int main (int argc, char * const argv[]) {
std::vector< std::string > ladontakadet;
ladontakadet.push_back("aabcbbca");
ladontakadet.push_back("abcdabcd");
ladontakadet.push_back("cbbdcdaa");
ladontakadet.push_back("aadcbdca");
ladontakadet.push_back("cccbaaab");
ladontakadet.push_back("dabccbaa");
ladontakadet.push_back("ccbdcbad");
ladontakadet.push_back("bdcbccad");
ladontakadet.push_back("ddcadccb");
ladontakadet.push_back("baccddaa");
std::string v = ladontakadet.at(0);
char *r;
r = str2char(v);
std::cout << r[0] << std::endl;
return 0;
}
Why is my returning garbage, when I'm expecting it to output a?
Thnx for any help!
P.S. The output of this code is random. It doesn't always print the same character..:S
It's because you return a pointer to a local variable, a local variable that goes out of scope when the function returns.
You are already using std::string for the argument, use it instead of the array and the return pointer.
If your aim is to pass the content of a std::string to a function modifying the content of a char*:
#include <iostream>
#include <vector>
void f(char* s) {
s[0] = 'H';
}
std::vector<char> to_vector(const std::string& s) {
return std::vector<char>(s.c_str(), s.c_str() + s.size() + 1);
}
int main(void)
{
std::string s = "_ello";
std::vector<char> t = to_vector(s);
f(t.data());
std::cout << t.data() << std::endl;
}
Your function is returning garbage because you're returning the address of a local variable which goes out of scope after your function returns. It should probably look like this:
char* str2char(const std::string &str)
{
char *const cset = new char[str.size() + 1]; // +1 for the null character
strcpy(cset, str.c_str());
return cset;
}
You will need to delete your variable r by doing delete[] r;. Ideally though you wouldn't be using raw pointers, and you would use std::string for everything, or wrap the char * in a std::unique_ptr.

Scanning ASCII value of each character of a string

Is there anyway , if I enter any string , then I want to scan ASCII value of each character inside that string , if I enter "john" then I should get 4 variables getting ASCII value of each character, in C or C++
Given a string in C:
char s[] = "john";
or in C++:
std::string s = "john";
s[0] gives the numeric value of the first character, s[1] the second an so on.
If your computer uses an ASCII representation of characters (which it does, unless it's something very unusual), then these values are the ASCII codes. You can display these values numerically:
printf("%d", s[0]); // in C
std::cout << static_cast<int>(s[0]); // in C++
Being an integer type (char), you can also assign these values to variables and perform arithmetic on them, if that's what you want.
I'm not quite sure what you mean by "scan". If you're asking how to iterate over the string to process each character in turn, then in C it's:
for (char const * p = s; *p; ++p) {
// Do something with the character value *p
}
and in (modern) C++:
for (char c : s) {
// Do something with the character value c
}
If you're asking how to read the string as a line of input from the terminal, then in C it's
char s[SOME_SIZE_YOU_HOPE_IS_LARGE_ENOUGH];
fgets(s, sizeof s, stdin);
and in C++ it's
std::string s;
std::cin >> s; // if you want a single word
std::getline(std::cin, s); // if you want a whole line
If you mean something else by "scan", then please clarify.
You can simply get the ascii value of a char by casting it to type int:
char c = 'b';
int i = c; //i contains ascii value of char 'b'
Thus, in your example the code to get the ascii values of a string would look something like this:
#include <iostream>
#include <string>
using std::string;
using std::cout;
using std::endl;
int main()
{
string text = "John";
for (int i = 0; i < text.size(); i++)
{
cout << (int)text[i] << endl; //prints corresponding ascii values (one per line)
}
}
To get the corresponding char from an integer representing an entry in the ascii table, you just have to cast the int back to char again:
char c = (char)74 // c contains 'J'
The code given above was written in C++ but it basically works the same way in C (and many other languages as well I guess)
There is no way to turn a string of length 'x' into x variables. In C or C++ you can only declare a fixed number of variables. But probably you don't need to do what you are saying. Perhaps you just need an array, or most likely you just need a better way to solve whatever problem you are trying to solve. If you explain what the problem is in the first place, then I'm sure a better way can be explained.
Ya,I think there are some more better solutions are also available but this one also be helpful.
In C
#include <stdio.h>
#include <string.h>
#include <malloc.h>
int main(){
char s[]="abc";
int cnt=0;
while(1){
if(s[cnt++]==NULL)break;
}
int *a=(int *)malloc(sizeof(int)*cnt);
for(int i=0;i<cnt;i++)a[i]=s[i];
for(int i=0;i<cnt-1;i++)printf("%d\n",a[i]);
return 0;
}
In C++
#include <iostream>
#include <string>
using namespace std;
int main(){
string s="abc";
//int *a=new int[s.length()];
//for(int i=0;i<s.length();i++)a[i]=s[i];
for(int i=0;i<s.length();i++)
cout<<(int)s[i]<<endl;
return 0;
}
I hope this one will be helpful..
yeah it's very easy ..just a demo
int main()
{
char *s="hello";
while(*s!='\0')
{
printf("%c --> %d\n",*s,*s);
s++;
}
return 0;
}
But make sure your machine is supporting the ASCII value format.
In C every char has one integral value associted with it called ASCII.
Using %d format specifier you can directly print the ASCII of any char as above.
NOTE: It's better to get good book and practice this kind of program yourself.

How to convert string to char array in C++?

I would like to convert string to char array but not char*. I know how to convert string to char* (by using malloc or the way I posted it in my code) - but that's not what I want. I simply want to convert string to char[size] array. Is it possible?
#include <iostream>
#include <string>
#include <stdio.h>
using namespace std;
int main()
{
// char to string
char tab[4];
tab[0] = 'c';
tab[1] = 'a';
tab[2] = 't';
tab[3] = '\0';
string tmp(tab);
cout << tmp << "\n";
// string to char* - but thats not what I want
char *c = const_cast<char*>(tmp.c_str());
cout << c << "\n";
//string to char
char tab2[1024];
// ?
return 0;
}
Simplest way I can think of doing it is:
string temp = "cat";
char tab2[1024];
strcpy(tab2, temp.c_str());
For safety, you might prefer:
string temp = "cat";
char tab2[1024];
strncpy(tab2, temp.c_str(), sizeof(tab2));
tab2[sizeof(tab2) - 1] = 0;
or could be in this fashion:
string temp = "cat";
char * tab2 = new char [temp.length()+1];
strcpy (tab2, temp.c_str());
Ok, i am shocked that no one really gave a good answer, now my turn. There are two cases;
A constant char array is good enough for you so you go with,
const char *array = tmp.c_str();
Or you need to modify the char array so constant is not ok, then just go with this
char *array = &tmp[0];
Both of them are just assignment operations and most of the time that is just what you need, if you really need a new copy then follow other fellows answers.
str.copy(cstr, str.length()+1); // since C++11
cstr[str.copy(cstr, str.length())] = '\0'; // before C++11
cstr[str.copy(cstr, sizeof(cstr)-1)] = '\0'; // before C++11 (safe)
It's a better practice to avoid C in C++, so std::string::copy should be the choice instead of strcpy.
Easiest way to do it would be this
std::string myWord = "myWord";
char myArray[myWord.size()+1];//as 1 char space for null is also required
strcpy(myArray, myWord.c_str());
Just copy the string into the array with strcpy.
Try this way it should be work.
string line="hello world";
char * data = new char[line.size() + 1];
copy(line.begin(), line.end(), data);
data[line.size()] = '\0';
Try strcpy(), but as Fred said, this is C++, not C
You could use strcpy(), like so:
strcpy(tab2, tmp.c_str());
Watch out for buffer overflow.
If you don't know the size of the string beforehand, you can dynamically allocate an array:
auto tab2 = std::make_unique<char[]>(temp.size() + 1);
std::strcpy(tab2.get(), temp.c_str());
If you're using C++11 or above, I'd suggest using std::snprintf over std::strcpy or std::strncpy because of its safety (i.e., you determine how many characters can be written to your buffer) and because it null-terminates the string for you (so you don't have to worry about it). It would be like this:
#include <string>
#include <cstdio>
std::string tmp = "cat";
char tab2[1024];
std::snprintf(tab2, sizeof(tab2), "%s", tmp.c_str());
In C++17, you have this alternative:
#include <string>
#include <cstdio>
#include <iterator>
std::string tmp = "cat";
char tab2[1024];
std::snprintf(tab2, std::size(tab2), "%s", tmp.c_str());
Well I know this maybe rather dumb than and simple, but I think it should work:
string n;
cin>> n;
char b[200];
for (int i = 0; i < sizeof(n); i++)
{
b[i] = n[i];
cout<< b[i]<< " ";
}

Reversing a string, weird output c++

Okay, so I'm trying to reverse a C style string in C++ , and I'm coming upon some weird output. Perhaps someone can shed some light?
Here is my code:
int main(){
char str[] = "string";
int strSize = sizeof(str)/sizeof(char);
char str2[strSize];
int n = strSize-1;
int i =0;
while (&str+n >= &str){
str2[i] = *(str+n);
n--;
i++;
}
int str2size = sizeof(str)/sizeof(char);
int x;
for(x=0;x<str2size;x++){
cout << str2[x];
}
}
The basic idea here is just making a pointer point to the end of the string, and then reading it in backwards into a new array using pointer arithmetic.
In this particular case, I get an output of: " gnirts"
There is an annoying space at the beginning of any output which I'm assuming is the null character? But when I try to get rid of it by decrementing the strSize variable to exclude it, I end up with some other character on the opposite end of the string probably from another memory block.
Any ideas on how to avoid this? PS: (would you guys consider this a good idea of reversing a string?)
A valid string should be terminated by a null character. So you need to keep the null character in its original position (at the end of the string) and only reverse the non-null characters. So you would have something like this:
str2[strSize - 1] = str[strSize - 1]; // Copy the null at the end of the string
int n = strSize - 2; // Start from the penultimate character
There is an algorithm in the Standard Library to reverse a sequence. Why reinvent the wheel?
#include <algorithm>
#include <cstring>
#include <iostream>
int main()
{
char str[] = "string";
std::reverse(str, str + strlen(str)); // use the Standard Library
std::cout << str << '\n';
}
#ildjarn and #Blastfurnace have already given good ideas, but I think I'd take it a step further and use the iterators to construct the reversed string:
std::string input("string");
std::string reversed(input.rbegin(), input.rend());
std::cout << reversed;
I would let the C++ standard library do more of the work...
#include <cstddef>
#include <algorithm>
#include <iterator>
#include <iostream>
int main()
{
typedef std::reverse_iterator<char const*> riter_t;
char const str[] = "string";
std::size_t const strSize = sizeof(str);
char str2[strSize] = { };
std::copy(riter_t(str + strSize - 1), riter_t(str), str2);
std::cout << str2 << '\n';
}
while (&str+n >= &str){
This is nonsense, you want simply
while (n >= 0) {
and
str2[i] = *(str+n);
should be the much more readable
str2[i] = str[n];
Your while loop condition (&str+n >= &str) is equivalent to (n >= 0).
Your *(str+n) is equivalent to str[n] and I prefer the latter.
As HappyPixel said, your should start n at strSize-2, so the first character copied will be the last actual character of str, not the null termination character of str.
Then after you have copied all the regular characters in the loop, you need to add a null termination character at the end of the str2 using str2[strSize-1] = 0;.
Here is fixed, working code that outputs "gnirts":
#include <iostream>
using namespace std;
int main(int argc, char **argv){
char str[] = "string";
int strSize = sizeof(str)/sizeof(char);
char str2[strSize];
int n = strSize-2; // Start at last non-null character
int i = 0;
while (n >= 0){
str2[i] = str[n];
n--;
i++;
}
str2[strSize-1] = 0; // Add the null terminator.
int str2size = sizeof(str)/sizeof(char);
int x;
cout << str2;
}

Whats wrong with this c++ reverse string function

void reverse (char s[]){
int len = strlen(s);
int j = len - 1;
for (int i = 0; i < j; i++,j--){
cout << s[i];
char ch = s[i];
s[i] = s[j]; //error line - giving exception, cannot write to the memory
s[j] = ch;
}
}
I am using Visual Studion 2008 and i can't understand whats the problem here .. :s .. I am out of C++ practice :$ .
The problem is that it uses C-style strings instead of C++ style strings. In particular, you are apparently trying to write to a constant string literal:
char const* str = "I cannot be written to";
C++ allows to omit the const here for backwards compatibility but the literal is still constant.
Finally, C++ already has a reverse function:
#include <algorithm>
#include <iostream>
#include <string>
int main() {
std::string str = "Hello world";
std::reverse(str.begin(), str.end());
std::cout << str << std::endl;
}
I'd guess the problem is with how you're calling it, probably with a string literal, something like:
reverse("This is a string");
or:
char *string = "This is a string";
reverse(string);
or some other minor variation. In any case, you're trying to write to a string literal, which gives undefined behavior.
Since you're apparently using C++, I'd consider using an std::string instead:
void reverse(std::string &s) {
int j=s.length()-1;
for (int i=0; i<j; i++, j--) {
// ..
}
}
Are you calling this on a const char* or a string literal?
Are you trying to reverse
reverse("foo");
or
char *s = "foo";
reverse(s);
You'll need to create a new string from the non-writeable one and reverse that instead. You can use strdup.
char *s = strdup("foo");
reverse(s);
free(s, strlen(s));
Also note that your question is tagged c++, so you should probably be using std::string.