LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Create directory in CVI

Hi,

I want to create directory in CVI.  did not know that C does not have a native function for it.  I tried this code (with some built-in error checks) but it seems to have some errors:

 

int Folder_Make (char Folder[])
{
    //this function takes in argument with single forward slash(es) (FS),
    //replaces them with double FS, then try to create intended folder
    int     result      =   0;
    int     len_Folder  =   strlen (Folder);
    int     len_New;    
    int     FS_count    =   0;
    int     FS_last     =   0;  //last FS flag
    int     FS_max      =   5;  //max FS
    int     FS_pos [FS_max];
    char   *MyFolder;

    //count FS
    for (int i = 0; i < len_Folder; i++)
    {
        if (Folder [i] == '\\')
        {
            FS_pos [FS_count] = i;  //FS position
            FS_count++;             //FS count
        }
    }

    //add last FS if necessary
    if (Folder [len_Folder - 1] != '\\')    FS_last = 1;
    if ((FS_last) && (FS_count < FS_max))
    {
        FS_pos [FS_count] = len_Folder; //FS position
        FS_count++;
    }

    //check for consecutive FS prior to correction
    for (int i = 0; i < (FS_count - 1); i++)
    {
        if (FS_pos [i] == FS_pos [i + 1])   result = -1;
    }

    if (!result)    //still no error
    {
        len_New     =   len_Folder + FS_count;      if (FS_last)    len_New++;
        MyFolder    =   malloc (len_New + 1);

        for (int i = 0, j = 0; i < len_Folder; i++, j++)
        {
                                        MyFolder [j]        =   Folder [i];
            if (Folder [i] == '\\')
            {                           j++;
                                        MyFolder [j]        =   '\\';
            }

            if (i == len_Folder - 1)
            {                           j++;
                                        MyFolder [j]        =   '\\';
                if (FS_last)
                {                       j++;
                                        MyFolder [j]        =   '\\';
                }
            }
        }
                                        MyFolder [len_New]  =   '\0';   //null-termination
    }

    //create folder
    MakeDir (MyFolder);

    return result;
/*  error value
    -1      consecutive FS found
*/
}

 

please help.

0 Kudos
Message 1 of 3
(5,552 Views)

alright,

this code works, and it seems to be a more robust one.

 

int Folder_Make (char Folder[])
{
    //this function takes in argument with single forward slash(es) (FS),
    //replaces them with double FS, then try to create intended folder
    int     result      =   0;
    int     len_Folder  =   strlen (Folder);
    int     len_A;
    int     FS_count    =   0;
    int     FS_last     =   0;  //last FS flag
    char   *Folder_A;

    //count FS (1)
    for (int i = 0; i < len_Folder; i++)
    {
        if (Folder [i] == '\\')             FS_count++;     //FS count
    }

    //add last FS if necessary
    if (Folder [len_Folder - 1] != '\\')    FS_last = 1;
    if (FS_last)                            FS_count++;

    int     FS_pos [FS_count];
            FS_count = 0;           //FS count reset

    //count FS (2)
    for (int i = 0; i < len_Folder; i++)
    {
        if (Folder [i] == '\\')
        {
            FS_pos [FS_count] = i;  //FS position
            FS_count++;             //FS count
        }
    }

    if (FS_last)        FS_count++; //repeat due to FS_count reset

    //check for consecutive FS prior to correction
    for (int i = 0; i < (FS_count - 1); i++)
    {
        if (FS_pos [i] == FS_pos [i + 1])   result = -1;
    }

    if (!result)    //still no error
    {
        len_A       =   len_Folder + FS_count;      if (FS_last)    len_A++;
        Folder_A    =   malloc (len_A + 1);

        for (int i = 0, j = 0; i < len_Folder; i++, j++)
        {
                                                    Folder_A [j]        =   Folder [i];
            if (Folder [i] == '\\')     {   j++;    Folder_A [j]        =   '\\';   }
            if (i == len_Folder - 1)
            {                               j++;    Folder_A [j]        =   '\\';
                if (FS_last)            {   j++;    Folder_A [j]        =   '\\';   }
            }
        }
                                                    Folder_A [len_A]    =   '\0';   //null-termination
        //count FS_2 (1)
        int     len_Corrected   =   strlen (Folder_A);
        int     FS_count_2      =   0;
        int     FS_pos_2 [FS_count * 2];

        //check if path length is legible (260 max w/ null char)
        if ((len_Corrected + 1) >= 260)     result = -2;    

        if (!result)    //still no error
        {
            //count FS
            for (int i = 0; i < len_Corrected; i++)
            {
                if (Folder_A [i] == '\\')
                {
                    FS_pos_2 [FS_count_2] = i;  //FS position 2
                    FS_count_2++;               //FS count 2
                }
            }

            //recursively check and create folders
            char    Folder_B    [260];      //standard = 260 max char. w/ null char
            int     a, b, c, d, x;          //place holders

            SetBreakOnLibraryErrors (0);    //turn OFF alarm

            //copy string and recursively create folder
            for (int i = 3; i < FS_count_2; i++)
            {
                        memmove         (Folder_B, Folder_A, FS_pos_2 [i] + 1);
                                         Folder_B           [FS_pos_2 [i] + 1] = '\0';
                x   =   GetFileAttrs    (Folder_B, &a, &b, &c, &d);

                if (x != 1)     //not directory or not exist
                {
                    result = MakeDir (Folder_B);
                }
            }

            SetBreakOnLibraryErrors (1);    //turn ON alarm
        }
    }

    return result;
/*  error value
    -1      consecutive FS found
    -2      len_Corrected + 1 >= 260 (max)
*/
}

 

