Opening file in C++ on Unix: can we avoid case sensitivity? [duplicate] - c++

For example, suppose we have a file called "Hello.txt", then checking if "hello.txt" or "heLLo.txt" exist should both return true.

If you're running Windows or any case-insensitive filesystem, then there's nothing to do but check one casing. If "Hello.txt" exists, then "hEllo.txt" exists (and is the same file) (the difficult problem here is when you want to make sure that the file is spelled with a given casing in the filesystem)
If you're running a case-sensitive filesystem, just take directory name of the current file, list file contents, and compare entries against the current filename, ignoring case.

Take a look at fcaseopen, which demonstrates how to handle case insensitive file operations.
Essentially, the C headers/functions to use are:
From dirent.h, use opendir/readdir/closedir to go thru the files in a directory
From string.h, use strcasecmp to compare two filesnames, ignoring the case of the characters

Related

Regex for Current NTUSER.DAT files

I am trying to come up with a regex (PCRE) that finds current windows NTUSER.DAT files when cycling through a file list (valid NTUSER.DAT are the ones that are in the correct path for use by Windows).
I am trying to exclude any NTUSER.DAT files that have been copied by a user and placed in a different location (e.g. on the Desktop). In the following sample data, the first 4 results are valid, the next 3 are invalid:
\Users\John Thomas Hamilton\ntuser.dat
\Users\Default\NTUSER.DAT
\Users\Mary Thomas\NTUSER.DAT
\Users\UpdatusUser\NTUSER.DAT
\Users\John Thomas Hamilton\Desktop\My Stuff\Windows\Users\Default\NTUSER.DAT
\Users\John Thomas Hamilton\Desktop\My Stuff\Windows\Users\Student\NTUSER.DAT
\Users\John Thomas Hamilton\Desktop\My Stuff\My stuff to sort\Tech Support Fix it\NTUSER.DAT
Currently the best/simplest regex I have is:
\\USERS\\[A-Z0-9]+\\NTUSER.DAT$
but of course there a plenty of valid Windows file name characters other than letters and numbers that could exist in the user name.
I think i need to search up to the first occurrence of the new folder "\" and then if it does not have NTUSER.DAT after it, reject it. I have not had any luck doing this so any help would be appreciated.
Well assuming you have a valid file list, this would work:
^\\Users\\[^\\]+?\\NTUSER.DAT$
Make sure you ignore case.
The secret is using [^\\]+? instead of .+? so that you match exactly one folder length in.

Fopen didn't open the file, but file exist

I write
FILE * new_file = fopen("Penguins.jpg","rb");
I fully confident that file exist and it is in right directory. I also tried a lot of various modes like "rb+" "r". I also chanded path like fopen("C:\Penguins.jpg","rb"); Compilator always says :
Besides, openCV open the file. But i need in FILE*. What wrong?
In order to denote a special character within a string, it must be preceded with a backslash.
Since the backslash itself is also a special character, it must be preceded with yet another backslash.
So change this:
fopen("C:\Penguins.jpg","rb");
To this:
fopen("C:\\Penguins.jpg","rb");
Please note that you need to apply this only for strings that are part of the code, i.e., strings that are "treated" by the compiler, not by the preprocessor (such as names of included header files, for example).
According to the documentation of fopen from http://www.cplusplus.com/reference/cstdio/fopen/
The file opens successfully is the function returns a non-null pointer:
If the file is successfully opened, the function returns a pointer to a FILE object that can be used to identify the stream on future operations.
Otherwise, a null pointer is returned.
So because your variable new_file (not new_file->_ptr) is valid, the file should be opened.

c++ opening file with non-Latin name

I have such files. I just want to open files with non-Latin names correctly.
I have no problems with files that have Latin names only with non-Latin names.
I use QDir for scanning directory and I hold names in QString, so it's held fine inside.
But there is a bottleneck with opening the file.
It gets so that I don't want to use QFile, I can use only C++ streams (more preferred) or C files.
When I want to open file, I do so:
fstream stream(source.toStdString().c_str(),ios_base::in | ios_base::binary);
After that I check whether attempt was successful:
if(!stream.is_open())
{ cout<<"file wasn't opened " <<source.toStdString().c_str())<<"\n";
return false; // cout was redirected to file // just a notice
}
I get in my log file:
file wasn't opened /home/sh/.mozilla/firefox/004_??????? - ????? - ?????.mp3
It doesn't work for any file with non-Latin name and it does work fine for every file with Latin names.
I understand that this problem can be jumped over using QFile.
But I wonder, is it possible to get it done without third-party libraries or are there some another ways for solving it?
Thanks in advance for any tips.
Things are going wrong when you call toStdString() on your QString. It will convert the contents based on QTextCodec::codecForCStrings(), if it has been set, and latin-1 will be used otherwise. Latin-1 will collapse your non-latin characters to '?'s.
Using source.toLocal8Bit().data() or source.toUtf8().data() instead will likely do what you want, but failing that you'll need to deal with QTextCodecs to get the right 8-bit encoding.

how to read from a text file contents file name extension in c++?

Hello I want to read from a text file full of directory contents
Here's my example:
below is my text file called MyText.txt
MyText.txt
title.txt,image.png,sound.mp3
I want to be able to read that .txt extension not the filename and I want it to be for file extensions only for example .txt or .mp3 how would I do that in c++?.
When I mean read I mean reference it in a if statement like this:
if(.mp3 exists in a text file)
{
fprintf(stderr,"sees the mp3 extensions");
}
I'm running Windows 7 32-bit.
I need a more cross platform approach.
May I suggest you to read a tutorial on C++ file handling and another one on C++ strings?
There is no a quick solution: you have to read the file using the ifstream class.
After reading the file and storing it in one or more strings, you can then use the find and substr string methods to create a queue of discrete filenames. Using the same methods, you can then split the queued elements again, in order to find the extensions and add them to a set. A set does not allow duplicates, so you are sure all the extensions will appear only once.

In C++ how do i validate a file or folder path?

A user input string for a destination path can potentially contain spaces or other invalid characters.
Example: " C:\users\username\ \directoryname\ "
Note that this has whitespace on both sides of the path as well as an invalid folder name of just a space in the middle. Checking to see if it is an absolute path is insufficient because that only really handles the leading whitespace. Removing trailing whitespace is also insufficient because you're still left with the invalid space-for-folder-name in the middle.
How do i prove that the path is valid before I attempt to do anything with it?
The only way to "prove" the path is valid is to open it.
SHLWAPI provides a set of path functions which can be used to canonicalize the path or verify that a path seems to be valid. This can be useful to reject obviously bad paths but you still cannot trust that the path is valid without going through the file system.
With NTFS, I believe the path you give is actually valid (though Explorer may not allow you to create a directory with only a space.)
The Boost Filesystem library provides helpers to manipulate files, paths and so... Take a look at the simple ls example and the exists function.
I use GetFileAttributes for checking for existence. Works for both folders (look for the FILE_ATTRIBUTE_DIRECTORY flag in the returned value) and for files. I've done this for years, never had a problem.
If you don't want to open the file you can also use something like the access() function on POSIX-like platforms or _access() and friends on Windows. However, I like the Boost.Filesystem method Ricardo pointed out.