Messing up of non-typical characters in DOS - batch-file

A command-line program outputs a list of file paths. I pipe the output to another program to do further processing. It all works fine until a file path is encountered that contains a "strange" character (ó, î, ä, etc.).
The cause of the problem seems to be the behavior described next:
Test 1
When I execute this command in cmd.exe,
C:\temp> echo ó > o.txt
the contents of the created file will be the character ¢.
Test 2
I created an input file, o_src.txt, (with my text editor) that contains the character ó.
The command
C:\temp> type o_src.txt
will print this character in cmd.exe
¾
If I execute
C:\temp>type o.txt
(o.txt from TEST 1) the result is ó
Test 3
After execution of the command
C:\temp> type o_src.txt > o_dst.txt
then the contents of o_src.txt and o_dst.txt are the same.
How does this work?
ASCII code of ó: F3 / 243
ASCII code of ¢: A2 / 162
ASCII code of ¾: BE / 190

I believe you need to change the code page using CHCP. Look at these questions for more info.
Batch script is not executed if chcp was called
What encoding/code page is cmd.exe using
Unicode characters in Windows command line - how?

Related

Can't output certain line to batch file

I'm using a batch file to create an RDP file using various variables to populate the contents.
Every line uses an Echo command and then outputs to a file with >>
For instance -
#echo screen mode id:i:1>> "C:\TEMP\file.RDP"
#echo use multimon:i:1>> "C:\TEMP\file.RDP"
Whilst this works for every line, one single line is giving me a problem and will not output -
#echo selectedmonitors:s:2,0>> "C:\TEMP\file.RDP"
For some reason, this line actually outputs selectedmonitors:s:2, (the 0 disappears) to the command window and outputs nothing into the .RDP file.
Whilst #echo selectedmonitors:s:2,0 works in the command window and outputs as expected, I can't output to a file.
What's going wrong here?
>> is just an abbreviation for 1>>, where 1 is an output stream.
There are ten of those streams:
0 is STDIN (Input) and not allowed for redirecting output.
1 is STDOUT("normal" output), 2 is STDERR (error output)
and 3 to 9 are not defined (but usable).
Remove the # to see what happens:
A batch file like
echo selectedmonitors:s:2,0>>file.txt
shows as executed command:
echo selectedmonitors:s:2, 0>>file.txt
which tries to redirect Stream 0 (STDIN) (which holds nothing here) to the file.
The reason your other lines are working is that , is a standard delimiter and : is not, so the comma snips the zero off the echo and adds it to the redirection while the colon doesn't.
Two possible workarounds:
>>file.txt echo selectedmonitors:s:2,0
(echo selectedmonitors:s:2,0)>>file.txt
Try the following, instead.
#(echo selectedmonitors:s:2,0)>> "C:\TEMP\file.RDP"
Without the parentheses, and since the , comma works as a delimiter in batch command lines (see cmd- comma to separate parameters Compared to space? for example) the last token in the command is parsed as 0>> "C:\TEMP\file.RDP" which literally means "append stream 0 output to the given file". Since stream 0 is the standard input stream, this is invalid and ignored, but the "0" parameter gets "eaten" in the process.

Why are the contents of my batch file being interpreted as alt codes?

I'm using a batch file to execute some adb commands. When trying to do a longpress of the power key I use the following line:
adb -s <ipaddress>:5555 shell input keyevent --longpress 26.
If I type this command into cmd, it works without a hitch. Running it from the batch file, however, results in a short press. I created a single line batch file, with the above command as the sole contents. When running the batch file (I just type the file name in cmd), the command is printed as:
adb -s <ipaddress>:5555 shell input keyevent -ΓÇôlongpress 26
Is there a setting I may have unknowingly enabled that is causing this, or do I need some sort of escape character?
I'm rather embarrassed that I came across a solution to my issue only a few minutes after posting this, but I figure I should share and not waste anyone's time.
I've replaced the second hyphen in my command with its own alt code (i.e. alt 45) and it is now interpreted correctly in the batch file. The line still reads:
adb -s <ipaddress>:5555 shell input keyevent --longpress 26
I don't understand why this works, and would appreciate it if someone would shed light on the subject.
Edit: Based off the recommendation of the comment below, I looked up the differences between encoding schemes. If I understand it correctly, when encoding in ASCII or ANSI, characters are limited to 7 bits of data. This will keep characters in the first 128 members of the ASCII table, so the alt codes I saw previously couldn't be generated.

printf not printing the same as fprintf [duplicate]

This question already has an answer here:
(C) Program that prints all CP850 characters on the screen and in a file have different outputs
(1 answer)
Closed 6 years ago.
I'm making a program in C for a project where it as to print to a file everything it prints to the console. The problem is that I have to print some special characters like 'Ç', so I use the ascii codes and it printd fine to the console however what it prints to the file is incorrect. Here is an example:
printf(" %c", 128);
output to console: Ç
fprintf(output, " %c", 128);
output to file: €
I ran the command chcp in cmd and it tells me I'm using code page 850 and I used those asci codes, so I don't know what is the problem. The program writes to a notepad txt file.
Ç is 128 in code page 437 or 850 etc., encodings which are sometimes used by Windows consoles. The same code 128 is € in code page 1252 or 1250, encodings which are quite often used by Windows graphical applications. The only reasonable way to proceed is to have your consoles use the same encoding as the graphical applications; for this, you can use the command chcp 1252 (change code page) in the console at the command prompt.
(Note: for chcp to be effective, the console must use a TrueType font such as Lucida Console or Consolas.)
Your command line (console) and whatever you use to display the file use different encodings.
Both times the byte 128 is written, but in some Extended ASCII variant (see also Wikipedia) it is interpreted as a C with cedilla,
whereas a common Windows encoding interprets it as the Euro symbol.

