formatting setw() function equivalent to 1 \t tab [duplicate] - c++

I want to implement a text drawing function. But I am not sure how \t works, which means I don't know how many spaces I should print for \t.
I have come up with the following algorithm:
a) Each \t represents at most NUMBER_OF_SPACES_FOR_TAB spaces.
b) If \t appears in the last line at a corresponding position, \t for this line should be aligned to the \t of last line.
Example:
printf("a\t\tb\n");
printf("\t\tc\n");
Should print:
a11112222b
34444c
Where:
1.Number i represents the spaces of \t at position i
2.NUMBER_OF_SPACES_FOR_TAB == 4
Does anyone know the standard algorithm? Thanks in advance.

A tab character should advance to the next tab stop. Historically tab stops were every 8th character, although smaller values are in common use today and most editors can be configured.
I would expect your output to look like the following:
123456789
a b
c
The algorithm is to start a column count at zero, then increment it for each character output. When you get to a tab, output n-(c%n) spaces where c is the column number (zero based) and n is the tab spacing.

Imagine a ruler with tab stops every 8 spaces. A tab character will align text to the next tab stop.
0 8 16 24 32 40
|.......|.......|.......|.......|.......|
printf("\tbar\n"); \t bar
printf("foo\tbar\n"); foo\t bar
printf("longerfoo\tbar"); longerfoo\t bar
To calculate where the next tab stop is, take the current column.
nextTabStop = (column + 8) / 8 * 8
The / 8 * 8 part effectively truncates the result to the nearest multiple of 8. For example, if you're at column 11, then (11 + 8) is 19 and 19 / 8 is 2, and 2 * 8 is 16. So the next tab stop from column 11 is at column 16.
In a text editor you may configure tab stops to smaller intervals, like every 4 spaces. If you're simulating what tabs look like at a terminal you should stick with 8 spaces per tab.

A Tab character shifts over to the next tab stop. By default, there is one every 8 spaces. But in most shells you can easily edit it to be whatever number of spaces you want (profile preferences in linux, set tabstop in vim).

Related

BigQuery string comparison and adjustment with replace/trim

