Author Topic: Playing around with a SAVE/OPEN routine...  (Read 3932 times)

0 Members and 1 Guest are viewing this topic.

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Playing around with a SAVE/OPEN routine...
« on: January 22, 2021, 12:51:53 pm »
I mostly hard coded names for files, and I know I did something like this decades ago, but for now, I'm just writing new code. What I intend to do is create a method to open and save files from a menu selection, which is easy, but also from user typed input. The code below is my attempt at idiot proofing the later. It roots out illegal file characters, separates drive, directory, and file name, adds .txt to a text file, etc. At present, it allows something other than a .txt extension. Notepad would take a .bas extension, and make it .bas.txt, if the .txt default fils type selection was left in place. I don't know if I want to copy that format, or not.

Oh, don't worry, the code will not write anything to your drive(s). It's just a mock routine to get the construct down. I hope that's the proper use of the term, construct, as in how the program flows through the process coded.

Code: QB64: [Select]
  1. operation$ = "save"
  2.  
  3. PRINT "/ \ : * ? < > | " + CHR$(34): PRINT
  4.  
  5.  
  6. doctype$ = "text"
  7.  
  8. drive$ = "": dir$ = ""
  9. illegal_file_symbols$ = "/\:*?<>|" + CHR$(34)
  10. ifs$ = illegal_file_symbols$ ' I just used this to shorten the name until I do a universal replacement.
  11.  
  12. ' Determine if there is a drive and/or directory in the input.
  13. IF MID$(a$, 2, 2) = ":\" THEN
  14.     IF LEFT$(UCASE$(a$), 1) >= "A" AND LEFT$(UCASE$(a$), 1) <= "Z" THEN
  15.         drive$ = MID$(a$, 1, 3)
  16.         a$ = MID$(a$, 4)
  17.     ELSE
  18.         BEEP
  19.     END IF
  20.  
  21. IF INSTR(a$, "\") THEN
  22.     dir$ = MID$(a$, 1, _INSTRREV(a$, "\"))
  23.     a$ = MID$(a$, LEN(dir$) + 1)
  24.  
  25.     IF LEN(drive$) THEN
  26.         IF _DIREXISTS(drive$) THEN
  27.         ELSE
  28.             flag% = 1
  29.         END IF
  30.     END IF
  31.     IF flag% THEN EXIT DO
  32.  
  33.     IF LEN(dir$) THEN
  34.         IF _DIREXISTS(drive$ + dir$) THEN
  35.         ELSE
  36.             flag% = 2
  37.         END IF
  38.     END IF
  39.     IF flag% THEN EXIT DO
  40.  
  41.     FOR i% = 1 TO LEN(ifs$)
  42.         IF INSTR(a$, MID$(ifs$, i%, 1)) THEN flag% = 3: EXIT FOR
  43.     NEXT
  44.  
  45.     IF _FILEEXISTS(a$) THEN
  46.         IF operation$ = "save" THEN
  47.             flag% = 4
  48.         END IF
  49.     END IF
  50.  
  51.     EXIT DO
  52.  
  53. IF drive$ = "" THEN drive$ = MID$(_CWD$, 1, 3)
  54. IF dir$ = "" THEN dir$ = MID$(_CWD$, 4) ' Note: no traling backslash.
  55.  
  56. PRINT: PRINT "Drive = "; drive$; " Dir = "; dir$; " File = "; a$: PRINT
  57.  
  58. SELECT CASE flag%
  59.     CASE 0
  60.         IF doctype$ = "text" THEN ' Check for text extension.
  61.             IF INSTR(a$, ".") = 0 THEN a$ = a$ + ".txt"
  62.         END IF
  63.  
  64.         ' Okay to save.
  65.         PRINT "Saving file as: "; a$: PRINT
  66.     CASE 1
  67.         PRINT "Drive not found.": PRINT
  68.     CASE 2
  69.         PRINT "Directory not found.": PRINT
  70.     CASE 3
  71.         ' Illegal symbols in file name.
  72.         PRINT "Illegal file name."
  73.     CASE 4
  74.         IF operation$ = "save" THEN
  75.             PRINT "File Already Exists. Overwrite?": PRINT
  76.         END IF
  77.  
  78.  

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

FellippeHeitor

  • Guest
Re: Playing around with a SAVE/OPEN routine...
« Reply #1 on: January 22, 2021, 01:04:39 pm »
Nice to see _INSTRREV put to good use.

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Playing around with a SAVE/OPEN routine...
« Reply #2 on: January 22, 2021, 01:17:58 pm »
Yeah, _INSTRREV. I love that one. I had to make my own function for it, prior to its existence, so thanks for that.

I hope I'm not missing anything on this files routine. I hate to add stuff that can mess up files if there is some "bug" or mistake in the code. My present concern is TheBOB is trying out my WP at the QBasic Forum, and I want to make sure his stuff is protected when it reaches this level. I made a promise to Mac, long before he handed the forum over to me, that no matter how much kidding around I did or arguments I got into, never, never "piss off TheBOB!" So right now, my WP he is testing out just loads files, but doesn't save them. I told Bob about my concerns, and he shared with me a time when Mac tried one of his routines, and it did wipe out one of Mac's files, which he had no back up for. I don't know about the rest of you guys, but I always try to remember to search the text of any one's code before running it. I look for keywords like KILL, OUTPUT, and BINARY.

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

FellippeHeitor

  • Guest
Re: Playing around with a SAVE/OPEN routine...
« Reply #3 on: January 22, 2021, 01:21:12 pm »
I look for keywords like KILL, OUTPUT, and BINARY.

Better safe than sorry. However, with API calls and external C procedures, there's quite a bit more that could put you in danger if someone decided to get naughty.

Offline Dav

  • Forum Resident
  • Posts: 792
    • View Profile
Re: Playing around with a SAVE/OPEN routine...
« Reply #4 on: January 22, 2021, 05:46:18 pm »
(edited out double post...)
« Last Edit: January 22, 2021, 11:02:18 pm by Dav »

Offline Dav

  • Forum Resident
  • Posts: 792
    • View Profile
Re: Playing around with a SAVE/OPEN routine...
« Reply #5 on: January 22, 2021, 05:47:01 pm »
_INSTRREV flew under my radar until Steve pointed it out to me recently.  Great to have!

Notepad would take a .bas extension, and make it .bas.txt, if the .txt default fils type selection was left in place. I don't know if I want to copy that format, or not.

I didn't know this for a long while, but If you surround the filename in quotes notepad will save it as typed, and won't add the .txt extension.  At least not my notepad version.  "screen0hero.bas"  will be saved as screen0hero.bas, no .txt added.

EDIT: Sorry about the double post up there....I don't know what happened.  How do I delete it?

- Dav
« Last Edit: January 22, 2021, 07:03:12 pm by Dav »

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Playing around with a SAVE/OPEN routine...
« Reply #6 on: January 22, 2021, 10:39:56 pm »
Well here's basically the same routine; mock only, so it won't change a thing on your computer. Just some bells and whistles added. Try it in your local directory, and type in a file name that already exists.

Pete

Code: QB64: [Select]
  1. DIM SHARED mb.l AS INTEGER, action$
  2. DIM button$(4)
  3.  
  4. COLOR 0, 7
  5. enl% = 13: CALL windowscreen(enl%)
  6.  
  7. button$(1) = "Yes": button$(2) = "No!"
  8. button$(3) = "Retry": button$(4) = "Cancel"
  9. operation$ = "save"
  10.  
  11. LOCATE 5, 1
  12. LINE INPUT "Save File As: "; a$
  13.  
  14. doctype$ = "text"
  15.  
  16. drive$ = "": dir$ = ""
  17. illegal_file_symbols$ = "/\:*?<>|" + CHR$(34)
  18. ifs$ = illegal_file_symbols$
  19.  
  20. ' Determine if there is a drive and/or directory in input.
  21. IF MID$(a$, 2, 2) = ":\" THEN
  22.     IF LEFT$(UCASE$(a$), 1) >= "A" AND LEFT$(UCASE$(a$), 1) <= "Z" THEN
  23.         drive$ = MID$(a$, 1, 3)
  24.         a$ = MID$(a$, 4)
  25.     ELSE
  26.         BEEP
  27.     END IF
  28.  
  29. IF INSTR(a$, "\") THEN
  30.     dir$ = MID$(a$, 1, _INSTRREV(a$, "\"))
  31.     a$ = MID$(a$, LEN(dir$) + 1)
  32.  
  33.     IF LEN(drive$) THEN
  34.         IF _DIREXISTS(drive$) THEN
  35.         ELSE
  36.             flag% = 1
  37.         END IF
  38.     END IF
  39.     IF flag% THEN EXIT DO
  40.  
  41.     IF LEN(dir$) THEN
  42.         IF _DIREXISTS(drive$ + dir$) THEN
  43.         ELSE
  44.             flag% = 2
  45.         END IF
  46.     END IF
  47.     IF flag% THEN EXIT DO
  48.  
  49.     FOR i% = 1 TO LEN(ifs$)
  50.         IF INSTR(a$, MID$(ifs$, i%, 1)) THEN flag% = 3: EXIT FOR
  51.     NEXT
  52.  
  53.     IF _FILEEXISTS(a$) THEN
  54.         IF operation$ = "save" THEN
  55.             flag% = 4
  56.         END IF
  57.     END IF
  58.  
  59.     EXIT DO
  60.  
  61. IF drive$ = "" THEN drive$ = MID$(_CWD$, 1, 3)
  62. IF dir$ = "" THEN dir$ = MID$(_CWD$, 4) ' Note: no traling backslash.
  63.  
  64. PRINT: PRINT "Drive = "; drive$; " Dir = "; dir$; " File = "; a$: PRINT
  65.  
  66. SELECT CASE flag%
  67.     CASE 0
  68.         IF doctype$ = "text" THEN ' Check for text extension.
  69.             IF INSTR(a$, ".") = 0 THEN a$ = a$ + ".txt"
  70.         END IF
  71.  
  72.         ' Okay to save.
  73.         PRINT "Saving file as: "; a$: PRINT
  74.     CASE 1
  75.         PRINT "Drive not found.": PRINT
  76.     CASE 2
  77.         PRINT "Directory not found.": PRINT
  78.     CASE 3
  79.         ' Illegal symbols in file name.
  80.         PRINT "Illegal file name."
  81.     CASE 4
  82.         IF operation$ = "save" THEN
  83.             msg$ = "File Already Exists. Overwrite?"
  84.             button% = 2: button_index% = 0
  85.  
  86.             _DELAY .75: CALL popup(msg$, msg%, button$(), button%, button_index%)
  87.  
  88.             COLOR 0, 7
  89.  
  90.             SELECT CASE action$
  91.                 CASE "yes"
  92.                     PRINT "Overwriting file: "; a$: PRINT
  93.                 CASE "no", "close"
  94.                     PRINT "Save aborted.": PRINT
  95.             END SELECT
  96.         END IF
  97.  
  98.  
  99. SUB popup (msg$, msg%, button$(), button%, button_index%)
  100.     STATIC doctype%
  101.     iyy% = CSRLIN: ixx% = POS(0)
  102.     IF W3% = 0 THEN W3% = 5 ' Min.
  103.     IF W4% = 0 THEN W4% = LEN(msg$) + 4 ' Min
  104.  
  105.     IF W1% = 0 THEN
  106.         ' Auto-Center
  107.         W1% = _HEIGHT \ 2 - W3% \ 2 + .5
  108.         W2% = _WIDTH \ 2 - W4% \ 2 + .5
  109.     END IF
  110.  
  111.     oldsmode = smode: PCOPY 0, 1: SCREEN 0, 0, 1, 1: smode = 1
  112.  
  113.     LOCATE W1%, W2%, 0 ' Cursor hide
  114.     FOR I = 1 TO W3%
  115.         A$ = ""
  116.         COLOR 15, 1
  117.         LOCATE , W2%
  118.         A$ = A$ + SPACE$(W4% - LEN(A$))
  119.         PRINT A$;
  120.         IF I <> 1 THEN
  121.             COLOR 1, 0: PRINT CHR$(176)
  122.         ELSE PRINT
  123.         END IF
  124.     NEXT I
  125.     LOCATE , W2% + 1
  126.     COLOR 1, 0: PRINT STRING$(W4%, CHR$(176));
  127.     COLOR 14, 1
  128.     LOCATE W1%, W2%
  129.     PRINT CHR$(218); STRING$(W4% - 2, CHR$(196)); CHR$(191);
  130.     LOCATE W1% + W3% - 1, W2%
  131.     PRINT CHR$(192); STRING$(W4% - 2, CHR$(196)); CHR$(217);
  132.     FOR I = 1 TO W3% - 2
  133.         LOCATE W1% + I, W2%: PRINT CHR$(179);: LOCATE W1% + I, W2% + W4% - 1: PRINT CHR$(179);
  134.     NEXT I
  135.     LOCATE W1%, W2% + W4% - 2: COLOR 15, 1: PRINT "x";
  136.  
  137.     IF LEN(msg$) THEN
  138.         SELECT CASE msg%
  139.             CASE -1
  140.                 LOCATE W1% + 1, W2% + W4% \ 2 - LEN(msg$) \ 2
  141.                 PRINT msg$;
  142.             CASE 0
  143.                 COLOR 15, 1
  144.                 IF button% THEN
  145.                     LOCATE W1% + W3% \ 2 - 1, W2% + W4% \ 2 - LEN(msg$) \ 2
  146.                     PRINT msg$;
  147.                     j% = 0
  148.                     FOR i% = 1 TO button%
  149.                         j% = j% + LEN(button$(button_index% + i%)) + 2
  150.                     NEXT
  151.                     LOCATE W1% + W3% \ 2 + 1, W2% + W4% \ 2 - j% \ 2 - 1
  152.                     COLOR 0, 7
  153.                     mouselocator$ = STRING$(_WIDTH, "0"): mouselocator% = W1% + W3% \ 2 + 1
  154.                     k% = 0
  155.                     FOR i% = button_index% + 1 TO button_index% + button%
  156.                         IF k% THEN LOCATE , POS(0) + 2
  157.                         k% = k% + 1
  158.                         MID$(mouselocator$, POS(0)) = STRING$(LEN(button$(i%)) + 2, LTRIM$(STR$(k%)))
  159.                         PRINT SPACE$(LEN(button$(i%)) + 2);
  160.                     NEXT
  161.                     LOCATE W1% + W3% \ 2 + 1, W2% + W4% \ 2 - j% \ 2
  162.                     COLOR 0, 7
  163.                     k% = 0
  164.                     FOR i% = button_index% + 1 TO button_index% + button%
  165.                         IF k% THEN LOCATE , POS(0) + 4
  166.                         PRINT button$(button_index% + i%);
  167.                         k% = k% + 1
  168.                     NEXT
  169.                     tabx% = 0
  170.                     DO
  171.                         CALL user(b$, mx%, my%, alt%, altoff%, shift%, ctrl%, ctrlshift%)
  172.  
  173.                         IF LEN(b$) THEN
  174.                             SELECT CASE b$
  175.                                 CASE CHR$(13)
  176.                                     SELECT CASE tabx%
  177.                                         CASE 1
  178.                                             action$ = "yes"
  179.                                         CASE 2
  180.                                             action$ = "no"
  181.                                     END SELECT
  182.                                 CASE CHR$(27)
  183.                                     action$ = "close"
  184.                             END SELECT
  185.                         END IF
  186.  
  187.                         IF my% = W1% AND mx% = W2% + W4% - 2 THEN
  188.                             IF closex% = 0 THEN closex% = -1: LOCATE my%, mx%: COLOR 15, 4: PRINT "x";
  189.                         ELSE
  190.                             IF closex% THEN closex% = 0: LOCATE W1%, W2% + W4% - 2: COLOR 7, 1: PRINT "x";
  191.                         END IF
  192.  
  193.                         IF bhl% THEN IF bhl% = 1 AND my% <> mouselocator% OR bhl% = 1 AND MID$(mouselocator$, mx%, 1) = "0" THEN tabx% = 0: bhl% = 0
  194.                         IF b$ = CHR$(9) THEN tabx% = tabx% + 1: IF tabx% > button% THEN tabx% = 1
  195.                         IF oldmx% = mx% AND oldmy% = my% THEN i% = 0 ELSE i% = -1
  196.                         IF b$ = CHR$(9) OR my% = mouselocator% AND MID$(mouselocator$, mx%, 1) <> "0" AND i% THEN
  197.                             IF b$ = CHR$(9) THEN k% = tabx%: bhl% = 9 ELSE k% = VAL(MID$(mouselocator$, mx%, 1)): tabx% = k%: bhl% = 1
  198.  
  199.                             IF h% AND h% <> tabx% THEN
  200.                                 COLOR 0, 7
  201.                                 LOCATE W1% + W3% \ 2 + 1, INSTR(mouselocator$, LTRIM$(STR$(h%)))
  202.                                 PRINT SPACE$(1) + button$(h%) + SPACE$(1);
  203.                             END IF
  204.  
  205.                             h% = k%: tabx% = h%
  206.  
  207.                             COLOR 0, 3
  208.                             LOCATE W1% + W3% \ 2 + 1, INSTR(mouselocator$, LTRIM$(STR$(h%)))
  209.                             PRINT SPACE$(1) + button$(h%) + SPACE$(1);
  210.                             _DELAY .15
  211.                         ELSE
  212.                             IF h% AND tabx% = 0 THEN
  213.                                 COLOR 0, 7
  214.                                 LOCATE W1% + W3% \ 2 + 1, INSTR(mouselocator$, LTRIM$(STR$(h%)))
  215.                                 PRINT SPACE$(1) + button$(h%) + SPACE$(1);
  216.                                 h% = 0: tabx% = 0
  217.                             END IF
  218.                         END IF
  219.  
  220.                         IF mb.l THEN
  221.                             IF closex% THEN SOUND 1000, .1: closex% = 0: action$ = "close"
  222.                             IF my% = mouselocator% AND MID$(mouselocator$, mx%, 1) <> "0" THEN
  223.                                 SOUND 1000, .1
  224.                                 SELECT CASE VAL(MID$(mouselocator$, mx%, 1))
  225.                                     CASE 1
  226.                                         action$ = "yes"
  227.                                     CASE 2
  228.                                         action$ = "no"
  229.                                 END SELECT
  230.                             END IF
  231.                         END IF
  232.  
  233.                         IF b$ = CHR$(9) THEN b$ = ""
  234.                         oldmy% = my%: oldmx% = mx%
  235.                     LOOP UNTIL LEN(action$)
  236.                     smode = oldsmode: SCREEN 0, 0, smode, smode
  237.                 ELSE
  238.                     LOCATE W1% + W3% \ 2, W2% + W4% \ 2 - LEN(msg$) \ 2
  239.                     PRINT msg$;
  240.                 END IF
  241.  
  242.         END SELECT
  243.     END IF
  244.     LOCATE iyy%, ixx%
  245.  
  246. SUB user (b$, mx%, my%, alt%, altoff%, shift%, ctrl%, ctrlshift%)
  247.  
  248.     DEF SEG = 0
  249.     IF PEEK(1047) MOD 16 = 1 OR PEEK(1047) MOD 16 = 2 THEN shift% = -1 ELSE shift% = 0
  250.     IF PEEK(1047) MOD 16 = 3 OR PEEK(1047) MOD 16 = 4 THEN ctrl% = -1 ELSE ctrl% = 0
  251.     IF PEEK(1047) MOD 16 = 5 OR PEEK(1047) MOD 16 = 6 THEN ctrlshift% = -1 ELSE ctrlshift% = 0
  252.  
  253.     IF PEEK(1047) MOD 16 = 7 OR PEEK(1047) MOD 16 = 8 THEN
  254.         alt% = -1
  255.     ELSE
  256.         IF alt% THEN altoff% = -1: alt% = 0 ELSE altoff% = 0: alt% = 0
  257.     END IF
  258.     DEF SEG
  259.  
  260.     b$ = INKEY$
  261.  
  262.     mb.w = 0
  263.         mb.w = mb.w + _MOUSEWHEEL
  264.     WEND
  265.  
  266.     mb.l% = _MOUSEBUTTON(1)
  267.     mb.r% = _MOUSEBUTTON(2)
  268.     mx% = _MOUSEX
  269.     my% = _MOUSEY
  270.  
  271. SUB windowscreen (ENL%)
  272.     IF displayfullscreen% = -1 THEN EXIT SUB
  273.     WINXX1% = CSRLIN: WINYY1% = POS(1)
  274.     winmode$ = "2"
  275.  
  276.     IF ENL% <> 0 THEN
  277.         full = _FULLSCREEN
  278.         IF full = 0 THEN
  279.             SELECT CASE ENL%
  280.                 CASE -1: IF SCRNSIZE% > 0 THEN ELSE EXIT SUB
  281.                 CASE 1: IF SCRNSIZE% < 14 THEN ELSE EXIT SUB
  282.             END SELECT
  283.         ELSE
  284.             EXIT SUB
  285.         END IF
  286.     END IF
  287.  
  288.     SCRNSIZE% = SCRNSIZE% + ENL%
  289.  
  290.     SELECT CASE winmode$
  291.         CASE "1"
  292.             full = _FULLSCREEN
  293.             IF full <> 0 THEN _FULLSCREEN _OFF
  294.             GOSUB ChangeFont
  295.         CASE "2"
  296.             full = _FULLSCREEN
  297.             IF full <> 0 THEN _FULLSCREEN _OFF
  298.             style$ = "MONOSPACE"
  299.             fontsize% = SCRNSIZE% + 13
  300.             IF fontsize% < 14 THEN winmode$ = ""
  301.             IF fontsize% < 18 THEN style$ = style$ + ", BOLD"
  302.             fontpath$ = ENVIRON$("SYSTEMROOT") + "\fonts\lucon.ttf" 'Find Windows Folder Path.
  303.             GOSUB ChangeFont
  304.         CASE "3"
  305.             GOSUB ChangeFont
  306.             _FULLSCREEN _SQUAREPIXELS
  307.             full = _FULLSCREEN
  308.             IF full = 0 THEN GOSUB nofull
  309.         CASE "4"
  310.             GOSUB ChangeFont
  311.             _FULLSCREEN _STRETCH
  312.             full = _FULLSCREEN
  313.             IF full = 0 THEN GOSUB nofull
  314.     END SELECT
  315.  
  316.     LOCATE WINXX1%, WINYY1%
  317.     EXIT SUB
  318.  
  319.     nofull:
  320.     RETURN
  321.  
  322.     ChangeFont:
  323.     IF winmode$ <> "2" THEN
  324.         _FONT 16 'select inbuilt 8x16 default font
  325.         currentf& = _FONT
  326.     ELSE
  327.         currentf& = _LOADFONT(fontpath$, fontsize%, style$)
  328.         _FONT currentf&
  329.     END IF
  330.  
  331.     IF currentf& <> f& AND f& <> defaultf& THEN _FREEFONT f&
  332.     f& = currentf&
  333.     RETURN
  334.  
  335.  

@Dav, you can't delete the whole post, but you could remove the contents. The double post probably happened because you held down that shi*t + arrow key when you posted! :D
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline euklides

  • Forum Regular
  • Posts: 128
    • View Profile
Re: Playing around with a SAVE/OPEN routine...
« Reply #7 on: January 23, 2021, 05:12:47 am »
Some hidden symbols can be used in file names...
I remember a case where I was unable to open a file.I made a lost of tests to understand. I don't remember what hidden symbol it was [ chr$(0) ??? ]

So testing each character of the file name to be sure that there is no symbol under value 32 could be a additional control ? 
Why not yes ?

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Playing around with a SAVE/OPEN routine...
« Reply #8 on: January 23, 2021, 07:49:56 am »
Some hidden symbols can be used in file names...
I remember a case where I was unable to open a file.I made a lost of tests to understand. I don't remember what hidden symbol it was [ chr$(0) ??? ]

So testing each character of the file name to be sure that there is no symbol under value 32 could be a additional control ?

Those used to work back in the days of DOS, but nobody bothers with them any longer, thanks to the graphical file explorers.  CHR$(0) wasn’t allowed, I don’t believe, but CHR$(255) was.  All you had to do is hold down ALT, and then type 2,5,5 sequentially on the numpad, before releasing ALT. ;)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Playing around with a SAVE/OPEN routine...
« Reply #9 on: January 23, 2021, 11:31:59 am »
You know on Mac machines, most of those excluded characters in the code are accepted. I'm not sure about Linux, I'd have to decide if I want to add an OS detection function, and further define my unaccepted character parameters. Of course there is always the easy way out, which works for ascii characters requiring special alt key inputs. Tha's to make an error handler. If QB64 can't create the file, the error handler does the work!

Pete 
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/