please correct any error you may find.

0 Kudos
Message 2 of 3
(5,547 Views)

I personally would take another approach: it adds some more preliminary checks with respect to your code and operates a different way.

 

//----------------------------------------------------------------------
// Function MyCreateFolder ()
//
// Missing: get active drive and pathname and restore at function end
//----------------------------------------------------------------------
/// HIFN MyCreateFolder ()
/// HIFN Creation of a pathname or a series of folders.
/// HIFN The function takes a string in input, checks whether it is a
/// HIFN valid pathname and creates necessary folders to obtain the
/// HIFN desired path on disk.
/// HIFN /// HIFN The function changes active drive/folder to the new path /// HIFN /// HIPAR pathname/The pathname containing the folder(s) to be created
/// HIPAR pathname/It must be a valid, absolute pathname including
/// HIPAR pathname/the drive letter /// HIRET Errors returned from MkDir. /// HIRET Errors from other functions are mapped to those error codes. int MyCreateFolder (char *pathname) { int ro, hid, sys, arc, drv, ndrv; int result = 0; char *token; char pattern[16] = "\042.:<>|*?/"; // characters not allowed in file/folder names char drive[MAX_DRIVENAME_LEN], file[MAX_PATHNAME_LEN]; DebugPrintf ("Original string supplied: %s\n", pathname); // 1. Check for pathname lenght if (strlen (pathname) > MAX_PATHNAME_LEN) { MessagePopup ("Error", "Too longh pathname supplied."); result = -5; goto Error; } // 2. Separate pathname path from disk name SplitPath (pathname, drive, pathname, file); MakePathname (pathname, file, pathname); // Rebuild complete pathname DebugPrintf ("Pathname extracted: %s\n", pathname); // 3. Check drive name if (!strlen (drive)) { MessagePopup ("Error", "Pathname must include a drive name."); result = -5; goto Error; } StringUpperCase (drive); // 4. Check for forbidden characters in pathname if (strcspn (pathname, pattern) < strlen (pathname)) { MessagePopup ("Error", "Characters not allowed in pathname."); result = -5; goto Error; } // 5. Change active drive if needed GetDrive (&drv, &ndrv); if (drv != (drive[0] - 65)) { if (SetDrive (drive[0] - 65) < 0) { MessagePopup ("Error", "Error changing to target drive."); result = -3; goto Error; } } // Move to drive radix SetDir ("\\"); // 6. Separate path components and create folders if needed token = strtok (pathname, "\\"); while (token) { DebugPrintf ("pathname: %s\n", token); // Check if the pathname is to be created switch (GetFileAttrs (token, &ro, &hid, &sys, &arc)) { case 1: // Specified file is a directory -> skip break; case 0: // Success: a file with the given name exists -> error result = -9; goto Error; case -1: // File not found -> create directory if (result = MakeDir (token) < 0) { MessagePopup ("Error", "Error creating directory."); goto Error; } break; } // Move to the new folder SetDir (token); // Check for next folder in path token = strtok (NULL, "\\"); } Error: return result; }

 

Whichever is the solution you adopt, the use of MAX_PATHNAME_LEN and MAX_FILENAME_LEN macros makes your code more adaptive to OS changes.

 



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
Message 3 of 3
(5,528 Views)