capitalizing characters, how toupper works? - c++

I need to use a character array and take the characters in the array and capitalize and lower case them as necessary. I was looking at the toupper and its example, but I'm confused about how this works. Looking from the example given on cplusplus.com I wrote
int main(){
int i = 0;
char str[] = "This is a test.";
while(str[i]){
putchar(toupper(str[i]));
i++;
}
for(int i = 0; i < 15; i++){
cout << str[i];
}
}
and there are two things I don't understand about this. The first is that without the cout at the bottom, the program prints out THIS IS A TEST. Does putchar print to the screen? (the use of putchar is not explained on the example). But my second more important question is why does the cout at the bottom still print out This is a test.? Does it not change the chars in str[]? Is there another way I should be doing this (keeping in mind I need to use character arrays)?

Yes, putchar() prints a character to the program's standard output. That is its purpose. It is the source of the uppercase output.
The cout at the bottom of the program prints the original string because you never modified it. The toupper() function doesn't -- indeed can't -- modify its argument. Instead, it returns the uppercased char.

putchar writes a single character to output: http://www.cplusplus.com/reference/cstdio/putchar/
As a result, the first while loop converts each character from str one at a time to upper case and outputs them. HOWEVER, it does not change the contents of str - this explains the lower case output from the second loop.
Edit:
I've expanded the first loop:
// Loop until we've reached the end of the string 'str'
while(str[i]){
// Convert str[i] to upper case, but then store that elsewhere. Do not modify str[i].
char upperChar = toupper(str[i]);
// Output our new character to the screen
putchar(upperChar);
i++;
}

Related

want to optimize this string manipulation program c++

I've just solve this problem:
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3139
Here's my solution:
https://ideone.com/pl8K3K
int main(void)
{
string s, sub;
int f,e,i;
while(getline(cin, s)){
f=s.find_first_of("[");
while(f< s.size()){
e= s.find_first_of("[]", f+1);
sub = s.substr(f, e-f);
s.erase(f,e-f);
s.insert(0, sub);
f=s.find_first_of("[", f+1);
}
for(i=0; i<s.size(); i++){
while((s[i]==']') || (s[i]=='[')) s.erase(s.begin()+i);
}
cout << s << endl;
}
return 0;
}
I get TLE ,and I wanna know which operation in my code costs too expensive and somehow optimize the code..
Thanks in advance..
If I am reading your problem correctly, you need to rethink your design. There is no need for functions to search, no need for erase, substr, etc.
First, don't think about the [ or ] characters right now. Start out with a blank string and add characters to it from the original string. That is the first thing that speeds up your code. A simple loop is what you should start out with.
Now, while looping, when you actually do encounter those special characters, all you need to do is change the "insertion point" in your output string to either the beginning of the string (in the case of [) or the end of the string (in the case of ]).
So the trick is to not only build a new string as you go along, but also change the point of insertion into the new string. Initially, the point of insertion is at the end of the string, but that will change if you encounter those special characters.
If you are not aware, you can build a string not by just using += or +, but also using the std::string::insert function.
So for example, you always build your output string this way:
out.insert(out.begin() + curInsertionPoint, original_text[i]);
curInsertionPoint++;
The out string is the string you're building, the original_text is the input that you were given. The curInsertionPoint will start out at 0, and will change if you encounter the [ or ] characters. The i is merely a loop index into the original string.
I won't post any more than this, but you should get the idea.

Why it works when I type multiple characters in a character variable?

I am a new C++ user.
My code is as following:
#include <iostream>
using namespace std;
int main()
{
int option = 1;
char abstract='a';
while(option == 1){
char temp;
cin>> temp;
abstract = temp;
cout << abstract;
option = 1;
if(abstract == '!'){
option = 0;
}
}
return 0;
}
And when I typed something like: abcdefg
all the characters are on the screen,why? It's just because of the compiler?
In fact, only one character at a time is stored in your char. cin>>temp; reads a single char at a time since more characters would not fit there. The loop simply reads and prints one character after the other.
As a visualization hint, try echoing your characters with cout<<abstract<<endl;. You will see a single character per line/iteration.
Your terminal does not restrict the number of characters typed in , that's why you can type as many as you want. Your c++ compiler would read only one of the characters because 'temp' is of type char. you can type an 'if' statement to check the number of characters typed in the terminal
Because of the while loop, which processes each character in turn. Not sure what you expected to happen.
Print it out with delimiters to see that there's never more than a single character printed per iteration:
cout << "'" << abstract << "'";
The terminal window itself is responsible for reading the characters and echoing them back to the screen. Your C++ program asks the terminal for characters and, in this sort of program at least, has no effect on how those characters are displayed.

C++: Checking whether a string character is a digit using isdigit. .

