Writing to a file in Unicode - c

I am having some problems writing to a file in unicode inside my c program. I am trying to write a unicode Japanese string to a file. When I go to check the file though it is empty. If I try a non-unicode string it works just fine. What am I doing wrong?
setlocale(LC_CTYPE, "");
FILE* f;
f = _wfopen(COMMON_FILE_PATH,L"w");
fwprintf(f,L"日本語");
fclose(f);
Oh about my system:
I am running Windows. And my IDE is Visual Studio 2008.

You might need to add the encoding to the mode. Possibly this:
f = _wfopen(COMMON_FILE_PATH,L"w, ccs=UTF-16LE");

Doing the same with fopen() works for me here. I'm using Mac OS X, so I don't have _wfopen(); assuming _wfopen() isn't returning bad stuff to you, your code should work.
Edit: I tested on cygwin, too - it also seems to work fine.

I cannot find a reference to _wfopen on either of my boxes, I however don't see why opening it with fopen should cause a problem, all you need is a file pointer.
What matters is if or not C recognizes the internal Unicode's values and pushes those binary values to the file properly.
Try just using fopen as Carl suggested, it should work properly.
Edit: if it still doesn't work you may try defining the characters as their integer values and pushing them with fwprintf(), I know that's cumbersome and not a good fix in the long run, but it should work as well.

Related

C - How do I make a function that finds the location of a file it has to use just by giving it the filename? (Windows)

