When I'm compiling the following source code, in the output the zero doesn't correctly show. Why? I want the output text to have the following format:
01 02 03 04
05 06 07 08
not 1 2 3 4....
How can I fix this issue?
#include "stdio.h"
int main(int argc, char const *argv[])
{
int a[3][4] = {
{00, 01, 02, 03} , /* initializers for row indexed by 0 */
{04, 05, 06, 07} , /* initializers for row indexed by 1 */
{08, 09, 10, 11} /* initializers for row indexed by 2 */
};
for (int i = 0; i < 3; ++i)
{
for (int t = 0; t < 4; ++t)
{
printf("%d\t", a[i][t] );
}
printf("\n");
}
return 0;
}
Check the printf manual page
Look for the padding with 0:
0
The value should be zero padded. For d, i, o, u, x, X, a, A, e, E, f,
F, g, and G conversions, the converted value is padded on the left
with zeros rather than blanks. If the 0 and - flags both appear, the 0
flag is ignored. If a precision is given with a numeric conversion (d,
i, o, u, x, and X), the 0 flag is ignored. For other conversions, the
behavior is undefined.
and look for the field width:
The field width
An optional decimal digit string (with nonzero first digit) specifying
a minimum field width. If the converted value has fewer characters
than the field width, it will be padded with spaces on the left (or
right, if the left-adjustment flag has been given). Instead of a
decimal digit string one may write "*" or "*m$" (for some decimal
integer m) to specify that the field width is given in the next
argument, or in the m-th argument, respectively, which must be of type
int. A negative field width is taken as a '-' flag followed by a
positive field width. In no case does a nonexistent or small field
width cause truncation of a field; if the result of a conversion is
wider than the field width, the field is expanded to contain the
conversion result.
solution use:
printf("%02d\b", a[i][t]);
and drop the 0 from literal (01, 02...) or they will be taken as octal numbers.
0 before number tells compiler, that this number is in octal notation. You cannot do this with numbers, only with chars, or with right format in printf. Actually your code is incorrect and should never compiles, since there is no digits 8 and 9 in octal.
Related
I have a c++ program that takes an integer and convert it to lower and uppercase alphabets, similar to what excel does to convert column index to column number but also including lower case letters.
#include <string>
#include <iostream>
#include <climits>
using namespace std;
string ConvertNum(unsigned long v)
{
char const digits[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
size_t const base = sizeof(digits) - 1;
char result[sizeof(unsigned long)*CHAR_BIT + 1];
char* current = result + sizeof(result);
*--current = '\0';
while (v != 0) {
v--;
*--current = digits[v % base];
v /= base;
}
return current;
}
// for testing
int main()
{
cout<< ConvertNum(705);
return 0;
}
I need the vba function to reverse this back to the original number. I do not have a lot of experience with C++ so I can not figure out a logic to reverse this in vba. Can anyone please help.
Update 1: I don't need already written code, just some help in the logic to reverse it. I'll try to convert the logic into code myself.
Update 2: Base on the wonderful explanation and help provided in the answer, it's clear that the code is not converting the number to a usual base52, it is misleading. So I have changed the function name to eliminate the confusion for future readers.
EDIT: The character string format being translated to decimal by the code described below is NOT a standard base-52 schema. The schema does not include 0 or any other digits. Therefore this code should not be used, as is, to translate a standard base-52 value to decimal.
O.K. this is based on converting a single character based on its position in a long string. the string is:
chSET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
The InStr() function tells us the A is in position 1 and the Z is in position 26 and that a is in position 27. All characters get converted the same way.
I use this rather than Asc() because Asc() has a gap between the upper and lower case letters.
The least significant character's value gets multiplied by 52^0The next character's value gets multiplied by 52^1The third character's value gets multiplied by 52^3, etc. The code:
Public Function deccimal(s As String) As Long
Dim chSET As String, arr(1 To 52) As String
Dim L As Long, i As Long, K As Long, CH As String
chSET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
deccimal = 0
L = Len(s)
K = 0
For i = L To 1 Step -1
CH = Mid(s, i, 1)
deccimal = deccimal + InStr(1, chSET, CH) * (52 ^ K)
K = K + 1
Next i
End Function
Some examples:
NOTE:
This is NOT the way bases are usually encoded. Usually bases start with a 0 and allow 0 in any of the encoded value's positions. In all my previous UDF()'s similar to this one, the first character in chSET is a 0 and I have to use (InStr(1, chSET, CH) - 1) * (52 ^ K)
Gary's Student provided a good and easy to understand way to get the number from what I call "Excel style base 52" and this is what you wanted.
However this is a little different from the usual base 52. I'll try to explain the difference to regular base 52 and its conversion. There might be an easier way but this is the best I could come up with that also explains the code you provided.
As an example: The number zz..zz means 51*(1 + 52 + 52^2 + ... 52^(n-1)) in regular base 52 and 52*(1 + 52 + 52^2 + ... 52^(n-1)) in Excel style base 52. So Excel style get's higher number with fewer digits. Here is how much that difference is based on number of digits. How is this possible? It uses leading zeros so 1, 01, 001 etc are all different numbers. Why don't we do this normally? It would mess up the easy arithmetic of the usual system.
We can't just shift all the digits by one after the base change and we can't just substract 1 before the base change to counter the fact that we start at 1 instead of 0. I'll outline the problem with base 10. If we'd use Excel style base 10 to number the columns, we would have to count like "0, 1, 2, ..., 9, 00, 01, 02, ...". On the first glance it looks like we just have to shift the digits so we start counting at 1 but this only works up to the 10th number.
1 2 .. 10 11 .. 20 21 .. 99 100 .. 110 111 //normal counting
0 1 .. 9 00 .. 09 10 .. 88 89 .. 99 000 //excel style counting
You notice that whenever we add a new digit we shift again. To counter that, we have to do a shift by 1 before calculating each digit, not shift the digit after calculating it. (This only makes a difference if we're at 52^k) Note that we still assign A to 0, B to 1 etc.
Normally what you would do to change bases is looping with something like
nextDigit = x mod base //determining the last digit
x = x/base //removing the last digit
//terminate if x = 0
However now it is
x = x - 1
nextDigit = x mod base
x = x/base
//terminate if x = 0
So x is decremented by 1 first! Let's do a quick check for x=52:
Regular base 52:
nextDigit = x mod 52 //52 mod 52 = 0 so the next digit is A
x = x/52 //x is now 1
//next iteration
nextDigit = x mod 52 //1 mod 52 = 1 so the next digit is B
x = x/52 //1/52 = 0 in integer arithmetic
//terminate because x = 0
//result is BA
Excel style:
x = x-1 //x is now 51
nextDigit = x mod 52 //51 mod 52 = 51 so the next digit is z
x = x/52 //51/52 = 0 in integer arithmetic
//terminate because x=0
//result is z
It works!
Part 2: Your C++ code
Now for let's read your code:
x % y means x mod y
When you do calculations with integers, the result will be an integer which is achieved by rounding down. So 39/10 will produce 3 etc.
x++ and ++x both increment x by 1.
You can use this in other statements to save a line of code. x++ means x is incremented after the statement is evaluated and ++x means it is incremented before the statement is evaluated
y=f(x++);
is the same as
y = f(x);
x = x + 1;
while
y=f(++x);
is the same as
x = x + 1;
y = f(x);
This goes the same way for --
Char* p creates a pointer to a char.
A pointer points to a certain location in memory. If you change the pointer, it points to a different location. E.g. doing p-- moves the pointer one to the left. To read or write the value that is saved at the location, use *p. E.g. *p="a"; "a" is written to the memory location that p points at. *p--="a"; "a" is written to the memory but the pointer is moved to the left afterwards so *p is now whatever is in the memory left of "a".
strings are just arrays of type char.
The end of a string is always '\0' if the computer reads a string it continues until it finds '\0'
This is hopefully enough to understand the code. Here it is
#include <string>
#include <iostream>
#include <climits>
using namespace std;
string base52(unsigned long v)
{
char const digits[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; //The digits. (Arrays start at 0)
size_t const base = sizeof(digits) - 1; //The base, based on the digits that were given
char result[sizeof(unsigned long)*CHAR_BIT + 1]; //The array that holds the answer
//sizeof(unsigned long)*CHAR_BIT is the number of bits of an unsigned long
//which means it is the absolute longest that v can be in any base.
//The +1 is to hold the terminating character '\0'
char* current = result + sizeof(result); //This is a pointer that is supposed to point to the next digit. It points to the first byte after the result array (because its start + length)
//(i.e. it will go through the memory from high to low)
*--current = '\0'; //The pointer gets moved one to the left (to the last char of result and the terminating char is added
//the pointer has to be moved to the left first because it was actually pointing to the first byte after the result.
while (v != 0) { //loop until v is zero (until there are no more digits left.
v--; //v = v - 1. This is the important part that does the 1 -> A part
*--current = digits[v % base]; // the pointer is moved one to the left and the corresponding digit is saved
v /= base; //the last digit is dropped
}
return current; //current is returned, which points at the last saved digit. The rest of the result array (before current) is not used.
}
// for testing
int main()
{
cout<< base52(705);
return 0;
}
I have this very strange problem where if I declare an int like so
int time = 0110;
and then display it to the console the value returned is 72. However when I remove the 0 at the front so that int time = 110; the console then displays 110 like expected.
Two things I'd like to know, first of all why it does this with a preceding 0 at the start of the int and is there a way to stop it so that 0110 at least equals 110?Secondly is there any way to keep it so that 0110 returns 0110?
If you take a crack guess at the variable name I'm trying to do operations with 24hr time, but at this point any time before 1000 is causing problems because of this.
Thanks in advance!
An integer literal that starts from 0 defines an octal integer literal. Now in C++ there are four categories of integer literals
integer-literal:
decimal-literal integer-suffixopt
octal-literal integer-suffixopt
hexadecimal-literal integer-suffixopt
binary-literal integer-suffixopt
And octal-integer literal is defined the following way
octal-literal:
0 octal-literal
opt octal-digit
That is it starts from 0.
Thus this octal integer literal
0110
corresponds to the following decimal number
8^2 + 8^1
that is equal to 72.
You can be sure that 72 in octal representation is equivalent to 110 by running the following simple program
#include <iostream>
#include <iomanip>
int main()
{
std::cout << std::oct << 72 << std::endl;
return 0;
}
The output is
110
It is because of Integer Literals. Placing a 0 before number means its a octal number. For binary it is 0b, for hexadecimal it is 0x or 0X. You don't need to write any thing for decimal. See the code bellow.
#include<stdio.h>
int main()
{
int binary = 0b10;
int octal=010;
int decimal = 10;
int hexa = 0x10;
printf("%d %d %d %d\n", octal, decimal, hexa, binary);
}
For more information visit tutorialspoint.
The compiler is interpreting the leading zero as an octal number. The octal value of "110" is 72 in decimal. There's no need for the leading zero if you're just storing an int value.
You're trying to store "time" as it appears on a clock. That's actually more complicated than a simple int. You could store the number of minutes since midnight instead.
Zero at the start means the number is in octal. Without it is decimal.
I am new to C so I do not understand what is happening in this line:
out[counter++] = recurring_count + '0';
What does +'0' mean?
Additionally, can you please help me by writing comments for most of the code? I don't understand it well, so I hope you can help me. Thank you.
#include "stdafx.h"
#include "stdafx.h"
#include<iostream>
void encode(char mass[], char* out, int size)
{
int counter = 0;
int recurring_count = 0;
for (int i = 0; i < size - 1; i++)
{
if (mass[i] != mass[i + 1])
{
recurring_count++;
out[counter++] = mass[i];
out[counter++] = recurring_count + '0';
recurring_count = 0;
}
else
{
recurring_count++;
}
}
}
int main()
{
char data[] = "yyyyyyttttt";
int size = sizeof(data) / sizeof(data[0]);
char * out = new char[size + 1]();
encode(data, out, size);
std::cout << out;
delete[] out;
std::cin.get();
return 0;
}
It adds the character encoding value of '0' to the value in recurring_count. If we assume ASCII encoded characters, that means adding 48.
This is common practice for making a "readable" digit from a integer value in the range 0..9 - in other words, convert a single digit number to an actual digit representation in a character form. And as long as all digits are "in sequence" (only digits between 0 and 9), it works for any encoding, not just ASCII - so a computer using EBCDIC encoding would still have the same effect.
recurring_count + '0' is a simple way of converting the int recurring_count value into an ascii character.
As you can see over on wikipedia the ascii character code of 0 is 48. Adding the value to that takes you to the corresponding character code for that value.
You see, computers may not really know about letters, digits, symbols; like the letter a, or the digit 1, or the symbol ?. All they know is zeroes and ones. True or not. To exist or not.
Here's one bit: 1
Here's another one: 0
These two are only things that a bit can be, existence or absence.
Yet computers can know about, say, 5. How? Well, 5 is 5 only in base 10; in base 4, it would be a 11, and in base 2, it would be 101. You don't have to know about the base 4, but let's examine the base 2 one, to make sure you know about that:
How would you represent 0 if you had only 0s and 1s? 0, right? You probably would also represent the 1 as 1. Then for 2? Well, you'd write 2 if you could, but you can't... So you write 10 instead.
This is exactly analogous to what you do while advancing from 9 to 10 in base 10. You cannot write 10 inside a single digit, so you rather reset the last digit to zero, and increase the next digit by one. Same thing while advancing from 19 to 20, you attempt to increase 9 by one, but you can't, because there is no single digit representation of 10 in base 10, so you rather reset that digit, and increase the next digit.
This is how you represent numbers with just 0s and 1s.
Now that you have numbers, how would you represent letters and symbols and character-digits, like the 4 and 3 inside the silly string L4M3 for example? You could map them; map them so, for example, that the number 1 would from then on represent the character A, and then 2 would represent B.
Of course, it would be a little problematic; because when you do that the number 1 would represent both the number 1 and the character A. This is exactly the reason why if you write...
printf( "%d %c", 65, 65 );
You will have the output "65 A", provided that the environment you're on is using ASCII encoding, because in ASCII 65 has been mapped to represent A when interpreted as a character. A full list can be found over there.
In short
'A' with single quotes around delivers the message that, "Hey, this A over here is to receive whatever the representative integer value of A is", and in most environments it will just be 65. Same for '0', which evaluates to 48 with ASCII encoding.
I'm trying (without much success) to write a short c++ function:
double digit(double x, int b, int d)
that returns the d-th digit in base-b expansion of the number x, which can be positive or negative, and can be a fraction. when d is negative, it should return the after-the-decimal-dot digits (its underfined for d=0 so say it returns 0 in that case).
For example:
const double x = 25.73;
for (int n = -5; n <= 5; n++)
cout<<digit(x,10,n)<<' ';
should print:
0
0
0
3
7
0
5
2
0
0
0
The function must use only loops, if, exp, pow, log, floor and ceil. i.e., without sprintf tricks etc.
Thanks!!!
EDIT: For simplicity, assume 2<=b<=10
EDIT: Please also avoid using mod, only pow-exp-log-floor-ceil based solutions
This seems to be the most straightforward implementation, and it seems to work just fine.
int digit( double x, int base, int index ) {
// shift number (mult by power of base) so desired digit is in one's place
x = std::abs( x ) * std::pow( base, - index );
// fmod strips higher digits; floor strips lower digits, leaving result.
return std::floor( std::fmod( x, base ) );
}
I changed the return type from double to int since it doesn't make sense to have a fraction in a digit. And it doesn't return . for 0, because again that's not a digit. The 0'th place value is the one's place.
Also this ignores the minus sign; you didn't define the "base-b expansion" for negative numbers. You could adjust the function to return b's complement notation or whatever.
By substituting x you can make this into one line, so it will satisfy the requirements for constexpr on platforms where the math functions are constexpr as well.
Let's do this in two steps.
1.Convert a number to base b
2.Find the d-th digit and return it.
The reason for splitting the tasks is because if you are repeatedly calling for the same set of base and number and only for different d's, then we can cache the number in the new base.For example the following function converts a number a from base 10, to a base b.I am curious how to deal with fractions.
string changeBase(int a,int b)
{
string A="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string res="";
while(a>=b)
{
res=A[a%b]+res;
a=a/b;
}
return res;
}
We need to return as a string as the new base can have digits like 'A' or 'B' or the like, which represent remainders of 10, 11, and so on.
Then we can play around with the returned string as in:
string A=changeBase(24,2);
cout<<A[0];//for some d
For negative support you can use the string index appropriately based on how you define it for negative d.
In this code what is the role of the symbol %3d? I know that % means refer to a variable.
This is the code:
#include <stdio.h>
int main(void)
{
int t, i, num[3][4];
for(t=0; t<3; ++t)
for(i=0; i<4; ++i)
num[t][i] = (t*4)+i+1;
/* now print them out */
for(t=0; t<3; ++t) {
for(i=0; i<4; ++i)
printf("%3d ", num[t][i]);
printf("\n");
}
return 0;
}
%3d can be broken down as follows:
% means "Print a variable here"
3 means "use at least 3 spaces to display, padding as needed"
d means "The variable will be an integer"
Putting these together, it means "Print an integer, taking minimum 3 spaces"
See http://www.cplusplus.com/reference/clibrary/cstdio/printf/ for more information
That is a format specifier to print a decimal number (d) in three (at least) digits (3).
From man printf:
An optional decimal digit string
specifying a minimum field width. If
the converted value has fewer
characters than the field width, it
will be padded with spaces on the left
(or right, if the left-adjustment flag
has been given) to fill out the field
width.
Take a look here:
Print("%3d",X);
If X is 1234, it prints 1234.
If X is 123, it prints 123.
If X is 12, it prints _12 where _ is a leading single whitespace character.
If X is 1, it prints __1 where __ is two leading whitespacce characters.
An example to enlighten existing answers:
printf("%3d" , x);
When:
x is 1234 prints 1234
x is 123 prints 123
x is 12 prints 12 with an extra padding (space)
x is 1 prints 1 with two extra paddings (spaces)
You can specify the field width between the % and d(for decimal). It represents the total number of characters printed.
A positive value, as mentioned in another answer, right-aligns the output and is the default.
A negative value left-aligns the text.
example:
int a = 3;
printf("|%-3d|", a);
The output:
|3 |
You could also specify the field width as an additional parameter by using the * character:
int a = 3;
printf("|%*d|", 5, a);
which gives:
| 3|
It is a formatting specification. %3d says: print the argument as a decimal, of width 3 digits.
Literally, it means to print an integer padded to three digits with spaces. The % introduces a format specifier, the 3 indicates 3 digits, and the d indicates an integer. Thus, the value of num[t][i] is printed to the screen as a value such as " 1", " 2", " 12", etc.
2/3 or any integer is padding/width .it means ex for 3 ,minimum 3 space if we print a=4 then it print like 4,here two space left before 4 because it is one character