I'm trying to understand how I can create a ".config" file containing a bunch of parameters to later use to set up the variables in my C project on Unix.
I created my ".config" file using sudo nano test.config and wrote some stuff inside such as:
#N is this
N 10
#p is that
p 0.002
#T is this
T 10
Now that I did that how can I read its content and use it to initialize my variables?
The several answers to this question explain how to parse that config file, but you could use standard parsing techniques (perhaps your own recursive descent parser) or Glib's lexical scanning or key-value pair parser (or use something else). You certainly should define and document (perhaps using EBNF) what is the format of that textual configuration file (and what the various entries there represent: for example, if that configuration file refers to other files, how do you handle spaces in such file paths, etc....). A common (but not universal) convention is to consider as comments so skip any line starting with #.
Another question is how to get that config file while running in an arbitrary working directory. You just need to build the absolute path of your file (for fopen(3) or open(2)), e.g. with
char configpath[100];
snprintf(configpath, sizeof(configpath), "%s/.test.config", getenv("HOME"));
You could test before that getenv("HOME") is not NULL, but in practice that is very unlikely; see environ(7) and getenv(3); and the case when it gives a very long file path is also unlikely; you might test that snprintf(3) returns a count less than sizeof(configpath) or use asprintf(3).
You might use other functions, e.g. glob(3) or wordexp(3) to get that file path (but you probably should stick to snprintf or asprintf with getenv("HOME")...).
You might consider instead embedding some scriptable interpreter like lua or guile in your program (but that is a strong architectural design decision). Then the configuration file becomes some (Turing-complete!) script.
BTW, there is no need to use sudo to edit that configuration file (under your home directory), and you might decide to also read some system-wide configuration under /etc/
According to Supported Win32 APIs for Windows Phone 8, WP8 does support many file manipulation APIs in fileapi.h like CreateFile2, ReadFile, WriteFile, ...
But when I include <stdio.h> I can use fopen, fread, fwrite, ...
Using both those APIs, I can create and read/write to a text file.
CreateFile2("hello.txt", ...);
fopen("hello.txt", ...);
... means other parameters, which aren't important to this question.
The other thing is that I don't know where that text file resides. Installed location isn't the case, because it is read-only location. The other case is Local folder, but I don't specify any Local folder path.
So what are the differences between those APIs (in fileapi.h and stdio.h) and which location does they act on ?
P/S: I'm doing in the WP Runtime Component
The main difference is the API set these functions use.
<stdio.h> contains the file APIs of the standard C library, <fileapi.h> is the Win32 APIs. There are also C++ APIs (<iostream>) which you could use.
I've found that whatever API you use, you should explicitly set the file location to the Local folder.
Platform::String^ localfolder = Windows::Storage::ApplicationData::Current->LocalFolder->Path;
Platform::String^ myFileName = Platform::String::Concat(localfolder, "\\myfile.txt");
One thing to watch is that Platform::String^ uses wchar_t, not char internally so you need to be a bit careful in specifying the file name.
So, try and find an API that takes wchar_t* for the file name and use that to avoid having to do character set conversion.
E.g.: Use _wfsopen instead of fopen.
Is there a Windows API function that I can pass a string value to that will return a value indicating whether a file name is valid or not?
I need to verify that a file name is valid, and I'm looking for an easy way to do it without re-inventing the wheel. I'm working in straight C, but targeting the Win32 API.
If there's no such function built-in, how would I go about writing my own? Is there a general algorithm or pattern that Windows follows for determining file name validity?
The problem is not so simple, because it depends from what you consider a "valid file name".
The Windows APIs used with UNC paths will let you happily create a lot of names that are deemed invalid inside normal paths, since with the prefix \\?\ you are telling to the Windows APIs to just deliver the path to the filesystem driver, without performing any check; the filesystems themselves often do not really care about what it's used as a file name, once they know that some string is only the file name (i.e. the path/name split has already been done) they generally treat it just as an opaque sequence of characters.
On the other hand, if you want to play it safe, you should perform validation according to the rules specified by the MSDN document you already linked for Win32 names; I don't think that any file system is allowed to have more stringent rules than these on file naming. On the other hand, violating such requirements, although can be supported by the kernel itself, often give bad headaches to many "normal" applications that expect to deal with "traditional" Win32 paths.
But, in my opinion, if you have to create the file immediately, the best validation you can do is to try to actually create/open the file, letting the OS do such work for you, and be prepared to handle gracefully a failure (GetLastError should return ERROR_BAD_PATHNAME). This will check any other restriction you have on creating such file, e.g. that your application has the appropriate permissions, that the path is not on a readonly medium, ...
If, for some reason, this is not possible, you may like the shell function PathCleanupSpec: provided the requested file name and the directory in the file system where it has to be created, this function will remove all the invalid characters (I'm not sure about reserved DOS names, they are not listed in its documentation) making the path "probably valid" and notifying you if any modification was made (so you can use it also only for validation).
Notice that this function is marked as "modifiable or removable in any future Windows version", although Microsoft policy is generally that "anything that made it way to a public header will remain public forever".
In case you are checking if the file name is valid in the sense "can the file be named like this?" :
No, there is no function to directly check that. You will have to write you own function.
But, if you know what is a valid file name (the valid file name does now contain any of the following: \ / : * ? " < > |) that shouldn't be such a problem.
You could perhaps help your self with some of these functions from ctype.h (with them you can check if a specific character belongs to some specific character classes):
http://www.cplusplus.com/reference/clibrary/cctype/
This function gives you the list of invalid chars for a filename. Up to you to check that your filename doesn't contain any:
public static char[] Path.GetInvalidFileNameChars()
Docs here.
Note that if you want to validate a directory name, you should use GetInvalidPathChars().
EDIT: Oooops! Sorry, I thought you were on .NET. Using Reflector, here's what this functions boils down to:
'"', '<', '>', '|',
'\0', '\x0001', '\x0002', '\x0003', '\x0004', '\x0005', '\x0006',
'\a', '\b', '\t', '\n', '\v', '\f', '\r',
'\x000e', '\x000f', '\x0010', '\x0011', '\x0012', '\x0013', '\x0014', '\x0015',
'\x0016', '\x0017', '\x0018', '\x0019', '\x001a', '\x001b', '\x001c', '\x001d',
'\x001e', '\x001f',
':', '*', '?', '\\', '/'
Note that, in addition, there are reserved names such as prn, con, com1, com2,... , lpt1, lpt2,...
I have trouble here using fopen to open files which have paths longer than the 260 characters supported by Windows natively.
I found out about the prefix \\\\?\\ which I need to put in front of the path to be able to handle the file.
My question is: Is this still valid in combination with fopen? I have still trouble to open the files, but I do not find information about it. My paths look like:
\\\\?\\C:\\Deposit\\Source\\Here_Comes_Now_A_List_Of_Many_Subdirs_And_A_Long_File_Name
I am not able to use the Windows API due to the requirement to write a cross-platform tool.
Just to update with the current state: I'm just quoting https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#enable-long-paths-in-windows-10-version-1607-and-later:
Starting in Windows 10, version 1607, MAX_PATH limitations have been
removed from common Win32 file and directory functions. However, you
must opt-in to the new behavior. To enable the new long path behavior,
both of the following conditions must be met: ...
And it is:
1. Having <longPathAware>true</longPathAware> in your application manifest (it was not default in my C++ Visual Studio project). My manifest file looks like this:
<assembly>
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings">
<ws2:longPathAware>true</ws2:longPathAware>
</windowsSettings>
</application>
</assembly>
and I have added it into Project Options -> Manifest Tool -> Input and Output -> Additional manifest files in my C++ Visual Studio project.
2. Enabled long paths in Windows (this can be done through registry (in item Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem\LongPathsEnabled by setting to 1) or Microsoft says that in Local Group Policy (item Computer Configuration -> Administrative Templates -> System -> Filesystem -> Enable Win32 long paths) - but this does not work for me).
Having both the above configured, you can simply use FILE *f = fopen("../my-very-long-path/my-file.txt") without any limitations (e.g. relative dirs and / with \ replacement work).
You could work around this limitation in a cross-platform way with conditional compilation:
#ifdef WIN32
myFile = _wfopen( ... )
#else
myFile = fopen( ... )
#endif
I think any non-trivial cross-platform project will have to do this somewhere, or else use a library (like SDL) that does.
I am trying to use _findfirst() Windows API in C to match file name using wildcards.
If I am passing ????????.txt then I am expecting it will match all the files in a directory with 8 characters only, but it matches more than that.
Is there any thing wrong with this usage?
I would guess that it is matching on the short name. On windows all files have a long name and a DOS 8.3 short name. Therefore "????????.txt" is effectively the same as "*.txt".
Also on a pedantic note, _findfirst() is not part of the Windows API. Is it part of the Microsoft C run-time library.