QSettings - What is the way to read path value? - c++

Using windows xp, i want to read a value from .ini file.
The value is a path.
Using QSettings, the result of the call to "settings.value("key").toString()" is the the path excluding backslashes, because backslash is escape character.
What is the way to read a path from ini file, using QSettings?

Although backslash is a special character in INI files, most Windows applications don't escape backslashes () in file paths [...]
QSettings always treats backslash as a special character and provides no API for reading or writing such entries.
This is what the documentation has to say about it. It is a polite way of saying "if some other code does it, they're not following the WINAPI spec and it's broken and we shouldn't have to deal with it". Pretty much your .ini files are broken.
If you wish to read them, you may need to provide your own backend for QSettings. Such a backend can be easily obtained by copying the one that comes as part of Qt, and modifying it not to perform escaping.
You'd need to investigate whether writing your own QTextCodec for this purpose and passing it to QSettings::setIniCodec would be sufficient. If sufficient, you wouldn't need to provide an entire backend.

To minimize compatibility issues, any # that doesn't appear at the first position in the value or that isn't followed by a Qt type (Point, Rect, Size, etc.) is treated as a normal character.
Although backslash is a special character in INI files, most Windows applications don't escape backslashes () in file paths
enter link description here

Related

Difference between \\ and / when working with path directories

Whenever I do any sort of file read or write, I always use the '/'
but I've seen some examples where the value of the given filepath is '\\' instead.
So what's the difference?
Am I doing it wrong or introducing bugs if I use '/'?
There's nothing wrong with using / on systems that support it. In fact, on UNIX systems it's the only thing that works.
Windows supports both / and \ as path separator in most situations.
Note that a platform agnostic option is available in the form of std::filesystem::path.
The common convention used for managing paths in Windows is just reciprocal of Linux. It's formatted something like: C:\abc\abc.txt, although it's your own choice which method you would prefer to access/write the file or folder.
This \\ is an escape sequence to print a common backslash to read or write the file. Note that you won't able to use a single backslash between string value since it reads next character as an escape sequence (e.g. \n, \b, etc.)
That's it.

c++ convert a char* of ascii characters to a unix filename

