string – Why does CALL SET work differently in a CMD Windows versus a .CMD file? – Stack Overflow

Comparing strings in 8086 real mode

use AX for comparing, it’s changed anyways; there’s no need to clobber anything else; and let the CPU do the “pointer calculation”, you can read from [BX 2], there’s no need to change it

mov bx, REBOOT_CMD
call is_cmd
or ax, ax
jz reboot_cmd

is_cmd:
   mov ax, [bx]
   cmp ax, [BUFFER]          ; [buffer] with [bx]
   jne is_cmd_no
   mov ax, [bx 2]
   cmp ax, [BUFFER 2]        ; [buffer 2] with [bx 2]
   jne is_cmd_no
   mov ax, 1                 ; is_cmd_yes
   ret
is_cmd_no:
   xor ax, ax
   ret

or even better, inline it into the use-case

is_reboot:
   mov ax, [REBOOT_CMD]
   cmp ax, [BUFFER]          ; [buffer] with "rs"
   jne no_reboot
   mov ax, [REBOOT_CMD 2]
   cmp ax, [BUFFER 2]        ; [buffer 2] with "et"
   jz reboot_cmd
no_reboot:

note: the 2 branches differ, first is a “jne”, second a “jz” to the reboot case. it’s like an “AND” in C, where the 2nd part of the expression is only evaluated, if the first had TRUE as result

if you feel like obfuscting if, even the “BUFFER db “rset”,0″ is obsolete, you could compare [BUFFER] with “rs” ( which is “s” 0x100 * “r” = 0x7372 ) and [BUFFER 2] with “et” ( = “e” 0x100 * “t” = 0x7465 ):

is_reboot:
   cmp word ptr [BUFFER],0x7372          ; [buffer] with "rs"
   jne no_reboot
   cmp word ptr [BUFFER 2],0x7465        ; [buffer 2] with "et"
   jz reboot_cmd
no_reboot:

How to search string for slashes or colon on windows command line or in batch file?

The commands SET and IF can be used to check if a string assigned to an environment variable contains a specific character or string.

Example:

@echo off
setlocal EnableExtensions
for %%I in ("C:UsersMikeW" "FolderFileName" "Folder or file name") do call :ColonBackslash %%I
endlocal
goto :EOF

:ColonBackslash
set "Argument=%~1"

rem Substitute in argument string all colons by nothing and compare this
rem string with unmodified argument string. The argument string contains
rem a colon if the modified and the unmodified strings are not equal.

if not "%Argument::=%" == "%Argument%" (
    echo Colon in argument:        %Argument%
    goto :EOF
)

rem Substitute in argument string all backslashes by nothing and compare
rem this string with unmodified argument string. The argument string
rem contains a backslash if the modified and the unmodified strings
rem are not equal.

if not "%Argument:=%" == "%Argument%" (
    echo Backslash in argument:    %Argument%
    goto :EOF
)
echo No colon or backslash in: %Argument%
goto :EOF

This batch file outputs:

Colon in argument:        C:UsersMikeW
Backslash in argument:    FolderFileName
No colon or backslash in: Folder or file name

Comparing strings with substituted characters/strings with unmodified string can be used to determine type of input string as demonstrated with the batch code below:

@echo off
setlocal EnableExtensions
for %%I in ("C:UsersMikeW" "C:UsersMi:keW" "documentation" "\serversharefolder" "\serversharefolder1..folder2" "\serversharefo:lder" "\server" "\serversharefolder.." "%SystemRoot%.." ".Folder" "....Folder" "Windows" ">:Invalid") do call :classifyInput %%I
endlocal
goto :EOF

:classifyInput
rem Subroutine called with no parameter or with just "" as parameter.
if "%~1" == "" goto :EOF
set "Argument=%~1"
rem Replace all forward slashes by backslashes in argument string.
set "Argument=%Argument:/=%"

rem Is the second character a colon and third character a backlash?
if "%Argument:~1,2%" == ":" goto AbsolutePath

rem Is there a colon anywhere else than at second position in argument?
rem C:Folder is interpreted as invalid argument and not as relative
rem path to subfolder "Folder" of current directory on drive C:.
if not "%Argument::=%" == "%Argument%" (
    echo Invalid argument:  %1
    goto :EOF
)

