Thread: Can't open inFile

  1. #1
    Registered User
    Join Date
    Dec 2016
    Posts
    96

    Can't open inFile

    Hi guys!

    I tried whatever I could think of, it should be working, but I can't open the input file, I don't know why.

    Code:
    #include <stdio.h>#include <stdlib.h>
    #include <string.h>
    #include <dirent.h>
    #include <conio.h>
    
    
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    
    
    void Encrypt(char * FILENAME, char * NEW_FILENAME, char* process);
    char* ExtensionRemover(char* mystr);
    int is_regular_file(const char *path);
    
    
    /* Global variables */
    char AllStrings[256];
    
    
    int main(void)
    {
      /* Local variables */
      char process[50];     // array big enough to hold expected input
      //char AfterProcess[50]="_";
      DIR *d;
      struct dirent *dir;
    
    
      printf ("Please enter 'encryption or decryption'\n\n");
      scanf  ("%49s", process);
    
    
      // Open the current directory
      d = opendir(".");
      if (d) // If the directory is not empty "if (d) != 0"
        {
          while ((dir = readdir(d)) != NULL) // While the directory is not empty
          {
           printf("\n%s\n", (dir->d_name)); // Print the name of the consequent file in the directory
           // Add an if to check if the file is a directory like: is_regular_file(dir->d_name)
           if (is_regular_file(dir->d_name) && strstr((dir->d_name), process) == 0) // We test a flag is it "0" or "1" to see if the name if of a file or directory
           {
            /* Always put brackets at (dir->d_name), (strcat(dir->d_name, process)) !!!!!!!!!!!!!!!!!!!!!!!!!!
            Or you will get an error can't open inFile. */
            Encrypt((dir->d_name), (strcat((dir->d_name), process)), process); // Encrypt(File1_Input, File2_Output, process)
           }
          }
          closedir(d); // Close the directory
        }
      return(0); // Error code for everything is ok
    }
    
    
    // Encrypts or decrypts a file
    void Encrypt(char * FILENAME, char * NEW_FILENAME, char* process)
    {
             printf("Processing started\n");
             FILE *inFile;
             FILE *outFile;
             char key[256] = "RandomString";         // array big enough to hold expected input, dont give "char *" to scanf with "%s"
             //char process[50];     // array big enough to hold expected input
             int keylen, keyidx;
    
    
             int Byte;       // fgetc returns int, so use an int for "Byte" and "newByte"
             int newByte;
    
    
             // printf ("Please enter 'encryption or decryption'\n\n");
             // scanf  ("%49s", process);
             // printf ("Please enter the key\n\n");
             // scanf  ("%49s", key);
             keylen = strlen(key);
             keyidx = 0;    // starting index into key
             printf("Opening files\n\n");
    
    
             inFile = fopen(FILENAME,"rb");
             outFile = fopen(NEW_FILENAME, "w");
    
    
             if(inFile == NULL)
             {
                printf("Error: Can't Open inFile\n");
             }
             else if(outFile == NULL)
             {
                printf("Error: Can't open outFile\n");
             }
             else
             {
                     printf("File Opened, processing.\n\n");
    
    
                     while((Byte = fgetc(inFile)) != EOF)    // read a byte, check if EOF, "EOF" is outside the range of "char most times"
                     {
                             if (!strcmp(process,"encryption")) /* ??? "strmcp()" compares (process) a string to(encryption) a string */
                             {
                                     printf (".");
                                     newByte = Byte + key[keyidx];    // use key index
                                     if (newByte > 256) newByte -= 256;   // check for overflow
                             }
                             else if (!strcmp(process,"decryption"))
                             {
                                     printf (".");
                                     newByte = Byte - key[keyidx];
                                     if (newByte < 0) newByte += 256;
                             }
                             else
                             {
                                newByte = Byte;
                             }
                             fputc(newByte, outFile);
                             keyidx++;
                             // loop to the start of the key if needed
                             if (keyidx >= keylen) keyidx = 0;
                     }
             }
             if (inFile != NULL) fclose(inFile);     // close your files when you're done
             if (outFile != NULL) fclose(outFile);
    }
    
    
    // Check if a file is a directory, the check must be update
    // to include checks for other not used files, like pipes and etc.
    int is_regular_file(const char *path)
    {
        struct stat path_stat;
        stat(path, &path_stat);
        return S_ISREG(path_stat.st_mode);
    }

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,675
    > Encrypt((dir->d_name), (strcat((dir->d_name), process)), process);
    Try creating a new string with the right amount of storage space.

    Trashing the end of dir->d_name isn't the way to go.


    Code:
                     while((Byte = fgetc(inFile)) != EOF)    // read a byte, check if EOF, "EOF" is outside the range of "char most times"
                     {
                             if (!strcmp(process,"encryption")) /* ??? "strmcp()" compares (process) a string to(encryption) a string */
                             {
                                     printf (".");
                                     newByte = Byte + key[keyidx];    // use key index
                                     if (newByte > 256) newByte -= 256;   // check for overflow
                             }
                             else if (!strcmp(process,"decryption"))
    Decide in advance of the while loop whether you're encrypting or decrypting.
    Doing one or two strcmp's for every single byte you read is phenomenally expensive, unless your compiler is smart enough to figure out the invariance.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Dec 2017
    Posts
    1,664
    it should be working
    Clearly not! :-) Whenever you have this feeling it means you are making an assumption that is not true. A major skill in debugging is ferreting out this hidden assumption.

    In your program you are modifying d_name by strcat'ing some text onto it. This means that both the input and output filenames to Encrypt will be the same. You need to make a copy of d_name to change it and also have the original. (Also it's generally not a good idea to modify a member of an object that you do not control.) Maybe something like this:
    Code:
    #define _DEFAULT_SOURCE
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <dirent.h>
     
    void *xmalloc(size_t sz) {
        void *p = malloc(sz);
        if (!p) {
            perror("xmalloc");
            exit(EXIT_FAILURE);
        }
        return p;
    }
     
    DIR *xopendir(const char *dirname) {
        DIR *dir = opendir(dirname);
        if (!dir) {
            perror("xopendir");
            exit(EXIT_FAILURE);
        }
        return dir;
    }
     
    char *append(const char *a, const char *b) {
        return strcat(strcpy(xmalloc(strlen(a) + strlen(b) + 1), a), b);
    }
     
    void f(const char *name, const char *outname) {
        printf("[%s] -> [%s]\n", name, outname);
    }
     
    int main() {
        DIR *dir = xopendir(".");
     
        for (struct dirent *ent; (ent = readdir(dir)); ) {
            if (ent->d_type != DT_REG) continue;
     
            char *outname = append(ent->d_name, "_encrypted");
            f(ent->d_name, outname);
            free(outname);
        }
     
        closedir(dir);
        return 0;
    }
    // Always put brackets at (dir->d_name)
    The parentheses are not needed (and are just (clutter)).

    Overall, your program doesn't make much sense. If I choose "encryption" it scans the current directory for regular files that have "encryption" somewhere in the filename (why?), then appends another copy of the word "encryption" to the end of the filename, then encrypts the file and saves it with the new name.
    E.g., my_encryption_file.txt becomes my_encryption_file.txtencryption
    It's weird, man.
    All truths are half-truths. - A.N. Whitehead

  4. #4
    Registered User
    Join Date
    Dec 2016
    Posts
    96
    The idea originally was to have a number of files in a folder and after the encryption, to add "_encryption" to the name, making it like a first barrier for the people who do not understand from tech at all, as they wont be able to read the file, when they don't know the extension. Also I have to check what will happen if the extension is hidden by the OS.

    The problem comes from the strcat() and strcpy() functions. When I use "scanf()" everything is ok, but otherwise no.

    I have 2 versions now.
    Version1:
    Code:
    /*
    The example is working. Implementing a simple encryption method. The professor told me that this is the encryption banks use with a longer public key (??? publicly known how long it is). In the example that he gave though, we were allocating memory with "malloc()" or "calloc()" (I thinkg it was "calloc()". He was indexing both the file and the key with a counter (i,z), I think the same counter for the file and key (i for the the file and key)
    */
    
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    
    #include <dirent.h>
    #include <conio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    
    
    // declare function before it's called
    void Encrypt(char * FILENAME, char * NEW_FILENAME, char * process);
    int is_regular_file(const char *path);
    char *strremove(char *str, const char *sub);
    int NotExe (char * f1);
    int StringFind(char str[], char search[]);
    
    
    int main ()
    {
        char f1[256];   // array big enough to hold expected input, max in Windows is 256 chars with the path
        char f2[256];   // array big enough to hold expected input, max in Windows is 256 chars with the path
        char process[50];     // array big enough to hold expected input
        char Decryption[50] = "Decryption_";
        char Encryption[50] = "Encryption_";
        DIR *d;
        struct dirent *dir;
    
    
        /* This block inputs file names from the user
        printf ("Please enter file for encryption\n");
        scanf  ("%99s", f1);    // set max characters to read to prevent buffer overflow
        printf ("Please enter the name of the file after encryption\n");
        scanf  ("%99s", f2);
        */
    
    
    START:
        printf ("Please enter 'encryption or decryption'\n");
        scanf  ("%49s", process);
    
    
        d = opendir("."); // Open the directory
        if (d) // If the directory is not empty "if (d) != 0"
         {
    
    
          while ((dir = readdir(d)) != NULL) // While the directory is not empty
          {
              if (is_regular_file(dir->d_name)) // If the file is not a directory
              {
                strcpy(f1, (dir->d_name)); // Transfer the file name into f1 to avoid "Can't open inFile"
                // strcpy(f2, "encryption_"); // Transfer the file name into f1 to avoid "Can't open inFile"
    
    
                if (NotExe (f1) == 0) // If the file is not an .exe
                {
                    if (strcmp (process, "decryption")) // If the process is "decryption"
                    {
                        if (StringFind(f1, Encryption) == 0) // If the substring is found
                        {
                            strremove(f1, Encryption); // Remove the substring
                            strcpy (f2, Decryption); // Transfer the file name into f2 to avoid "Can't open inFile"
                            strcat (f2, f1); // Add to the file name "Decryption_" + "FileName"
                            printf ("\nf2 = %s\n", f2); // For debugging only
                        }
                    }
                    else if (StringFind(f1, Encryption) != 0) // If the substring is not found and the process is "encryption"
                    {
                        //printf ("else if = %d", strstr(f1, Encryption));
                        //strcpy(f2, f1); strcat(f2, "_"); strcat(f2, process);
                        strcpy (f2, Encryption); // Transfer the file name "Encryption_" into f2 to avoid "Can't open inFile"
                        strcat (f2, f1); // Transfer the file name into f2
                        printf ("\noutFile f2 = %s\n", f2); // For debugging only
                    }
                Encrypt(f1, f2, process);
                }
              }
          }
    
    
        closedir(d); // Close the directory
    
    
        goto START;
        return 1; // The software did not return to START
        }
    }
    
    
    void Encrypt(char * FILENAME, char * NEW_FILENAME, char * process)
    {
             printf("Process started\n");
             FILE *inFile;
             FILE *outFile;
             char key[256] = "EyBtLfnPP9htzwXHjayXeuFV3TDdiSFjESL3K3do4E1HQqru1w0UTBhuotsQ9PVCup6mwB9hhrU11aroOJMlw1xYQ5PhfLIMp5WDzr3gXrERuIADifqGDQ6LyyDAsKqI9P7iVDNsMTBYzHENdcXpP1aCdmSgEqfuOkGHnhP0LxcsusIFGIYLACU3TYKDmwWEEs99Jc0mcZeXA8P4VGEIL4qIqauL0twT9H3koBq1jfDXe8SiekYGGVRg87uuTtIl";         // array big enough to hold expected input, dont give "char *" to scanf with "%s"
             int keylen, keyidx;
    
    
             int Byte;       // fgetc returns int, so use an int for "Byte" and "newByte"
             int newByte;
    
    
             //printf ("Please enter the key\n");
             //scanf  ("%49s", key);
             keylen = strlen(key);
             keyidx = 0;    // starting index into key
             printf("Opening files\n");
    
    
             inFile = fopen(FILENAME,"rb");
             outFile = fopen(NEW_FILENAME, "w");
    
    
             if(inFile == NULL)
             {
                printf("Error: Can't Open inFile\n");
             }
             else if(outFile == NULL)
             {
                printf("Error: Can't open outFile\n");
             }
             else
             {
                     printf("File Opened, processing\n");
    
    
                     while((Byte = fgetc(inFile)) != EOF)    // read a byte, check if EOF, "EOF" is outside the range of "char most times"
                     {
                             if (!strcmp(process,"encryption")) /* ??? "strmcp()" compares (process) a string to(encryption) a string */
                             {
                                     newByte = Byte + key[keyidx];    // use key index
                                     if (newByte > 255) newByte -= 256;   // check for overflow
                             }
                             else if (!strcmp(process,"decryption"))
                             {
                                     newByte = Byte - key[keyidx];
                                     if (newByte < 0) newByte += 256;
                             }
                             else
                             {
                                newByte = Byte;
                             }
                             fputc(newByte, outFile);
                             keyidx++;
                             // loop to the start of the key if needed
                             if (keyidx >= keylen) keyidx = 0;
                     }
             }
             if (inFile != NULL) fclose(inFile);     // close your files when you're done
             if (outFile != NULL) fclose(outFile);
    }
    
    
    // Check if a file is a directory, the check must be update
    // to include checks for other not used files, like pipes and etc.
    int is_regular_file(const char *path)
    {
        struct stat path_stat;
        stat(path, &path_stat);
        return S_ISREG(path_stat.st_mode);
    }
    
    
    char *strremove(char *str, const char *sub)
    {
        size_t len = strlen(sub);
        if (len > 0) {
            char *p = str;
            while ((p = strstr(p, sub)) != NULL) {
                memmove(p, p + len, strlen(p + len) + 1);
            }
        }
        return str;
    }
    
    
    int NotExe (char * f1)
    {
        if (strstr(f1, ".exe"))
        {
            return 1;
        }
        else
        {
            return 0;
        }
    }
    
    
    int StringFind(char str[], char search[])
    {
    	//char str[] = "teacher teach tea";
    	//char search[] = "ac";
    	char *ptr = strstr(str, search);
    
    
    	if (ptr != NULL) /* Substring found */
    	{
    		printf("'%s' contains '%s'\n", str, search);
    		return 0;
    	}
    	else /* Substring not found */
    	{
    		printf("'%s' doesn't contain '%s'\n", str, search);
    		return 1;
    	}
    }
    Version 2:
    Code:
    /* Usage
    $ gcc encryptor.c -o encryptor
    $ ./encryptor /path/to/folder encrypt
    $ ./encryptor /path/to/folder decrypt
    */
    
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    
    #define KEY 'K' // Change this to any other character for a different key
    
    
    void encryptFile(char *filename) {
        FILE *fp;
        char ch;
    
    
        fp = fopen(filename, "rb+");
        if (fp == NULL) {
            printf("\nCannot open file: %s", filename);
            return;
        }
    
    
        while ((ch = fgetc(fp)) != EOF) {
            ch = ch ^ KEY;
            fseek(fp, -1L, SEEK_CUR);
            fputc(ch, fp);
        }
    
    
        fclose(fp);
    }
    
    
    void decryptFile(char *filename) {
        encryptFile(filename); // XOR encryption and decryption are the same operation
    }
    
    
    int main(int argc, char *argv[]) {
        char *folderPath, *command;
        size_t pathLength;
    
    
        if (argc != 3) {
            printf("Usage: %s <folder_path> <encrypt/decrypt>\n", argv[0]);
            return 1;
        }
    
    
        folderPath = argv[1];
        pathLength = strlen(folderPath);
    
    
        if (folderPath[pathLength-1] != '/') {
            folderPath = realloc(folderPath, pathLength + 2);
            folderPath[pathLength] = '/';
            folderPath[pathLength+1] = '\0';
        }
    
    
        command = argv[2];
    
    
        if (strcmp(command, "encrypt") == 0) {
            printf("Encrypting files in folder: %s\n", folderPath);
    
    
            char *commandBuffer = malloc(pathLength + 30);
            sprintf(commandBuffer, "find %s -type f -exec %s {} \\;", folderPath, argv[0]);
            system(commandBuffer);
            free(commandBuffer);
    
    
            printf("Done.\n");
        } else if (strcmp(command, "decrypt") == 0) {
            printf("Decrypting files in folder: %s\n", folderPath);
    
    
            char *commandBuffer = malloc(pathLength + 30);
            sprintf(commandBuffer, "find %s -type f -exec %s {} \\;", folderPath, argv[0]);
            system(commandBuffer);
            free(commandBuffer);
    
    
            printf("Done.\n");
        } else {
            printf("Invalid command: %s\n", command);
            return 1;
        }
    
    
        return 0;
    }
    On version 2, I get "encryptor has stopped responding, do you want to close the window".

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,675
    > On version 2, I get "encryptor has stopped responding, do you want to close the window".
    Well the first big mistake is this.

    > folderPath = realloc(folderPath, pathLength + 2);
    folderPath wasn't the result of a previous malloc/realloc call (or NULL), so you just trashed everything.

    > char *commandBuffer = malloc(pathLength + 30);
    This just doesn't seem enough, given the fixed length string and the two string parameters.


    Was it your professor's idea to use goto in your other program?

    > // Transfer the file name into f1 to avoid "Can't open inFile"
    This is a voodoo comment.
    Cargo cult programming - Wikipedia
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Having trouble with InFile.open
    By partnole in forum C++ Programming
    Replies: 2
    Last Post: 06-26-2007, 04:19 AM
  2. infile String
    By carisma36 in forum C++ Programming
    Replies: 7
    Last Post: 12-07-2004, 08:06 PM
  3. infile from the web
    By major_small in forum C++ Programming
    Replies: 2
    Last Post: 05-25-2003, 01:23 AM
  4. Im missing something (infile)
    By RoD in forum C++ Programming
    Replies: 13
    Last Post: 05-07-2003, 01:54 PM
  5. help with infile and getline using for loop
    By lostgirls in forum C++ Programming
    Replies: 10
    Last Post: 03-27-2002, 02:36 PM

Tags for this Thread