0

I have a File named as Account.txt which contains the following data

Joey 1990  
Gordon 1984  
Clint 1992

What I would like to do is check if the username inputted by the user matches with the above names.
Upto now I am able to write this up

  @echo off  
:CheckUser  
set /p Uid="User: "  
echo %uid%  
set detailslocation=C:\Users\Troy\Desktop\Accounts.txt  
findstr /m "\<%uid%\>" "%detailslocation%" >nul 2>&1  
if %errorlevel% == 0 goto NextFunction    
color c  
echo Invalid User ID. Please enter again   
cls  
goto CheckUser  

The above code is an extracted from the Batch File I am trying to develop.
What I intend to do is check if the username inputted by the user matches with one in Accounts.txt (ie. the First word on every line)

The problem with above code is that it will work if I enter Joey (or any of the names mentioned). However it also accepts 1990 or 1984 or 1992. How do I limit it to check for only the first word of every line and not the second word.

Thanks. Also I am not a programmer by profession, So I would appreciate if you could explain me the reasoning behind your piece of code.

x0nar
  • 125
  • 2
  • 10
  • `findstr /mbi ...` `/b` switch matches only at beginning of line, `/i` is case insensitive so you may write `clint`, `CLINT`, `Clint`. As you see, you may group findstr options, `/b /i /m` is the same as `/bim`. Also, place `cls` prior to `echo Invalid ...` – elzooilogico May 27 '17 at 11:44
  • Note the escape code`\<` is beginning of word not line. so this indicates beggining of _any_ word in the line, not beggining of line. So, final `findstr` search pattern should be `findstr /mib "%uid%" ...` – elzooilogico May 27 '17 at 11:51
  • Also I was wondering how you would proceed if instead of first word it was the second word you wanted to check for. Thanks again. – x0nar May 27 '17 at 12:00
  • BTW `findstr /rmbic:"\<%uid%\>" "%detailslocation%" >nul 2>&1` will match exact word, thus you may distinguish `clint` and `clinton` – elzooilogico May 27 '17 at 12:19
  • Then you should use a for loop. `for /f "tokens=2 delims= " %%i in (%detailslocation%) do ( echo %%i | find /I "%uid%" >NUL 2>&1 && goto :found )` or `for /f "tokens=2 delims= " %%i in (%detailslocation%) do ( if /I "%%i" == "%uid%" goto :found )` First succedes with partial matches, the second only with exact matches. Both are case insensitive. – elzooilogico May 27 '17 at 12:26

2 Answers2

1

To check for the first word, use

findstr /ib /c:"%uid% " "%detailslocation%" >nul 2>nul

To check for the last word, use

findstr /ie /c:" %uid%" "%detailslocation%" >nul 2>nul

Since there is at least one space between the two columns; case-insensitive at the beginning or end, the keystring with the space immediately after or before as included in the constant string indicated by /c:"...".

Magoo
  • 77,302
  • 8
  • 62
  • 84
0

I would not use findstr for this task for several reasons: it requires to delimit whole words with special characters, it executes findstr.exe file for each one of the user input (it is inefficient) and it will become much more complex code if you later want to use the values associated to the names, that is, the account numbers.

I would use a solution based on arrays instead. In this case the file is read just once and the access to the defined values is immediate. This is the code:

@echo off

rem Put this just once at beginning of the program
setlocal EnableDelayedExpansion

rem Load the "account" array elements from the file
set detailslocation=C:\Users\Troy\Desktop\Accounts.txt
for /F "tokens=1,2" %%a in (%detailslocation%) do (
   set "account[%%a]=%%b"
)

rem Previous FOR is equivalent to execute these lines:
rem    set "account[Joey]=1990"
rem    set "account[Gordon]=1984"         etc...



rem After that, do the checking this way:
:CheckUser
set /p "Uid=User: "
if defined account[%Uid%] goto NextFunction
color c
echo Invalid User ID. Please enter again
pause
cls
goto CheckUser



rem You may get the account number in a very simple way:
:NextFunction
echo The account of %Uid% is !account[%Uid%]!

IMHO, all this code is simpler and self-explanatory that the findstr based one... You may read a detailed explanation of array management in Batch files at this answer.

Aacini
  • 65,180
  • 12
  • 72
  • 108