I tried to accommodate in BigQuery for inputs with bad spacing.
However, I keep getting weird results, basically saying that abc <> abc.
Can anyone explain how this is possible?
I tried to adjust this by using replace and rtrim but none of them served the purpose.
Thank you
SELECT o = t,o, t, length(o) as lon_o, length(t) as len_t
from
(select replace('abc ',' ','') o,
'abc' as t)
I was able easily reproduce your case by having (for example) few tabs inside that string instead of spaces -
visually they look exactly alike - but first row has 64 spaces in it whereas second row has 5 tabs and 44 spaces. In Web UI each tab occupy 2 char-places so that is why total 5 tabs + 44 spaces look like 64 spaces (exactly as in first row)
To address this - you can use REGEXP_REPLACE instead of REPLACE
Using REGEXP_REPLACE allows you to 'remove' all white spaces, as in example below (the only difference here is in second row - using REGEXP_REPLACE instead of REPLACE and use of r'\s' instead ' '
And, finally - if to get back to first example - the good way of seeing what actually makes those 8 chars vs. 3 chars in result's lon_o is to switch from Table viewtoJSON` view as below
This is working for me
Check if you don't have hidden ASCII chars in your text which might be causing this for example HEX 80

Concatinate in OPEN OFFICE removing Leading zeroes

A B C D
2 DRUGS 000000000004 2 PARACETAMOL (ACETAMINOPHEN) TAB 500 MG
This is my entry in my open office so we have here the row 2 with columns A-D
I have create a formula =CONCATENATE("('" ;A2;"','";B2;"','";C2;"','";D2;"'),")
and this one give me this result:
('DRUGS','4','2','PARACETAMOL (ACETAMINOPHEN) TAB 500 MG'),
Basically I want a result like:
('DRUGS','000000000004','2','PARACETAMOL (ACETAMINOPHEN) TAB 500 MG'),
Column B is set to Number with Leading zeroes set to 12.
What I want is to get a result where the leading zeroes in column B is will retained.
=CONCATENATE("('" ;A2;"','";TEXT(B2;"000000000000");"','";C2;"','";D2;"'),")
Use any mask you want as the second parameter to the TEXT function
More on TEXT and other text functions: https://help.libreoffice.org/Calc/Text_Functions#TEXT
Please try:
=CONCATENATE("('";A2;"','";REPT("0";12-LEN(B2));B2;"','";C2;"','";D2;"'),")
I suspect what you have in B2 is 4 formatted with many leading 0. If so, it is possible, assuming many other entries, that some will be text and the cell content actually something like 000000000004 - for which the above formula will not work (but yours should).

In sapscript, how do I trim/offset from the right of a string?

I have a need in SAPScript to trim a string from the right. There doesn't appear to be a function to accomplish this. &myfield+3& only trims from the left.
Is there a way to trim from the right? Can offset accept a negative value?
My ultimate goal was to take a number such as a quantity; 12.43 and convert that to: 001243.
6 characters long
padded left with zeroes
no special characters (decimals or thousands separators)
Ultimately I had to first define a field and do the intial number formatting:
/:DEFINE &myfield& = &qtyfield(.2CT)&
The above
sets the number to 2 decimal points (.2)
space compreession (C)
removes the thousands separator (T)
Then I call a function within our print routine to do the special character stripping as such:
/:PERFORM get_unformatted_value IN PROGRAM zbc_rle_ean128_label
/:USING &myfield&
/:CHANGING &myfield&
/:ENDPERFORM
Then I can do the final output as such:
/ &myfield(K6RF0)&
which:
Ignores any conversions (K)
Sets output length to 6 and right aligns it (6R)
and left pad with zeros (F0)
That seems to work for me. Hopefully this helps someone!

Replace groups of text all together with gVim

Consider the following data:
Class Gender Condition Tenis
A Male Fail Fail 33
A Female Fail NotFail 23
S Male Yellow 14
BC Male Happy Elephant 44
I have a comma separated value with unformatted tabulation (it varies among tabs and whitespaces).
In one specific column I have compound words which I would like to eliminate the space. In the above example, I would like to replace "Fail " with "Fail_" and "Happy" with "Happy_".
The result would be the following:
Class Gender Condition Tenis
A Male Fail_Fail 33
A Female Fail_NotFail 23
S Male Yellow 14
BC Male Happy_Elephant 44
I already managed to do that in two steps:
:%s/Fail /Fail_/g
:%s/Happy /Happy_/g
Question: As I'm very new to gVim I am trying to implement these replacements all together, but I could not find how to do that*.
After this step, I will tabulate my data with the following:
:%s/\s\+/,/g
And get the final result:
Number,Gender,Condition,Tenis
A,Male,Fail_Fail,33
A,Female,Fail_NotFail,23
S,Male,Yellow,14
BC,Male,Happy_Elephant,44
On SO, I searched for [vim] :%s two is:question and some variations, but I could not find a related thread, so I guess I am lacking the correct terminology.
Edit: This is the actual data (with more than 1 million rows). The problem starts in the 12th column (e.g. "Fail Planting" should be "Fail_Planting").
SP1 51F001 3 1 1 2 3 2001 52 52 H Normal 17,20000076 23,39999962 NULL NULL
SP1 51F001 3 1 1 2 3 2001 53 53 F Fail Planting 0 0 NULL NULL
SP1 51F001 3 1 1 2 3 2001 54 54 N Normal 13,89999962 0 NULL NULL
You can use an expression on the right hand side of the substitution.
:%s/\(Fail\|Happy\) \|\s\+/\= submatch(0) =~# '^\s\+$' ? ',' : submatch(1).'_'/g
So this finds Fail or Happy or whitespace and then converts checks to see if the matched part is completely whitespace. It it is replace by a comma if it is not use the captured part and append an underscore. submatch(0) is the whole match and submatch(1) is the first capture group.
Take a look at :h sub-replace-expression. If you want to do something very complex define you can define a function.
Very magic version
:%s/\v(Fail|Happy) |\s+/\= submatch(0) =~# '^\v\s+$' ? ',' : submatch(1).'_'/g
You have all the parts you just need to combine them together with |. Example:
:%s/\>\s\</_/g|%s/\s\+/,/g
I am using \> and \< to find words that only have one space between them so we can replace it with _.
For more help see:
:h /\>
:h :range
:h :bar
You could perhaps try a macro if there are certain conditions that are true (or write a vimscript, but my vimscript is very rusty). I will show a sample macro you could use:
Go to first line in file after the headings
press q to begin recording a macro
press t to choose the register t for recording to (I use t for "temp")
press ^ to move to the beginning of the line
press 2w to move to the third word (move 2 words to the right)
press e to move to the end of the word
press l (letter l) to move right one character (to the space)
press r to enter replace single character mode
press _ to enter an underscore
press j to move down a line
press q to stop recording the macro
Now that you have the macro stored in register t you can run the macro on every line in the file. If there are 100 lines in the file, you have already done 1 and there is a header, so you would type the following to run it on the remaining 98 lines:
98#t
These two commands:
:%s/\(\a\) \(\a\)/\1_\2/g
:%s/\s\+/,/g
seem to work on your sample:
SP1,51F001,3,1,1,2,3,2001,52,52,H,Normal,17,20000076,23,39999962,NULL,NULL
SP1,51F001,3,1,1,2,3,2001,53,53,F,Fail_Planting,0,0,NULL,NULL
SP1,51F001,3,1,1,2,3,2001,54,54,N,Normal,13,89999962,0,NULL,NULL
but you have decimal numbers here with a comma as separator that will mess with the "comma-separated-ness" of your data. Changing those commas into periods beforehand might be a good idea:
:%s/,/./g
SP1,51F001,3,1,1,2,3,2001,52,52,H,Normal,17.20000076,23.39999962,NULL,NULL
SP1,51F001,3,1,1,2,3,2001,53,53,F,Fail_Planting,0,0,NULL,NULL
SP1,51F001,3,1,1,2,3,2001,54,54,N,Normal,13.89999962,0,NULL,NULL

Ncurses: Creating padded spaces between columns

I am creating a scrollable list using ncurses, similar to the list in aptitude (apt-get front end).
How should I go about creating padded spaces between columns? I am planning to write each column using wprintw().
e.g.
pizza spicy 10
steak normal 10
burritoes guacamole 20
each line using wprintw().
The following will give you 2 space padded, left justified, string columns 10 characters wide, each followed by a space, then a 2 digit decimal column.
wprintw(win,"%-10s %-10s %2d\n", "pizza", "spicy", 10);