Zachary Sedefian
Zachary Sedefian

Reputation: 13

C can't open file in Unix but works fine on macOSx

I've written a program to reverse a .txt file, line-by-line, and return the output to a new file. It is part of the requirements for the command line arguments to NOT include the .txt extension, so I add in at the top of the program before fopen is called on the file. This works perfectly fine in macOSx terminal, as you can see here: https://i.sstatic.net/PHugj.jpg

However, when I upload this to my school's server, I get the following output: https://i.sstatic.net/SLygw.jpg

Relevant code:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

#define NUMARG 3
#define INFILEARG 1
#define OUTFILEARG 2

int countWords(const char *sentence);

int main(int argc, char *argv[]){

    /* File pointers */
    FILE *finp;
    FILE *foutp;

    /* Three levels of strings: word < line < text. 
       Both token variables to use with strtok splitting the text. */
    char **holdWords = NULL, *holdLine = NULL, *holdText = NULL,
             *lineToken = NULL, *wordToken = NULL;
    int stringSize = 0, totalStrings, i;
    size_t size = 0;

    /* Add .txt extension */
    int inFileNameSize = sizeof(argv[INFILEARG]);
    int outFileNameSize = sizeof(argv[OUTFILEARG]);

    char inFileName[inFileNameSize+4]; //add 4 to have room for ".txt"
    char outFileName[outFileNameSize+4];

    strcat(inFileName, argv[INFILEARG]);
    strcat(inFileName, ".txt");
    strcat(outFileName, argv[OUTFILEARG]);
    strcat(outFileName, ".txt");

    /* Check for errors in argument number and opening files. */
    if(argc != NUMARG){
            printf("You have to put the input and output files after the program name.\n"); fflush(stdout);
            return(1);
    }

    if( (finp = fopen(inFileName, "r")) == NULL ){
            printf("Couldn't open %s for reading.\n", inFileName); fflush(stdout);
            return(1);
    }

    if( (foutp = fopen(outFileName, "w")) == NULL){
            printf("Couldn't open %s for writing.\n", outFileName); fflush(stdout);
            return(1);
    }

Can anyone help me figure out what's going on here? Thank you.

EDIT TO EXPLAIN WHY DIFFERENT THAN LINKED QUESTION: While it's helpful to know why a pointer to an array can't be sizeof'd, my question is about getting the size of a string (one pointer, not a pointer to a pointer). I get an error when using strlen on my mac, yet it works on unix. I get an error when using sizeof of the unix, yet sizeof works on my mac.

Upvotes: 0

Views: 57

Answers (1)

Benjamin Close
Benjamin Close

Reputation: 341

It appears your have a buffer overflow, you can see this by the fact the file names printed appear corrupted.

If you look at the lines:

/* Add .txt extension */
int inFileNameSize = sizeof(argv[INFILEARG]);
int outFileNameSize = sizeof(argv[OUTFILEARG]);

Your error lies in the use of the sizeof operator. This returns the sizeof the type not the length of the string. Hence your in/outFileNameSize variable is too short for the actual string you are copying into it.

Upvotes: 1

Related Questions