0

My program should open a file, the file path is retrieved from the command line using argv[1].

I then try to open the file using fopen but my program crashes because the filepath I use doesn't contain double backslashes so fopen doesn't work.

I've tried to write my own convert function and using print to check the result looked good at first sight.

The problem is that when I use the returned const char* as argument it gives me a weird result.. my code:

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


const char* ConvertToPath(std::string path)
{
    std::string newpath = "";
    for(unsigned int i = 0; i < path.length(); ++i)
    {
        if(path[i] == '\\')
        {
            newpath += "\\\\";
        }
        else
        {
            newpath += path[i];
        }
    }
    printf("%s \n", newpath.c_str());
    return newpath.c_str();
}

bool OpenDBC(const char* path)
{
    const char* file = ConvertToPath(path);
    printf("%s \n", file);
    FILE* dbc = fopen(file, "rbw");
    if (!dbc)
        return false;
    return true;
}

int main(int argc, char* argv[])
{
    if (argc < 2)
    {
        printf("Error, expected DBC file.");
        getchar();
        return -1;
    }

    if (!OpenDBC(argv[1]))
    {
        printf("There was an error opening the DBC file.");
        getchar();
        return -1;
    }
    getchar();
    return 0;
}

Opening a DBC file with my program gives me the following result:

D:\\Achievement.dbc
a

So it looks like const char* file only contains 1 char of the file path, why?

tshepang
  • 12,111
  • 21
  • 91
  • 136
Hatted Rooster
  • 35,759
  • 6
  • 62
  • 122
  • 6
    You're relying upon Undefined Behavior, returning `c_str()` from a local string is a really bad idea. Just return the string instead and call `c_str()` from inside `OpenDBC`. – Chnossos Apr 27 '14 at 19:56
  • 1
    @Chnossos's comment is correct, but I'm also curious about this statement: "my program crashes because the filepath I use doesn't contain double backslashes so fopen doesn't work". You generally shouldn't need to escape backslashes except when the path is being specified in the program's source code. – Michael Burr Apr 27 '14 at 20:02
  • 1
    You don't need `ConvertToPath` at all, just call `fopen(argv[1])` and see results. – CiaPan Apr 27 '14 at 20:02

2 Answers2

1

You do not need the ConvertToPath function at all. Double backslashes are only needed in string literals. Never in variables such as a std::string.

ScottMcP-MVP
  • 10,337
  • 2
  • 15
  • 15
0

I compiled your code on Linux and can not replicate your result

Running ./filereader "D:\\Achievement.dbc" results in

D:\\Achievement.dbc
D:\\Achievement.dbc

Running ./filereader "D:\\\\Achievement.dbc" results in

D:\\\\Achievement.dbc 
D:\\\\Achievement.dbc 

The later is what you want because command line arguments need to be escaped. Then you can remove the ConvertToPath.

Simon Warta
  • 10,850
  • 5
  • 40
  • 78