Share via


Replace single slash in filename by double slash C++

Question

Tuesday, June 12, 2012 2:07 PM

Hi

      I am using CFileDialog to select a file and getting filename in a CString. The filename returned by CFileDialog has single slash like "d:\code\try.txt" but i need it to have double backslashes like "d:\code\try.txt" since i have to used it some other places of my code where double slash is required. How to do this?

Thanks in Advance

Manigandasuresh

All replies (13)

Tuesday, June 12, 2012 2:20 PM

"The filename returned by CFileDialog has single slash like "d:\code\try.txt""

That's a backslash, not a slash.

" but i need it to have double backslashes like "d:\code\try.txt" since i have to used it some other places of my code where double slash is required"

That's a rather odd requirement, are you sure you got it right? Anyway, you could simply use CString::Replace (http://msdn.microsoft.com/en-us/library/ztyt5e9c.aspx) to do this. Something like filename.Replace(_T("\"), _T(\\));


Tuesday, June 12, 2012 2:25 PM

Mike, he/she is probably confused.  A double backslash is merely the literal representation of a backslash in C++ code files.  Manigandasuresh, have you verified for sure that you need double backslashes?

Jose R. MCP
Code Samples


Tuesday, June 12, 2012 3:52 PM

The only place you need \ is in a string literal so the compiler can "replace" it with \  It is a compile time issue since \ is used to identify "escape characters" such as \t and \n.

Once your program is executing, the compiler is no longer an issue and \ is just another character.  So when a function like CFileDialog (or even user input) returns a string value, it is ready for use and nothing special need be done to the \


Tuesday, June 12, 2012 8:47 PM

Hi

       Thanks to all your replies...

What i have done is, the fileName returned by Cfiledialog(here i converted cstring into string fileName) is used to createFile in another file as,

    TCHAR *param=new TCHAR[fileName.size()+1];
    param[fileName.size()]=0;
    std::copy(fileName.begin(),fileName.end(),param);
    hFile = CreateFile(param,
        GENERIC_READ,
        FILE_SHARE_READ,
        NULL,
        OPEN_EXISTING,
        FILE_FLAG_SEQUENTIAL_SCAN,
        NULL);

    if (INVALID_HANDLE_VALUE == hFile)
    {
        dwStatus = GetLastError();
    }
But it returns 123 INVALID_FILE_NAME. This createfile works when i use filename with double slashes...then why it doesn't work with single backslash?

Thanks in advance

Manigandasuresh


Tuesday, June 12, 2012 8:58 PM

On 6/12/2012 4:47 PM, Manigandasuresh wrote:

What i have done is, the fileName returned by Cfiledialog(here i converted cstring into string fileName)

Converted how? And, perhaps more interestingly, why? If you have

CString fileName = ...; // initialized somehow, e.g. from CFileDialog

you can just do

HANDLE hFile = CreateFile(fileName, ...);

Igor Tandetnik


Tuesday, June 12, 2012 9:03 PM

>This createfile works when i use filename with
>double slashes...

Presumably you mean when you hard code the filename
in the program source. That has already been explained.

>then why it doesn't work with single backslash?

It won't work with single backslashes *in your source code*
as already explained. It *will* work with single backslashes
in the name when it's retrieved dynamically at run time.

Use the debugger to examine the *exact* contents of param
before the CreateFile is attempted.

  • Wayne

Friday, June 15, 2012 10:39 AM

Hi Igor

       I am compiling my code using mingw gcc in which CString cant be used.

      Thanks for all your replies i converted my filename with single backslash into all forward slashes and it works nice..

Manigandasuresh


Wednesday, June 20, 2012 3:16 AM

Hi Maniqandasuresh,

I’m glad to hear that you found a good idea to resolve your question. If you find out the root cause finally and share your solutions & experience here, it will be very beneficial for other community members who have similar questions. By the way, please mark the reply as answer if it helps you find the solution. 

Thanks for your active participation in the MSDN Forum.
Best regards,

Helen Zhao [MSFT]
MSDN Community Support | Feedback to us


Friday, July 19, 2013 6:55 AM