I am having trouble with the function fopen(). I would always send the exact location of a file as an arguement to fopen(),
which would look something like this:
fopen("c:\\Users/Username/Desktop/Projects/program_name/version 1.0/data/important_data.txt", "r");
That works just fine on my computer, but what if I decide to transfer the program to another computer?
The location would completely change.
It would no longer be:
c:\\Users/Username/Desktop/Projects/program_name/version 1.0/data/important_data.txt
But it would rather be something like:
c:\\Users/OtherUsername/Desktop/program_name/version 1.0/data/important_data.txt
My question is, how do I make a portable function which can obtain the location of a file, if I only give the
name (including the type e.g. .txt) of the file to the function?
Keep in mind, I've been learning C for less than a year. There are still a lot of things which I must learn, and
things like this are of high importance.
this is operating system specific. on linux you can use the locate shell command and parse its output ( http://www.linfo.org/locate.html )
C: Run a System Command and Get Output?
How do I execute a Shell built-in command with a C function?
however this solution will only work on linux. i think yano's solution in the comments above is better ...

scanf-printf call messes non-ASCII chars after locale is set

I wonder why non-ASCII localed input-output fails:
setlocale(LC_ALL,"");
scanf("%s",buffer); // I type "příšerně"
printf("%s",buffer); // I get "pýˇçernŘ"
The locale is Czech_Czech Republic.1250 and all the non-ASCII chars (říšě) are in CP1250. Why it fails? The reference says
In <cstdio> (<stdio.h>), formatted input/output operations are
affected by character transformation rules.
Using the default "C" locale gives correct output. How to fix it? On Windows I can't use UTF-8 in setlocale
If you provide a code page value of UTF-7 or UTF-8, setlocale will
fail, returning NULL.
In my project I use setlocale to read UTF8 text file and to display it on console using WinAPI MultiByteToWideChar function, but that requires system default locale, so I need to set the locale.
edit: I just found the input is in CP852, which is the default in "C". I suppose I could use iconv, but I'd rather convince scanf not to stay with CP852.
After 3 hours of testing, I finaly got the working solution. It might not work for everybody since there is still a little mystery behind it. So this helped:
setlocale(LC_CTYPE,"Czech_Czech Republic.852");
CP852 was the default console codepage for Central Europe since DOS times. There is also chcp DOS command and SetConsoleCP and SetconsoleOutputCP winAPI functions. For some reason, this still messes the output:
setlocale(LC_CTYPE,"Czech_Czech Republic.1250");
SetConsoleCP(1250);
SetConsoleOutputCP(1250);
...but this is OK
setlocale(LC_CTYPE,"Czech_Czech Republic.852");
SetConsoleCP(852); // default in CE win console
SetConsoleOutputCP(852); // default in CE win console
Note that UTF-8 can't be set in setlocale, see the original question.

Can any programs read a text file into c++ code?

Is it possible for a program to open up a text file and use it as c++ code? If so, how? What if a program wanted to append code from a text file to itself? Can that happen?
Thanks!
Depends on what you mean by "text file" and "use it as c++ code." If by "text file" you mean a file containing uncompiled C++ code, and by "use it as C++ code" you mean execute it, the answer is no, you'd need to compile it first before it's of any real use (unless you want to write some sort of interpreter or compiler).
With regards to your second question, I suppose it's possible, but it'd be really hard because you would need to compile the C++ code in that text file into binary, then insert it into the program in a meaningful way.
If you're doing this just for curiosity, you might have better luck with an interpreted language (such as Perl or Ruby). I was a bit curious myself, so I took a stab at the problem with the following ruby script (saved in alpha.rb):
File.open('alpha.rb', 'a') do |file1|
file1.puts "\nprint 'Sneaky Addition!'";
end
After you run it, you'll see that a new line of code has been added. If you run it a second time, it'll run the code. I believe the reason that it isn't run the first time is that the file is already loaded into Ruby when it's run, so it doesn't see the change to the file until it reloads it.
Of course, we could possibly get around this by using a second file (as explained here)...
Alpha.rb
print "Alpha running...\n"
File.open('beta.rb', 'a') do |beta|
beta.puts("\nprint \"But alpha got the last word.\\n\"")
end
load 'beta.rb';
Beta.rb
print "Beta running...\n"
File.open('alpha.rb', 'w') do |alpha|
alpha.puts("print \"Sneaky Beta addition.\\n\"")
alpha.puts("\nprint \"Beta overwrote alpha!\\n\"")
alpha.puts("\nprint \"This code only works once =) \\n\"")
end
load 'alpha.rb'
I suppose you might be able to do something similar in C++, but it'd be much more complicated since you would be compiling your code into binary, and even then you probably can't just append it.

How to AllocConsole + Stdout redirect under cygwin

I have a complex >>cygwin<< windows application (aka. subsystem windows), and I want to add a debug console. I already tried the following variants, but none works for me.
The console appears with changed title, but remains dead-black, no output shown.
Variant 1)
ok = AllocConsole();
if (ok) {
h = GetStdHandle(STD_OUTPUT_HANDLE);
fd = _open_osfhandle((intptr_t)h, O_TEXT);
fp = _fdopen( fd, "w" );
*stdout = *fp;
setvbuf( stdout, NULL, _IONBF, 0 );
fprintf(stdout, "Hello worldd\n");
SetConsoleTitle("VM Debug");
}
Variant 2)
freopen("conout$","w",stdout);
fprintf(...
Variant 3)
freopen("/dev/conout","w",stdout);
fprintf(...
This may have been answered already many times, but none of the solutions worked for me.
Can anyone please help me?
But please keep in mind: it MUST be a cygwin problem and I need a cywin solution, as I know that one or the other variant works under MSVC or BorlandC.
Any answer helps, even one saying that cygwin is broken and there is no solution for me.
Yes, it is a cygwin problem. Cygwin's guys actually have worked hard to simulate as much as possible an "unix" environment, so the common W32 tricks can't work. You can anyway write your messages on the new console by using the WriteConsole function, but I see it isn't what you want. In the past I had a similar problem, ad solved it by creating a pipe(), redirecting it to stdout/stderr, and creating a thread that received characters from the pipe end wrote them to the new console via WriteConsole. Not easy.
Also, I think that the cygwin's console management has changed many times with the different versions, so maybe that a trick that seems to work with one version stops working wit another one.
It's a wild world...

fopen fails mysteriously under Windows

Maybe I just have another black out but, this one line is giving me a lot of troubles:
FILE *fp = fopen("data/world.data", "rb");
This works fine under Linux when compiled with GCC. But when I compile it with Visual Studio, it crashes. fp is always NULL. Both the BIN and the EXE are in the exact same directory. Now, to make things even crazier, when I run the EXE using Wine under Linux... it... works...
I have absolutely not a god damn clue what's going on here. Maybe it's some insanely stupid mistake on my side, but I cannot get this thing to run under Windows :/
Also, I have another program which works just fine, there the data files are also contained in a sub directory named data.
EDIT:
To make it clear neither / NOR `\ * do work.
EDIT 2:
OK I've given up on this, maybe someone has fun trying to figure it out, here's ZIP containing the EXE, Debug Data for VS etc.:
https://dl.dropbox.com/u/2332843/Leaf.zip
EDIT 3:
Compiled it with CodeBlocks and MinGW, works like a charm. Guess it has to do something with MSVC or the Project Settings in VS.
It sounds like data isn't a subdirectory of your current directory when you run the program. By default (for x86 targets) VS will build and run your program from either a DEBUG or RELEASE subdirectory of the base directory you've created for the project. You can modify the directory that will be "current" when it runs though (e.g., project | properties | configuration properties | debugging for VS 2008).
Edit: While Windows requires that you use a backslash as a directory separator at the command line, a forward slash works fine in code -- this is not the source of your problem.
In windows you have to write the following:
FILE *fp = fopen("data\\world.data", "rb");
This is like that because the backslash is a special character (so a backslash in a string is written using \ and a quotation symbol is \" and so with other special characters).
Since this issue happens only on windows. I doubt whether the file is really named "world.data". As you know, the default setting for windows hides the file extention. Is its real name world.data.xxx?
Include a line to GetCurrentDirectory(), to see if you are running from the directory you expected.
When I develop in C#/ C++ on visual studio, I normally get to run it from the debug folder. I don't think it matters if forward slash is used in place of backslash in .net.
I happened to have the same problem, and suddenly i figured it out.
That should be your windows fault.
Let's say, FILE *fp = fopen("data/world.data", "rb"); in windows, if you hide the extensions, then you can see the file data/world.data, but actually it maybe /data/world.dat.txt or somewhat.
So please check the extensions.
Hope it helps!
I ran into this today, and it happened because I used "br" instead of "rb" on that mode argument.
The underlying fopen is throwing an exception of some kind, which only registers as a crash. It's not bothering to return the standard NULL response or set the associated error values.
I'm not sure but it may be because you're using slash instead of (an escaped) backslash in the path?

Resources