Escape character for '£' in batch file

I am trying to execute a program from command line where there will be parameters. In my password there is a symbol '£', which I could not find to escape.
It is always good to enclose a parameter string like a quite good password containing also other characters than ASCII letters and numbers in double quotes.
But care must be taken on using characters in batch files which are not from ASCII table, i.e. the code point value (byte value) of the character is greater 127 decimal.
On using Windows Notepad to write a batch file and saving the file with ANSI encoding, the characters with a code point value greater 127 are saved using the code page according to Windows Region and Language settings. For North American and Western European countries this means using code page Windows-1252. The pound sign has decimal value 163 (hexadecimal: A3) in this code page.
But in a command process a different code page is used which can be seen by opening a command prompt window and run the command CHCP (change code page) without any parameter. This command outputs the active code page for command process which depends also on Windows Region and Language settings. The code page OEM 437 is used in North American countries and OEM 850 in Western European countries by default within a command process. The pound sign has the decimal value 156 in code page 437 as also in code page 850.
In other words you need to know what the application which compares the password expects for the pound sign in password:
A byte with value 163 as the password was defined using a GUI application.
A byte with value 156 as the password was defined from within a command prompt window.
Or 1 or even more other byte values depending on the code page and character encoding (ANSI, OEM, UTF-8, UTF-16) used as the password with pound sign was defined. For example UTF-8 character encoding uses 2 bytes with the decimal values 194 and 163 to encode a pound sign.
So what to write into the batch file?
Well, you have to find that out by yourself.
For example the password was defined from within a command prompt window using code page 850 and so the pound sign in stored password is a single byte with value 156. The batch file is edited in Notepad using code page 1252 and therefore the character œ must be used in password to have a byte with value 156 in the batch file in password string.
Thank you for your detailed answer #Mofi.
Background: My CMD program calls SQLPlus and the database password contains a '£'.
Summing this up into a short fix, the following steps worked for me.
The fix:
Open your script in a robust text editor (e.g. Atom, Notepad++,
etc)
Change the file encoding (of the text editor) to CP-1252
Add chcp 1252>nul to the top of your script
Run your script and enjoy the results!
As you have found, handling of the UK pound sign is a trap for the unwary in batch files.
The issue here is that a UK pound sign £ is not an ascii character, so is processed differently by the command prompt and Windows GUI programs like Notepad.
A solution that worked for me was to change the code page in the batch file to 650001 for unicode before using the £ sign.
This idea was discussed at Change the active console Code Page, which explains that the default code page is determined by the Windows Locale.
For example, put this code at the start of your batch file:
#echo off
:: Change the code page to Unicode/65001 before using non-ascii characters.
chcp 65001

Question about K&R - redirect input

In section 1.6 of 'The C Programming Language' (K&R) there is an example program and the authors state:
The output of this program ON ITSELF is
digits = 9 3 0 0 0 0 0 0 0 1, white space = 123, other = 345
Then there are many similar programs etc. including exercises. I understand everything about the logic of the code and can do the exercises, but how do I actually test my program on a file like the authors or many others on the web?
Edit: The question should be: How can I redirect the input of a file to the program?
The program in chapter 1.6 reads input from stdin. To make it read from a file, you can (on most operating systems) redirect stdin to be a file by running your program like this:
myprogram < somefile
Or you can pipe the content of a file to it like so:
cat somefile | myprogram
On windows, you'd use the type program instead of cat,
type somefile | myprogram
This is using re-direction. Instead of the input to the program coming from the keyboard it comes from a file.
At the DOS prompt:-
C:>myexe < filename
Get to the DOS prompt in Windows use the command shell. Or start Run.. and enter cmd
On a Mac this is called terminal (type "terminal" into Searchlight to get to it).
By default, your program will take input from stdin, which is a buffer which is filled based on input from your keyboard (by default). However, you can also tell your program to fill stdin from a text file instead.
Using a *nix based system, you can simply create a text file, and save it as whatever you'd like, "test_input" for instance. Fill it with the input that you'd like to pass to your program, save it, and then run your program like this:
./a.out < test_input
This is called redirection because you are "redirecting" (if you will) the input to come from a file, rather than the default (keyboard). It goes both ways, you can also redirect your output to a file, rather than stdout with the other angle bracket, '>'.
Using Visual Studio, and not popping open a command prompt to do something like the command above, you can use a C++ ifstream, put the text file in the local directory, and then simply use the ifstream everywhere instead of stdin:
ifstream sin("test_input.txt" , ifstream::in);
int value;
sin >> value;
You can output to a file using an ofstream.
Note that ifstreams and ofstreams are C++ objects, and can't be used in C. While you can write to files and read from files in C, it's a little trickier than simply replacing all instances of cout and cin. You actually have to think about what you are reading and writing :)

Resources