1

I have the trans function which uses a single parameter, has to be void, and returns through c the opposite case of a letter from a word input in main.

Example: input: dOgdoG output: DoGDOg 

The function does change the case, but i cant figure out a way to build the new word / replace the old one because i keep getting compiling errors regarding "const char" or "invalid conversions".

The following program gives error "invalid conversion from char to const char*

I only changed the type of the function for example purposes.

#include <iostream> #include <cstring> #include <fstream> using namespace std; char trans(char c) { if(c >= 'a' && c <= 'z') return c-32; else if(c >= 'A' && c <= 'Z') return c+32; } int main() { char s[101], s2[101] = ""; cin >> s; int i; for(i=0; i<strlen(s); i++) { strncat(s2, trans(s[i]), 1); } cout<<s2; return 0; } 

EDIT: I changed from the char function to a void function and removed the body of the for.

void trans(char c) { if(c >= 'a' && c <= 'z') c-=32; else if(c >= 'A' && c <= 'Z') c+=32; } int main() { char s[101], s2[101] = ""; cin >> s; int i; for(i=0; i<strlen(s); i++) { /// i dont know what to put here } cout<<s2; return 0; } 
5
  • 1
    Look up the toupper and tolower functions. Commented Dec 1, 2021 at 14:05
  • 1
    Don't mess around with strncat; you know that s2 is large enough to hold the result, because you wrote it that way. So just do it: s2[i] = trans(s[i]);. And don't forget the nul terminator; that comes after the last character, so looping up to strlen(s) won't reach it. Commented Dec 1, 2021 at 14:07
  • @PeteBecker: Or just make the changes to s directly. Commented Dec 1, 2021 at 14:08
  • @ScottHunter -- maybe, but the question asks about "build the new word / replace the old one", and the code in the quesiton builds the new word. Commented Dec 1, 2021 at 14:10
  • Having i<strlen(s) in the for loop probably means that your loop has O(N*N) time complexity, where N is the length of s, since strlen(s) itself has O(N) complexity, and the for loop itself runs N times. I'd recommend having the statement int len = strlen(s); before the loop, and then have i<len instead of i<strlen(s). (Take a look at joelonsoftware.com/2001/12/11/back-to-basics/.) Commented Dec 1, 2021 at 14:50

3 Answers 3

2

Don't reinvent the wheel. The standard library has functions to identify uppercase and lowercase letter, and to change case. Use them.

char trans(char ch) { unsigned char uch = ch; // unfortunately, character classification function require unsigned char if (std::isupper(uch)) return std::tolower(uch); else return std::toupper(uch); } 

You might be inclined to change that else branch to else if (std::islower(uch) return std::toupper(uch); else return uch;, but that's not necessary; std::toupper only changes lowercase letters to uppercase, so it won't affect characters that aren't lowercase.

Then, when you call it, just copy the result:

int i = 0; for ( ; i < strlen(s); ++i) s2[i] = tran(s[i]); s2[i] = '\0'; 

EDIT:

Since there seems to be a requirement to do things the hard way, let's change trans to match:

void trans(char& ch) { unsigned char uch = ch; // unfortunately, character classification function require unsigned char if (std::isupper(uch)) ch = std::tolower(uch); else ch = std::toupper(uch); } 

And now, you can just apply it in place:

for (int i = 0; i < strlen(s); ++i) trans(s[i]); 

I called this "the hard way" because with the original version of trans you can use it directly to modify the original string:

for (int i = 0; i < strlen(s); ++i) s[i] = trans(s[i]); 

and you can use it to copy the string:

for (int i = 0; i < strlen(s); ++i) s2[i] = trans(s[i]); // don't forget the terminating nul 

With pass by reference, you can only modify in place; copying requires an additional step:

strcpy(s2, s1); for (int i = 0; i < strlen(s); ++i) trans(s2[i]); 
Sign up to request clarification or add additional context in comments.

1 Comment

not trying to reinvent anything, i know those functions, but i need to do it the way i did, plus, i did mention the char function was for example purposes only, as i need to use a void function which is what i dont understand how to do I will edit the question to make it more obvious
1

strncat takes 2 strings and a number as parameters; your second argument is a char, not a string.

Comments

1

You can use std::transform with string utility functions like std::isupper, std::toupper and similarly for lowercase. Since, the question is tagged std::string is preferred over const char*1 for strings.

#include <string> #include <cctype> #include <iostream> #include <algorithm> char trans(unsigned char c){ if (std::isupper(c)) return std::tolower(c); else if (std::islower(c)) return std::toupper(c); else return c; } int main(){ std::string s = "dOgdoG12"; std::string out; out.resize(s.length()); std::transform(s.begin(), s.end(), out.begin(), trans); std::cout << out; // DoGDOg12 } 

Demo


1. SO post on char* vs std::string

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.