2

I am using Code::Blocks and have set the command-line arugments via the IDE. I have also opened the executable with the proper argument and I can't manage to get a non-NULL on fopen() return. I've tried hard-coding the filename also with no success. The platform is Windows XP SP3.

The first is the one that fails, when i hardcoded it i used double backlash. Also i never knew if the second works because i never managed to start the process by opening the first one.

Obviously i put the text file in the same directory that the executable and rebuilt the executable many times, but it still doesn't work.

EDIT: I added the perror("fopen"); line in the if(finput==NULL) block. This is the output.

http://prntscr.com/h71pa

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

#define first_part_url "[url=http://magiccards.info/query?q="
#define second_part_url "&v=card&s=cname]"
#define end_bracket "[/url]\n"
#define output_file_prefix "output_"

char* get_card(FILE* finput);

int main(int n, char* arguments[])
{
FILE* finput;
FILE* foutput;
short int counter;
char* output_filename;
char* finalstring;


for(counter=1; counter<n; counter++)
{
    finput=fopen(arguments[counter], "r");

    if (finput==NULL)
    {
        printf("Unable to open ");
        puts(arguments[counter]);
                    perror("fopen");
        break;
    }

    strcpy(output_filename, output_file_prefix);
    strcat(output_filename, arguments[counter]);

    if((foutput=fopen(output_filename, "w"))==NULL)
    {
        printf("There was an error while trying to open ");
        puts(arguments[counter]);
        printf(" .\n");
        break;
    }

    while(!feof(finput))
    {
    finalstring=get_card(finput);
    fputs(finalstring, foutput);
    while(((fgetc(finput))!='\n')||feof(finput));
    }

    printf("Autocarding ");
    puts(arguments[counter]);
    printf(" was a success.\n");
    fclose(foutput);
}

if(finput!=NULL)
{
fclose(finput);
free(finalstring);
}
return 0;
}

char* get_card(FILE* finput)
{
char* currentcard;
char* finalstring;

currentcard=(char*)malloc(sizeof(char)*150);
fgets(currentcard, 150, finput);

/* Allocates the exact amount of space needed for the final string*/
finalstring=(char*)malloc(sizeof(char)*(strlen(first_part_url)+strlen(second_part_url)+strlen(end_bracket)+strlen(currentcard)));

/* Get all the final forum link together*/
strcat(finalstring, first_part_url);
strcat(finalstring, currentcard);
strcat(finalstring, second_part_url);
strcat(finalstring, end_bracket);

free(currentcard);

return finalstring;
}
user1736495
  • 51
  • 2
  • 7
  • Which one fails, the first or the second? – Sergey Kalinichenko Oct 11 '12 at 00:46
  • When you hard coded the file name, did you use a single or double backslash as the path separator? – Greg Hewgill Oct 11 '12 at 00:49
  • The first is the one that fails, when i hardcoded it i used double backlash. Also i never knew if the second works because i never managed to start the process by opening the first one. – user1736495 Oct 11 '12 at 00:53
  • In the case where `fopen()` returns `NULL`, add a call to `perror("fopen");` - this will print a message from the OS describing why the open failed. – caf Oct 11 '12 at 01:04
  • thank you sir, i will do it immediately and post my results. – user1736495 Oct 11 '12 at 01:05
  • http://prntscr.com/h71pa – user1736495 Oct 11 '12 at 01:08
  • 1
    Great, you have changed the source code again, and... now `strcpy()` attempts to write to nobody knows where because `output_filename` is not even initialized. Do NOT keep changing the code in the question. Append newer versions, but don't change the original one because if you keep changing it, answering the question becomes pointless, because it changes! – Alexey Frunze Oct 11 '12 at 01:38
  • Sorry Alexey, i'm a very bad programmer : P However your help was very appreciated. – user1736495 Oct 11 '12 at 01:49

3 Answers3

2

The error you are getting, "No such file or directory" indicates that the file name you're trying to open doesn't exist.

In this case, it's probably because the program's current working directory is not the same as the directory containing the executable file.

caf
  • 233,326
  • 40
  • 323
  • 462
  • This is almost certainly the underlying problem. When a process is started, it has a "current directory" which is *not* necessarily the same directory as the location of the executable. Code::Blocks might be setting the current directory somewhere else (like the project directory). – Greg Hewgill Oct 11 '12 at 01:36
  • Thank you Greg Hewgill i will try to put the text file in the root directory of the project and post a screen. – user1736495 Oct 11 '12 at 01:42
  • You were spot on Greg, i put the file in the root of the project instead of the exe directory (this always worked on Visual Studio). Now i got a different kind of error, which is great because i solved the main error. http://prntscr.com/h73u5 – user1736495 Oct 11 '12 at 01:45
0

This

finput=fopen(arguments[counter], "r");

Will only fail if you do not supply correct filenames (e.g. if there are non-ASCII characters in the names or the names do not include the correct path, fopen() opens files in the current directory if no path is specified in the file name).

This

output_filename=(char*)malloc(sizeof(arguments[counter]));

most likely does not allocate enough space for a name because arguments[counter] is a pointer, and sizeof() of a pointer is not the same as strlen(that_same_pointer) + 1.

This

output_filename=output_file_prefix;

loses the just allocated memory because you are reassigning the pointer output_filename to point to some other place, output_file_prefix ("output_").

After the above this

strcat(output_filename, arguments[counter]);

is likely going to crash your program because this is going to attempt to overwrite a string literal ("output_"), doing which causes undefined behavior per the C standard.

You have to allocate enough cumulative space for the strings that you want to concatenate and you have to concatenate them in the allocated space.

To save you even more trouble, here's another problem:

finput=fopen(arguments[counter], "r");
...
while(!feof(finput))

feof() only works after at least one read from a file. This has been asked ans answered multiple times.

Community
  • 1
  • 1
Alexey Frunze
  • 61,140
  • 12
  • 83
  • 180
  • Thank you sir, i will correct those mistakes. However, the program should still perform fopen. Here's a screenshot that proves i used correct filenames and directories. http://prntscr.com/h71pa – user1736495 Oct 11 '12 at 01:16
  • Do NOT keep changing the code in the question. Append newer versions, but don't change the original one because if you keep changing it, answering the question becomes pointless, because it changes! – Alexey Frunze Oct 11 '12 at 01:37
  • It's a large chunk of code to append like 5 newer versions for each simple change, and I think these changes shouldn't affect the main problem at all. – user1736495 Oct 11 '12 at 01:41
  • Thank you for your time Alexey Frunze, the question is solved. – user1736495 Oct 11 '12 at 01:46
0

Try changing

for(counter=1; counter<n; ++n)
{

to

for(counter=1; counter<n; ++counter)

It appears the code loops infinitely, therefore it would exhaust the possible elements in your argument array causing a NULL pointer to be returned.