Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
This is the program for converting the ascii sentence to character sentence. But i dont understand the num = num * 10 + (str[i] - '0'); why it us used and why it's needed?
#include <bits/stdc++.h>
using namespace std;
void asciiToSentence(string str, int len)
{
int num = 0;
for (int i = 0; i < len; i++) {
num = num * 10 + (str[i] - '0');
if (num >= 32 && num <= 122) {
char ch = (char)num;
cout << ch;
num = 0;
}
}
}
int main()
{
string str = "973265";
int len = str.length();
asciiToSentence(str, len);
return 0;
}
Firstly, bits/* are not standard headers, you shouldn't be using them otherwise your code may not compile with compilers like MSVC. Refer this.
Now let's come to your query : str[i] - '0' is simply a way to convert char to respective int, i.e. '0' to 0. You can find more discussion on this thread.
What does your code do?
It just keeps on extracting chars from your string (in loop), converting it to int and adding to num after multiplying it by 10. This is basically converting a part of string, say, "97" to an integer 97.
When num comes in range from 32 (' ') to 122 ('Z') (both inclusive), it cast them to char and prints it.
Explanation of Sample Output:
Your code prints a A to console. You will get this result if you can figure out the substrings. Here consider these three - "97" "32" "65". Then "97" will be converted to 97 (as int), then will be cast to char and end up being 'a' ('a' has ASCII value of 97). Similarly "32", will be a space ' ', and "65" will be 'A'.
These substrings didn't come here by magic. Let me explain one for you :
You have str = "973265", num = 0, then the loop begins :
i = 0 -> str[i] = '9' -> str[i] - '0' = 9 -> num = 0*10 + 9 = 9 -> is num in range [32, 122]? false -> go to next iteration.
i = 1 -> str[i] = '7' -> str[i] - '7' = 7 -> num = 9*10 + 7 = 97 -> is num in range [32, 122]? true -> ch = (char)num = (char)97 = 'A' -> print ch, i.e. 'A' -> num = 0 -> go to next iteration.
Pro Tip: Use your debugger, set breakpoints, watch variables and step through your code for better understanding.
Note that: When I wrote ____ - I meant ____ like this ____.
"convert" -- conversion -- '0' <-> 0 or "12" <-> 12
"cast" -- casting -- '0' <-> 48 (assuming your compiler is using ASCII).
In http://www.asciitable.com/, you can see that 0 has ascii value of 48, 1 is 49, 2 is 50 and so on.
So str[i] - '0' will give you 0 if str[i] == '0', 1 if str[i] == '1' and so on. This is a simple trick to convert numeric char into its mathematical value.
Let's call str[i] - '0' as x, so the line you don't understand becomes num = num * 10 + x. What this does is, take the original num (say it was 32), add a 0 behind it (so it becomes 320), then add x (if x is 7, num becomes 327).
So overall, this code is basically a function that converts a number string into integer type.
Related
I recently learnt that using getchar_unlocked() is a faster way of reading input.
I searched on the internet and found the code snippet below:
But I am unable to understand it.
void fast_scanf(int &number)
{
register int ch = getchar_unlocked();
number= 0;
while (ch > 47 && ch < 58) {
number = number * 10 + ch - 48;
ch = getchar_unlocked();
}
}
int main(void)
{
int test_cases;fast_scanf(test_cases);
while (test_cases--)
{
int n;
fast_scanf(n);
int array[n];
for (int i = 0; i < n; i++)
fast_scanf(array[i]);
}
return 0;
}
So, this code takes input for an integer array of size n for a given number of test_cases . I didn't understand anything in the function fast_scanf, like why this line:
while (ch > 47 && ch < 58)
{ number = number * 10 + ch - 48;
why the register is used while declaring ch?
why the getchar_unlocked() is used twice in the function? and so on..
It would be great help if someone elaborates this for me. Thanks in advance!
Okay, since what you are asking needs to be explained clearly, I am writing it here... so I don't jumble it all up inside the comments...
The function: (Edited it a bit to make it look like more C++-standard)
void fast_scanf(int &number)
{
auto ch = getchar_unlocked();
number= 0;
while (ch >= '0' && ch <= '9')
{
number = number * 10 + ch - '0';
ch = getchar_unlocked();
}
}
Here, take up consideration by looking at the ASCII Table first, since you won't understand how the results are coming up if you don't...
1) Here, you have a character ch takes up the input character from the user using getchar_unlocked() (The auto keyword does that automatically for you and is only usable in C++, not C)...
2) You assign the variable number to zero so that the variable can be re-used, note that the variable is a reference so it changes inside your program as well...
3) while (ch >= '0' && ch <= '9')... As pointed out, checks whether the characters is within the numerical ASCII limit, similar to saying that the character has to be greater than or equal to 48 but less than or equal to 57...
4) Here, things are a little bit tricky, Variable number is multiplied with the product of itself and 10 and the real integer value of the character you stored)...
5) In the next line, ch is reassigned so that you don't have to stay in the loop forever, since ch will remain that number forever if the user doesn't type anything... remember a loop goes back to where it was declared after reaching the end, checks if the condition is true, continues if it is true else breaks)...
For example: 456764
Here, ch will first take 4 then the others follow so we go with 4 first...
1) Number will be assigned to zero. While loop checks if the given character is a number or not, if it is continues the loop else breaks it...
2) Multiplication of 0 with 10 will be zero... and adding it with difference 52 (that is '4') with 48 (that is '0') gives you 4 (the real numerical value, not the char '4')...
So the variable number now is 4...
And the same continues with the others as well... See...
number = number * 10 + '5' - '0'
number = 4 * 10 + 53 - 48
number = 40 + 5
number = 45... etc, etc. for other numbers...
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
Can someone help me to write a few c++ lines of code to convert an input string letters as follow:
Lowercase letters to Uppercase letters.
Uppercase letters to lowercase letters.
libraries functions are not allowed.
if statement, comparisons, | operation and & not allowed.
Thanks.
You can write an translation array (= map).
a -> A
A -> a
b -> B
B -> b
...
z -> Z
Z .. z
For ASCII you can implement it as a char[] with 128 entries and simply use the character of you source as index to read the resulting character.
char translate[128];
translate['A']='a';
...
Possible Implementation:
// The following init-String is quite long (128 characters)!
char* translate=" abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ ";
int i=0;
while(0!=s[i])
s[i] = translate[s[i++]];
If your input is ASCII, you can simply invert bit 5 which means xor the value 32 to each character. That will convert lowercase to upper case and vici versa.
Only problem is it only works for a-zA-Z and nothing else.
You can use a combination of std::transform and the functions toupper and tolower.
EDIT: sorry missed your last two points. You will have to perform a cycle like for and you may use the ternary operator ? to avoid if statements. A possible solution for to upcase is:
for (unsigned i = 0; i < s.size(); ++i) {
s[i] = (s[i] >= 'a' && s[i] <= 'z') ? s[i] - 'a' + 'A' : s[i];
}
Something like this would work, but only if you have alphabets
char c = 'a';
int e = c;
int d = e < 90 ? e + 32 : e - 32;
My solution: was looking for others.
string s;
cin>>s;
int a[3] = {'A', 'a', 'a'};
int A[3] = {'a', 'A', 'A'};
for (int i=0; i<s.size(); ++i)
s[i] = s[i] - a[(s[i]-'A')/26] + A[(s[i]-'A')/26];
cout << s << endl;
Thanks for trying.
I have an IDC_Edit text box set which will accept hexadecimal space-separated values that I'm wanting to convert into a WORD. I'm wanting the control to mimic the array, but I'm really unsure how to complete the conversion.
Basically, if I input:
"12 AB"
I need the resulting WORD to equal:
0x12AB
As someone who rarely dabbles with C++, let alone the WinAPI, I'm really stumped as to how to do this. My current code is:
HWND hTextInput = GetDlgItem(hWnd, IDC_EDIT);
DWORD dwInputLength = Edit_GetTextLength(hTextInput);
char* resultString = new char[dwInputLength+1];
memset(hTextInput , 0, dwInputLength+1);
WORD result = (resultString[0] << 8) | resultString[1];
This pulls the IDC_EDIT control's text and length and turns it into a char* array. This then attempts to convert into a WORD, but obviously this only currently takes the first two characters (12) in this case.
How can I make this pull "12 AB" into the char* array as [0x12, 0xAB] (rather than ["1", "2", "A", "B"]) so that I can then shift the two bytes into a WORD?
Try this:
WORD Readhex(const char *p)
{
char c ;
WORD result = 0 ;
while (c = *p++)
{
if (c >= '0' && c <= '9')
c -= '0' ;
else if (c >= 'A' && c <= 'F')
c -= 'A' - 10 ;
else if (c >= 'a' && c <= 'f')
c -= 'a' - 10 ;
else
continue ;
result = (result << 4) + c ;
}
return result ;
}
...
HWND hTextInput = GetDlgItem(hWnd, IDC_EDIT);
DWORD dwInputLength = Edit_GetTextLength(hTextInput);
char* resultString = new char[dwInputLength+1];
GetWindowText(hTextInput, resultString, dwInputLength+1) ;
WORD result = ReadHex(resultString) ;
You also forgot the GetWindowText; and filling the buffer with zeros (memset) is not necessary.
The strtol function as suggested will not work for you because strtol will consider the space as a terminator. Maybe you should also consider to do some error checking, for example if the user enters garbage. The ReadHex function above simply ignores any non hex digits.
for (int i = 0; i < s.length(); i++)
{
if (isdigit(s[i]))
counts[s[i] - '0'] ++;
}
what does this code means, any one can able to explain this code " counts[s[i] - '0'] ++;" exact opertion
counts is a ten-element array, which is being used to count how many times each digit appears in s.
Specifically:
s[i] - '0' turns '0' into 0, '1' into 1 etc.
counts[...]++ increments the corresponding element of the array.
Hope this helps.
1) Ascii value of '0' is 48
2) Whenever s[i] is a digit (between 0-9 inclusive)
3) s[i] - '0' evaluates to an index (between 0..9 inclusive);
Example:
Ascii value of '1' is 49
Say s[i] is '1'
then s[i] - '0' is 49-48 = 1
4) counts[s[i]-'0']++ would count the number of times a particular digit has been found in s[i].
The code is counting how many times a digit (1-9) is appearing in string s.
Note. 'i' - '0' is the same as i - 0 if i is a digit.
The reason is that characters '0' -'9' have consecutive ASCII values. So the difference in ASCII value between 'i' and '0' is i;
Now let's say
string s = "1b21cc55";
and
int count[10] is all zeros
in the loop
we check s[i],
s[0] = 1 ---> isdigit(1) = yes ----> count[1-0] += 1 ---> count[1] is 1;
s[1] = b ---> isdigit(b) = no ;
s[2] = 2 ---> isdigit(2) = yes ----> count[2-0] += 1; ---> count[2] is 1;
s[3] = 1 ---> isdigit(1) = yes ----> count[1-0] += 1; ---> count[1] is 2;
and so on ...
At the end count[i] will tell you how many is are in the string.
counts is an array.
s[i] is a character which contains numbers in ASCII. '0', '1',
'2', ...
s[i] - '0' converts them into integer numbers. 1, 2, 3, ...
Above number indicates the index of n'th item in the array --> X
counts[X] ++ increments one the X'th item of the array.
To start off, I'm four weeks into a C++ course and I don't even know loops yet, so please speak baby talk?
Okay, so I'm supposed to read a twelve character string (plus NULL makes thirteen) from a file, and then shift the letters backwards three, and then print my results to screen and file. I'm okay with everything except the shifting letters. I don't want to write miles of code to take each character individually, subtract three, and re-assemble the string, but I'm not sure how to work with the whole string at once. Can someone recommend a really simple method of doing this?
If you are dealing with simple letters (A to Z or a to z), then you can assume that the internals codes are linear.
Letters are coded as numbers, between 0 and 127. A is coded as 65, B as 66, C as 67, Z as 90.
In order to shift letters, you just have to change the internal letter code as if it were a number, so basically just substracting 3 from the character. Beware of edge cases though, because substracting 3 to 'A' will give you '>' (code 62) and not 'X' (code 88). You can deal with them using "if" statements or the modulo operator ("%").
Here is an ASCII characters table to help you
Once you've loaded your string in, you can use the modulous operator to rotate while keeping within the confines of A-Z space.
I'd keep track of whether the letter was a capital to start with:
bool isCaps = ( letter >= 'A' ) && ( letter <= 'Z' );
if( isCaps )
letter -= 'A'-'a';
and then just do the cipher shift like this:
int shift = -3;
letter -= 'a'; // to make it a number from 0-25
letter = ( letter + shift + 26 ) % 26;
// add 26 in case the shift is negative
letter += 'a'; // back to ascii code
finally finish off with
if( isCaps )
letter += 'A'-'a';
so, putting all this together we get:
char *mystring; // ciphertext
int shift = -3; // ciphershift
for( char *letter = mystring; letter; ++letter )
{
bool isCaps = ( *letter >= 'A' ) && ( *letter <= 'Z' );
if( isCaps )
*letter -= 'A'-'a';
letter -= 'a';
letter = ( letter + shift + 26 ) % 26;
letter += 'a';
if( isCaps )
letter += 'A'-'a';
}
You're going to have to learn loops. They will allow you to repeat some code over the characters of a string, which is exactly what you need here. You'll keep an integer variable that will be your index into the string, and inside the loop do your letter-shifting on the character at that index and increment the index variable by one until you reach NULL.
Edit: If you're not expected to know about loops yet in your course, maybe they want you to do this:
string[0] -= 3; // this is short for "string[0] = string[0] - 3;"
string[1] -= 3;
string[2] -= 3;
...
It will only result in 12 lines of code rather than miles. You don't have to "reassemble" the string this way, you can just edit each character in-place. Then I bet after making you do that, they'll show you the fast way of doing it using loops.
Iterate over the characters with a for loop. And do what you want with the char*. Then put the new char back.
for(int i=0; i<12; i++){
string[i] = string[i] - 3;
}
Where string is your character array (string). There is a bit more involved if you want to make it periodic (I.E. have A wrap round to Z, but the above code should help you get started)
I'm a little unclear what you mean by "shift the letters backwards 3"?
Does that mean D ==> A?
If so, here's a simple loop.
(I didn't do reading from the file, or writing to the file... Thats your part)
#include <string.h>
int main(void)
{
char input[13] = "ABCDEFGHIJKL";
int i;
int len = strlen(input);
for(i=0; i<len; ++i)
{
input[i] = input[i]-3;
}
printf("%s", input); // OUTPUT is: ">?#ABCDEFGHI"
}