Author Topic: Code fragment sought: user-specified file names  (Read 3073 times)

0 Members and 1 Guest are viewing this topic.

Offline MWheatley

  • Newbie
  • Posts: 64
    • View Profile
Code fragment sought: user-specified file names
« on: December 21, 2021, 11:00:33 am »
A job for over the holiday is to adapt an old program of mine so that it can accept a data file.  Nothing fancy, just numbers, one per line.

Rather than hard-code the file name into the program (which is what I tended to do, back in the day), I'm looking to specify it at run-time, in a user dialogue.

Does anyone have a code fragment that they'd share, showing how to do this?  Or is it as simple as inputting a string, and then entering that string in an OPEN# statement?

Malcolm

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Code fragment sought: user-specified file names
« Reply #1 on: December 21, 2021, 11:38:41 am »
A job for over the holiday is to adapt an old program of mine so that it can accept a data file.  Nothing fancy, just numbers, one per line.

Rather than hard-code the file name into the program (which is what I tended to do, back in the day), I'm looking to specify it at run-time, in a user dialogue.

Does anyone have a code fragment that they'd share, showing how to do this?  Or is it as simple as inputting a string, and then entering that string in an OPEN# statement?

Malcolm

Yeah if likely know the file name then just Input it, otherwise I suggest a Filename Dialog to navigate folders and select a file off lists. Been done many times here at this forum. Try a search on Filename or Filename Dialog?

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Code fragment sought: user-specified file names
« Reply #2 on: December 21, 2021, 11:52:16 am »
I think this is best File Dialog I've found so far (If you don't want to just Input the filename):

Code: QB64: [Select]
  1. ' fixed 2021-11-16 for folders or files OVER 32,000+ Integer Range
  2. ' ref 2021-11-09 Steve update GetLists:  https://www.qb64.org/forum/index.php?topic=4360.msg138031#msg138031
  3. Sub GetLists (SearchDirectory As String, DirList() As String, FileList() As String)
  4.     ' Thanks SNcNeill ! for a cross platform method to get file and directory lists
  5.     'put this block in main code section of your program close to top
  6.     '' direntry.h needs to be in QB64 folder '<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  7.     'Declare CustomType Library ".\direntry"
  8.     '    Function load_dir& (s As String)
  9.     '    Function has_next_entry& ()
  10.     '    Sub close_dir ()
  11.     '    Sub get_next_entry (s As String, flags As Long, file_size As Long)
  12.     'End Declare
  13.  
  14.     ' fix 2021-11-16 I have a folder in Downloads that is over 40,000 files mostly HTML which caused subscript errors
  15.     ' change DirCount and FileCount to Long from Integer
  16.     Dim flags As Long, file_size As Long, DirCount As Long, FileCount As Long, length As Long
  17.     Dim nam$, slash$
  18.     ReDim _Preserve DirList(100), FileList(100)
  19.     DirCount = 0: FileCount = 0
  20.     $If WIN Then
  21.         slash$ = "\"
  22.     $Else
  23.         slash$ = "/"
  24.     $End If
  25.     If Right$(SearchDirectory$, 1) <> "/" And Right$(SearchDirectory$, 1) <> "\" Then SearchDirectory$ = SearchDirectory$ + slash$
  26.  
  27.     If load_dir(SearchDirectory + Chr$(0)) Then
  28.         Do
  29.             length = has_next_entry
  30.             If length > -1 Then
  31.                 nam$ = Space$(length)
  32.                 get_next_entry nam$, flags, file_size
  33.                 If _DirExists(SearchDirectory + nam$) Then
  34.                     DirCount = DirCount + 1
  35.                     If DirCount > UBound(DirList) Then ReDim _Preserve DirList(UBound(DirList) + 100)
  36.                     DirList(DirCount) = nam$
  37.                 ElseIf _FileExists(SearchDirectory + nam$) Then
  38.                     FileCount = FileCount + 1
  39.                     If FileCount > UBound(FileList) Then ReDim _Preserve FileList(UBound(FileList) + 100)
  40.                     FileList(FileCount) = nam$
  41.                 Else 'This else should never actually trigger
  42.                     Print: Print: Print "zzz...  Unknown file found: "; SearchDirectory; slash$; nam$, _DirExists(nam$)
  43.                     Beep: Sleep ' alert the user to
  44.                 End If
  45.             End If
  46.         Loop Until length = -1
  47.     End If
  48.     close_dir
  49.  
  50.     ReDim _Preserve DirList(DirCount)
  51.     ReDim _Preserve FileList(FileCount)

It's from this thread where we knocked out a few more bugs from previous code.
https://www.qb64.org/forum/index.php?topic=4360.0

Need this for above direntry.h in QB64.exe folder
Code: [Select]
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>

const int IS_DIR_FLAG = 1, IS_FILE_FLAG = 2;

DIR *pdir;
struct dirent *next_entry;
struct stat statbuf1;

char current_dir[FILENAME_MAX];
#ifdef QB64_WINDOWS
  #define GetCurrentDir _getcwd
#else
  #define GetCurrentDir getcwd
#endif

int load_dir (char * path) {
  struct dirent *pent;
  struct stat statbuf1;
//Open current directory
pdir = opendir(path);
if (!pdir) {
return 0; //Didn't open
}
return -1;
}

int has_next_entry () {
  next_entry = readdir(pdir);
  if (next_entry == NULL) return -1;
 
  stat(next_entry->d_name, &statbuf1);
  return strlen(next_entry->d_name);
}

void get_next_entry (char * nam, int * flags, int * file_size) {
  strcpy(nam, next_entry->d_name);
  if (S_ISDIR(statbuf1.st_mode)) {
    *flags = IS_DIR_FLAG;
  } else {
    *flags = IS_FILE_FLAG;
  }
  *file_size = statbuf1.st_size;
  return ;
}

void close_dir () {
  closedir(pdir);
  pdir = NULL;
  return ;
}

int current_dir_length () {
  GetCurrentDir(current_dir, sizeof(current_dir));
  return strlen(current_dir);
}

void get_current_dir(char *dir) {
  memcpy(dir, current_dir, strlen(current_dir));
  return ;
}

« Last Edit: December 21, 2021, 12:00:34 pm by bplus »

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Code fragment sought: user-specified file names
« Reply #3 on: December 21, 2021, 11:54:52 am »
Easiest way is just:

DO
    INPUT "File to open:"; file$
    IF file$ = "" THEN END 'End of program if user enters blank file name; this line is optional
    IF _FILEEXISTS(file$) THEN OPEN file$ FOR INPUT AS #1 'check to make certain file exists, in case the user entered a typo in their input
LOOP
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline MWheatley

  • Newbie
  • Posts: 64
    • View Profile
Re: Code fragment sought: user-specified file names
« Reply #4 on: December 21, 2021, 12:10:12 pm »
Thanks, both!  I did the seach, and found examples.  But SMcNeill's "easy" code fragment suits my needs fine.

Thanks again.

Malcolm