Im also facing the same problem. First i select a file and store its directory in a message box. It is stored as "C:\MyDir\MySubDir\myfile.ext". But then I need this exact address to create a new text file. But to create it, the visual C++ GUI requires a format like this: "C:\MyDir\MySubDir\myfile.ext". So to use the directory name stored in the message box, i would have t convert \ to \. So please can any one help me figure this thing out?


Friday, July 19, 2013 7:12 AM

can you also tell me how to use

Path::AltDirectorySeparatorChar.ToString();

i think this line of code can be used to change the separator charter. but im unable to figure out how to use it


Friday, July 19, 2013 7:39 AM | 1 vote

First i select a file and store its directory in a message box. It is stored as "C:\MyDir\MySubDir\myfile.ext". But then I need this exact address to create a new text file. But to create it, the visual C++ GUI requires a format like this: "C:\MyDir\MySubDir\myfile.ext". So to use the directory name stored in the message box, i would have t convert \ to \.

No, you wouldn't have to convert anything. Didn't you understand what has already been
explained about the double backslashes?

Using \ instead of \ in a path name is *only* required when that path is hard coded
in your *source code*. That's because the *compiler* treats a single backslash as the
"escape character".

When you get a path at run time - from console input, a message box, an edit control,
etc. - you should *not* double the backslash. Run time input is *not* processed by the
*compiler* and therefore there is no "escape character" processing taking place.

  • Wayne

Friday, July 19, 2013 9:17 AM

Wayne,

That was quite useful. I understand it now. And so I tried out this code.

OpenFileDialog^ openFileDialog1 = gcnew OpenFileDialog;
                     Stream^ myStream;
                     if (openFileDialog1->ShowDialog() == System::Windows::Forms::DialogResult::OK)
                    {    
                        if( (myStream = openFileDialog1->OpenFile()) != nullptr)        //if file opens
                        {
                            String^ filePath = openFileDialog1->InitialDirectory + openFileDialog1->FileName;    
                            StreamWriter^ outFile = gcnew StreamWriter(filePath);
                            outFile->Write("heloo");
                            outFile->Close();
                            myStream->Close();
                        }
                    }

It gives no errors and the Build is succeeded. This code is supposed to be able to let me select an empty text file through the browse button, and then write "Hello" in it. But an exception is thrown which says that "E:\my stuff\test.txt" is being used by another process.

Can you please help me figure out where im going wrong? Im really new to this file handling stuff.


Friday, July 19, 2013 6:11 PM | 1 vote

OpenFileDialog^ openFileDialog1 = gcnew OpenFileDialog;

                     Stream^ myStream;
                     if (openFileDialog1->ShowDialog() == System::Windows::Forms::DialogResult::OK)
                    {    
                        if( (myStream = openFileDialog1->OpenFile()) != nullptr)        //if file opens
                        {
                            String^ filePath = openFileDialog1->InitialDirectory + openFileDialog1->FileName;    
                            StreamWriter^ outFile = gcnew StreamWriter(filePath);
                            outFile->Write("heloo");
                            outFile->Close();
                            myStream->Close();
                        }
                    }

It gives no errors and the Build is succeeded. This code is supposed to be able to let me select an empty text file through the browse button, and then write "Hello" in it. But an exception is thrown which says that "E:\my stuff\test.txt" is being used by another process.

You are trying to use the file in two different ways at the same time.
Get rid of the OpenFile():

OpenFileDialog^ openFileDialog1 = gcnew OpenFileDialog;
if (openFileDialog1->ShowDialog() == System::Windows::Forms::DialogResult::OK)
  {
  String^ filePath = openFileDialog1->InitialDirectory + openFileDialog1->FileName;    
  StreamWriter^ outFile = gcnew StreamWriter(filePath);
  outFile->Write("heloo");
  outFile->Close();
  }

Also consider some of the other options for the StreamWriter constructor. e.g. -

StreamWriter^ outFile = gcnew StreamWriter(filePath, true, // append
    System::Text::Encoding::ASCII);
    

StreamWriter^ outFile = gcnew StreamWriter(filePath, false, // overwrite
    System::Text::Encoding::ASCII);

- Wayne