rem Starts the argument with two backslashes?
if "%Argument:~0,2%" == "\" goto PathUNC

rem Starts the argument with  for a path relative to current drive?
if "%Argument:~0,1%" == "" (
    echo Relative path:     %1
    goto :EOF
)

rem Starts the argument with . for a path relative to current directory?
if "%Argument:~0,2%" == "." (
    echo Relative path:     %1
    goto :EOF
)

rem Starts the argument with .. for a path relative to parent directory?
if "%Argument:~0,3%" == ".." (
    echo Relative path:     %1
    goto :EOF
)

rem Contains the argument a backslash for a path relative to current directory?
if not "%Argument:=%" == "%Argument%" (
    echo Relative path:     %1
    goto :EOF
)

echo Name without path: %1
goto :EOF

:AbsolutePath
set "Remaining=%Argument:~2%"
rem Is there a colon anywhere else after second position in argument?
if not "%Remaining::=%" == "%Remaining%" (
    echo Invalid argument:  %1
    goto :EOF
)

rem Is the first character a drive letter if second character is a colon?
set "FirstIsLetter="
for /F "delims=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" %%# in ("%Argument:~0,1%") do set "FirstIsLetter=%%#"
if not "%FirstIsLetter%" == "" (
    echo Invalid argument:  %1
    goto :EOF
)

rem Contains the absolute path also . or .. in path?
if "%Argument:.=%" == "%Argument%" (
    echo Absolute path:     %1
) else (
    echo Abs.   rel. path:  %1
)
goto :EOF

:PathUNC
rem Does the UNC path contain also a colon?
if not "%Argument::=%" == "%Argument%" (
    echo Invalid argument:  %1
    goto :EOF
)

set "ServerName="
set "ShareName="
set "Remaining="
for /F "tokens=1,2* delims=" %%A in ("%Argument%") do (
    set "ServerName=%%A"
    set "ShareName=%%B
    set "Remaining=%%C"
)

rem Is there no share name specified after server name in UNC path?
if "%ShareName%" == "" (
    echo Invalid argument:  %1
    goto :EOF
)

rem Is there an invalid share name specified after server name in UNC path?
if "%ShareName%" == "." (
    echo Invalid argument:  %1
    goto :EOF
)

rem Is there an invalid share name specified after server name in UNC path?
if "%ShareName%" == ".." (
    echo Invalid argument:  %1
    goto :EOF
)

rem Contains the UNC path also . or .. in remaining path?
if "%Remaining:.=%" == "%Remaining%" (
    echo UNC path:          %1
) else (
    echo UNC    rel. path:  %1
)
goto :EOF

The output is:

Absolute path:     "C:UsersMikeW"
Invalid argument:  "C:UsersMi:keW"
Name without path: "documentation"
UNC path:          "\serversharefolder"
UNC    rel. path:  "\serversharefolder1..folder2"
Invalid argument:  "\serversharefo:lder"
Invalid argument:  "\server"
UNC    rel. path:  "\serversharefolder.."
Abs.   rel. path:  "C:WINDOWS.."
Relative path:     ".Folder"
Relative path:     "....Folder"
Relative path:     "Windows"
Invalid argument:  ">:Invalid"

But this batch code is not complete for checking for invalid paths, folder or file names in an argument string. There are still a lot of possible errors not detected by this batch code.

:/>  Настройка яркости экрана на Windows 10: как ее увеличить или уменьшить на ноутбуке или стационарном компьютере

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

It would be better to let Windows kernel check if the argument specifies an existing folder or file independent if the argument string is without or with a path of any type and being valid at all. See the topics:

And in case of testing for validity on non existing folder/file, just create the file/folder, suppress the error message using 2>nul (see the Microsoft article Using command redirection operators) and check with if errorlevel 1 or with if exist "%~1" if the folder/file could be created successfully, or if this operation failed because of an invalid folder/file name string, denied access, missing permissions, etc.

Online compiler(online gdb)works correctly while g and gcc on windows 10 cmd doesn’t work when comparing strings