I am reading input for my program in a loop using getline.
string temp(STR_SIZE, ' ');
string str_num(STR_SIZE, ' ');
...
getline(cin, temp, '\n');
After which, I use a function to find the next delimiter(white space) and assign all the characters before the white space to str_num. Looks something like this:
str_num.assign(temp, 0, next_white_space(0));
I have verified that this works well. The next step in my solution would be to convert str_num to an int(this part also works well), but I should check to make sure each character in str_num is a digit. Here's the best of what I've tried:
if(!isdigit(str_num[0] - '0')) {
cout << "Error: Not an appropriate value\n";
break; /* Leave control structure */
}
For some reason, This always prints the error message and exits the structure.
Why is that?
I've used operator[] for string objects before, and it seemed to work well. But, here, it's totally messing me up.
Thanks.
std::isdigit takes a char's integer value and checks it.
So, remove the - '0' and just pass str_num[index] to isdigit().
Note: because this function comes from C, the old style of treating chars as integers shows through in the method taking an int. However, chars can promote to int values, so a char becomes an int just fine and this works.

ASCII and isalpha if statement issue

I am writing a program that takes a user inputted character, such as A, and a user inputted number, such as 7. The program checks the validity of the character, if true runs thru till it gets to this loop inside of a function. I am using ascii decimal for this loop inside of a function. This loop needs to check isalpha and if it is run the code inside the {}'s, it's doing that correctly. The else is not working the way I want and am not sure how to correct it. I need the else (is not alpha) to add a 1 back to the counter in the loop and increase the ascii by 1. If I run it as so, it gives off a retry/ignore/abort error. If I run it without the num++; it runs and stops after the loop ends. So, if you put in a Z and choose 3, it runs thru the loop 3 times and outputs just a Z. Any thoughts on how to fix this?
I need it to output something like: Input: Z Input: 4 it should output: Z A B C to the screen. It needs to ignore other ascii non alpha characters.
Thanks
string buildSeries(char A, int num)
{
//builds the output with the info the
//user inputted
stringstream str1;
string outted;
int DeC=(int)A, i = 0;
//loop builds the output
for(i=0;i<num;i++)
{
if (isalpha(DeC))
{
//converts the decimal to a letter
str1<<(char)DeC;
//adds a space
str1<<" ";
//increases the decimal
DeC++;
}
else
{
num++;
DeC++;
}
}
//builds the sstream and puts it in
//variable "outted"
outted = str1.str();
return outted;
}
If you need to loop back to 'A' at Z change your DeC++ to
if DecC == 'Z'
DecC = 'A'
else
DecC++;
Or you could get fancy and use the modulus operator
Edit
I think the problem may be that this stringstream insertion operator, >>, doesn't have an overload that handles a char. It's converting the char to a short or an int then inserting it. Try using string::append(size_t size, char c) instead. That should handle inserting a char.
That is replace you calls to str1<<(char)DeC; with outted.append(1, (char)DeC) and remove your use of the string stream
What is DeC? The phrase "ascii list" makes me suspect it's a 'C' string, in which case you are calling isAlpha() on the pointer not on the value in the string.
edit: If for example you have
char DeC[40];
// read in a string form somewhere
// DeC is a pointer to some memory it has a value of a 32 or 64bit number
if ( isAlpha(DeC) {
// what you might have meant is
if ( isAlpha(*DeC) { // the character value at the current position in DeC

C++ substr() problems when string contains special characters

I'm trying to split a c++ string into a number of substrings (NUM_LINES) each with the length of CHAR_PER_LINE.
for(int i = 0; i < NUM_LINES; i++) {
lines[i] = totalstring.substr(i*CHAR_PER_LINE,CHAR_PER_LINE);
}
Works fine as long as there's no special character in the string. Otherwise substr() gets me a string that isn't CHAR_PER_LINE characters long, but stops right before a special character and exits the loop.
Any hints?
ok, edit:
1) I'm definitely not reaching the end of my string. If my totalstring.length() is 1000 and I have a special character in the first line (that is the first CHAR_PER_LINE (30) chars of the string) the loop exits.
2) Special characters I had problems with are for instance 'ö' and '–' (the long one)
EDIT 2:
std::string text = "aaaabbbbccccdödd";
std::string line[4];
for(int i = 0; i < 4; i++)
line[i] = text.substr(i*4,4);
for(int i = 0; i < 4; i++)
std::cout << line[i] << "\n";
This example works. I get a '%' for the ö.
So the problem wasn't substr(). Sorry. I'm using Cairo to create a gui and it seems my Cairo output is causing the troubles, not substr().
How about a hint of what special characters you're talking about?
My guess is that you reached the end of the string.
The STL doesn't care of special characters. If there are multibyte sequences (i.e. UTF8), std::string treats them as a sequence of single one-byte-characters. If you need proper Unicode handling, do not use the builtin substr or length.
You can, however, use std::wstring (from your posting it isn't clear whether you're already using it, but I guess not) - it holds wchar_t characters - large enough for the native character set of your target platform.
What's happening is that you're running off the end of the string on the last line. It isn't exiting the loop after skipping characters. It exits the loop precisely when it should, and the last line contains the right number of characters, it's just that some of them are garbage so your diagnositic printout is showing that the line is short.
The only way the loop could be exited early is if an exception were thrown.