I have a char* which only contains ASCII characters (decimal: 32-126). I'm searching for a c++ function which escapes (add a backslash before the character) characters that have special meanings in the unix filesystem like '/' or '.'. I want to open the file with fopen later.
I'm not sure, if manually replacing would be a good option. I don't know all characters with special meanings. I also don't know if '?' or '*' would work with fopen.
Actually Unix (or more specific the SuS) disallows only the byte values '/' and '\0' in file names. Everything else actually is fair game. The exact (in the sense that they're immediately following and followed by a '/') strings "." and ".." are reserved to relative path access, but they are very well valid in a Unix path.
And of course any number and sequence of '.' is perfectly allowed in a Unix filename, as long as another character other than '/' or '\0' is part of the filename. Yes, newline, any control character, they're all perfectly valid Unix filenames.
Of course the file system you're using may have a different idea about what's permissible, but you were just asking about Unix.
Update:
Oh and it should be noted, that Unix doesn't specify dome "parse" method for filenames. Which essentially means, a filename is treated as a binary blob key into a key→value database. It also means, that there's no such thing as "escaping" for Unix filenames.
POSIX filenames don't have a concept of escape characters. There is no way to have a slash as an element of a filename (when the system renders filenames using Unicode you may be able to create a filename which looks as if it contains a slash, though). I think all other printable characters are just fine although using special characters like * and ? in filename will probably cause problems when people try use them from a shell.

Convert path to \\

Okay, after two days of searching the web and MSDN, I didn't found any real solution to this problem, so I'm gonna ask here in hope I've overlooked something.
I have open dialog window, and after I get location from selected file, it gives the string in following way C:\file.exe. For next part of mine program I need C:\\file.exe. Is there any Microsoft function that can solve this problem, or some workaround?
ofn.lpstrFile = fileName;
char fileNameStr[sizeof(fileName)+1] = "";
if (GetOpenFileName(&ofn))
strcpy(fileNameStr, fileName);
DeleteFile(fileName); // doesn't works, invalid path
I've posted only this part of code, because everything else works fine and isn't relevant to this problem. Any assistence is greatly appreciated, as I'm going mad in last two days.
You are confusing the requirement in C and C++ to escape backslash characters in string literals with what Windows requires.
Windows allows double backslashes in paths in only two circumstances:
Paths that begin with "\\?\"
Paths that refer to share names such as "\\myserver\foo"
Therefore, "C:\\file.exe" is never a valid path.
The problem here is that Microsoft made the (disastrous) decision decades ago to use backslashes as path separators rather than forward slashes like UNIX uses. That decision has been haunting Windows programmers since the early 1980s because C and C++ use the backslash as an escape character in string literals (and only in literals).
So in C or C++ if you type something like DeleteFile("c:\file.exe") what DeleteFile will see is "c:ile.exe" with an unprintable 0xf inserted between the colon and "ile.exe". That's because the compiler sees the backslash and interprets it to mean the next character isn't what it appears to be. In this case, the next character is an f, which is a valid hex digit. Therefore, the compiler converts "\f" into the character 0xf, which isn't valid in a file name.
So how do you create the path "c:\file.exe" in a C/C++ program? You have two choices:
"c:/file.exe"
"c:\\file.exe"
The first choice works because in the Win32 API (and only the API, not the command line), forward slashes in paths are accepted as path separators. The second choice works because the first backslash tells the compiler to treat the next character specially. If the next character is a hex digit, that's what you will get. If the next character is another backslash, it will be interpreted as exactly that and your string will be correct.
The library Boost.Filesystem "provides portable facilities to query and manipulate paths, files, and directories".
In short, you should not use strings as file or path names. Use boost::filesystem::path instead. You can still init it from a string or char* and you can convert it back to std::string, but all manipulations and decorations will be done correctly by the class.
Im guessing you mean convert "C:\file.exe" to "C:\\file.exe"
std::string output_string;
for (auto character : input_string)
{
if (character == '\\')
{
output_string.push_back(character);
}
output_string.push_back(character);
}
Please note it is actually looking for a single backslash to replace, the double backslash used in the code is to escape the first one.

How can I use custom fields in a vCard?

I'm writing an application which generates vCards from an internal customer database and would like to include additional information in the card, e.g. internal customer number. Reading the RFC, I've see "vendor-specific" extensions, which are to be registered at IANA etc. Are these extensions the way to go? What should I keep in mind while using them, any pitfalls? Are there any alternative ways to define a custom field in a vCard?
RFC 2426 section 4 specifies how to create non-standard names. If you read the production rules, you'll get the exact way properties can be defined. For example, to define a customer number, you could say simply X-CUSTOMER-ID:123 on a separate line.
Things to beware:
Escaping characters like comma, semicolon, colon and newline. This is well defined in the syntax rules.
Which things are case sensitive and which are not. Ditto.
Encoding and line endings in the resulting file. Just to use UTF-8, line endings \r\n (Windows style) and an extra empty line at the end of the file.

How can I make a case-insensitive regexp match for Russian letters?

I have list of catalog paths and need to filter out some of them. My match pattern is in a non-Unicode encoding.
I tried the following:
require 5.004;
use POSIX qw(locale_h);
my $old_locale = setlocale(LC_ALL);
setlocale(LC_ALL, "ru_RU.cp1251");
#{$data -> {doc_folder_rights}} =
grep {
# catalog path pattern in $_REQUEST{q}
$_->{doc_folder} =~/$_REQUEST{q}/i;
}
#{$data -> {doc_folder_rights}};
setlocale(LC_ALL, $old_locale);
What I need is case-insensitive regexp pattern matching when pattern contains russsian letters.
There are several (potential) issues with your code:
Your code filters out all doc_folders that do not match the regexp in $_REQUEST{q}, however the question suggests that you want to do the opposite.
You might have an encoding issue. Setting the locale (using setlocale) changes the perl's handling of upper- & lower-case-conversions, but it does not change any encoding. You need to assure that $_REQUEST{q} is interpreted correctly.
For simplicity you can assume that any Perl-string contains Unicode-data in some internal representation that you need not know about in detail. Only when Perl does I/O there is an implicit or explicit conversion. When reading from stdin, ARGV or environment, Perl assumes that the bytes are encoded using the current locale and implicitly converts.
If you have an encoding issue, there are several ways to fix it:
Fix the environment in which Perl runs so that it knows about the correct locale from the very start. That will fix the implicit conversion.
In the unlikely case that $_REQUEST is loaded from a filehandle, you could explicitly tell Perl to convert using binmode($fh, ":encoding(cp1251)");. Do that prior the reading $_REQUEST.
There is the $string = Encode::decode(Encoding, $octets) function that tells Perl to forget its assumption about the encoding of $octets and instead treat the contents of $octets as byte-stream that needs to be converted to Unicode using Encoding. You need to do that before touching the contents of $octets, or strange things may happen.
Since $_REQUEST was probably loaded by some cgi-module, and was probably url-encoded in transit, you could just tell the cgi-module how to correctly do the decoding.