When I compare 2 strings in the website “online gdb”, if the comparison is equal it gives 10, if it’s not it doesn’t give 10(It’s already weird that it gives 10 instead of 0, but it works so I didn’t care). But since I tried to compile my code with g or gcc(I tried with -g too for both)it gives -1 or 1, or only 1, but never 0. Thanks to everyone which will read this code and will help me.

#include <stdio.h>
#include <math.h>
#include <string.h>

int main()
{
    char v1q[55], v2q[55], v3q[55], v4q[55];
    float v1, v2, v3, v4, vr, min, max;
    int comparison;
    int v3b = 1;

printf("Per la prima banda non esiste l'oro e l'argento;nPer la seconda banda non esiste l'oro e l'argento;nPer la terza banda non esiste il bianco;nPer la quarta banda esistono SOLO il bianco, oro e argento.nn");

printf("Prima cifra: ");
fgets(v1q, sizeof(v1q), stdin);


if(strcmp(v1q, "nero") == 0)
{
    printf("nNon esiste un valore per il nero, per la prima banda");
}
if(strcmp(v1q, "marrone") == 0)
{
    v1 = 10;
}
if(strcmp(v1q, "rosso") == 0)
{
    v1 = 20;
}
if(strcmp(v1q, "arancione") == 0)
{
    v1 = 30;
}
if(strcmp(v1q, "giallo") == 0)
{
    v1 = 40;
}
if(strcmp(v1q, "verde") == 0)
{
    v1 = 50;
}
if(strcmp(v1q, "blu") == 0)
{
    v1 = 60;
}
if(strcmp(v1q, "viola") == 0)
{
    v1 = 70;
}
if(strcmp(v1q, "grigio") == 0)
{
    v1 = 80;
}
if(strcmp(v1q, "bianco") == 0)
{
    v1 = 90;
}
if(strcmp(v1q, "oro") == 0)
{
    printf("nNon esiste un valore per l'oro, per la prima banda");
}
if(strcmp(v1q, "argento") == 0)
{
    printf("nNon esiste un valore per l'argento, per la prima banda");
}
comparison = strcmp(v1q, "marrone");
printf("%d", comparison);
}

Why does call set work differently in a cmd windows versus a .cmd file?

I am trying to use the Windows CMD SET string manipulation versions in a programmatic way. The two versions of SET are …

SET New_String=%String:Old_Text=New_Text%

In variable String replace Old_Text with New_Text, and return result in variable New_String.

SET New_String=%String:~Number_Of_Chars_To_Skip,Number_Of_Chars_To_Keep%

In variable String extract Number_Of_Chars_To_Keep after skipping Number_Of_Chars_To_Skip, and return result in variable New_String

Old_Text, New_Text, Number_Of_Chars_To_Skip, Number_Of_Chars_To_Keep must all be literals, not variables. So, typical usage would be like this …

SET New_String=%String:abcd=fghi%
SET New_String=%String:~2,4%

Usage like this won’t work …

SET New_String=%String:%Old_Text%=%New_Text%%
SET New_String=%String:~%Skip_Count%,%Keep_Count%%

To do the above two SETs you have to CALL SET, like …

CALL SET New_String=%%String:%Old_Text%=%New_Text%%%
CALL SET New_String=%%String:~%Skip_Count%,%Keep_Count%%%

So, I have this following test code fragment …

SET "Chars=" & SET "String=0123456789" & SET "Skip=1" & SET "Keep=3"
CALL SET Chars=%%String:~%Skip%,%Keep%%%
ECHO Chars="%Chars%" (expected to be "123")

From a CMD file this works correctly. The CALL has been expanded to SET Chars=%string:~1,3% and has returned the expected result 123. But, and a big but it is, from a CMD Window (with the same variables) the exact same CALL SET returns this …

23456789Skip%,3%%

Why doesn’t this work in a CMD Window? I researched around and haven’t found any info explaining why.

:/>  Как в CMD сменить кодировку? Русский текст в CMD

Windows command prompt: how to pass multi-line string parameters

I have a program that accepts a string parameter. I create a batch file that executes the program and a multiline string paramter. I also have a second parameter after the multiline string.

C:>MyProgram "This is a
multiline text" parameter2

When I run this, only the first line of string is included in the command and the subsequent lines and the second parameter are ignored. Is there any way to pass multiline string parameters?

Оставьте комментарий