First off: I know there are similar topics for C++, but I am curious about standard C, and I don't believe my problem is related to previous problems.
I am trying to implement Unicode support for a simple program which just asks the user to select a directory through a folder browser and then passes it to another program (only got to the first part). But when attempting to write the received path to a file, it results in a 0-byte file. And when printing it out using wprintf_s, non-ASCII characters come out as question marks. I don't believe there is any undefined behavior or anything as I've double checked documentation. So what am I doing wrong?
The code currently looks like this (just the bare minimum for strict test conditions):
#define UNICODE
#define _UNICODE
#include <windows.h>
#include <shlobj.h>
#include <stdio.h>
int main()
{
BROWSEINFOW bi = { 0 };
LPITEMIDLIST pidl;
wchar_t path[MAX_PATH];
pidl = SHBrowseForFolderW(&bi);
SHGetPathFromIDListW(pidl, path);
wprintf_s(L"%s\n", path);
return 0;
}
The above code prints it regularly. When attempting to write to a file instead, I replace the wprintf_s call with this (having declared FILE *f first of course):
if(_wfopen_s(&f, L"C:\\test.txt", L"w"))
{
fwprintf_s(f, L"%s\n", path)
fclose(f);
}
However, I have also tried using fwrite with both w and wb mode, but all methods results in an empty file.
You need _O_U16TEXT for console output, and "UTF-16LE" for file output.
Also, _wfopen_s returns zero when successful according to MS documentation:
Return Value Zero if successful; an error code on failure. See errno,
_doserrno, _sys_errlist, and _sys_nerr for more information about these error codes.
You should make sure return value is zero
if (0 == _wfopen_s(&f, filename, L"w, ccs=UTF-16LE")){
//isokay ...
}
or check if f is non-NULL. For example:
#include <stdio.h>
#include <io.h> //for _setmode
#include <fcntl.h> //for _O_U16TEXT
int main()
{
_setmode(_fileno(stdout), _O_U16TEXT);
const wchar_t *buf = L"ελληνική";
wprintf(L"%s\n", buf);
FILE *f = NULL;
_wfopen_s(&f, L"C:\\test\\test.txt", L"w, ccs=UTF-16LE");
if (f)
{
fwprintf_s(f, L"%s\n", buf);
fclose(f);
}
return 0;
}
Related
I'm using a library for my project. This library sometimes prints some messages to stdout. This is a problem for me because the messages are mixed up along with the application messages. It will be useful to a stop this behaviour or have them printed to a different window. I'm using C Language and Mingw32 enviroment. How can I do this? Thanks.
You might be able to (nonportably) swap the stdout with another stream:
#include <stdio.h>
FILE *devnull;
#define SWAPSTDOUT() do{ FILE *tmp = stdout; stdout = devnull; devnull = tmp; }while(0)
int main(void)
{
/*program initialization*/
if(0==(devnull= fopen("/dev/null", "r"))) return 1;
fputs("your code 0\n",stdout);
SWAPSTDOUT();
fputs("library code 0\n",stdout); //should be silent
SWAPSTDOUT();
fputs("your code 1\n", stdout);
}
Unfortunately, that's unlikely to work with functions that hardcode stdout (e.g., printf or puts).
If you're on a POSIX platform, you might have freopen but that won't help much if you can't save the original stream. However, on POSIX you could fflush(stdout) and then shuffle the underlying file descriptors, which should be quite reliable:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
int devnull, tmp;
int swapstdout(void);
int main(void)
{
/*program initialization*/
if(0>(devnull=open("/dev/null", O_RDONLY))) return EXIT_FAILURE;
if(0>(tmp=dup(devnull))) return EXIT_FAILURE; //reserve a fd spot
fputs("your code 0\n",stdout);
if(0>swapstdout()) return EXIT_FAILURE:
fputs("library code 0\n",stdout); //should be silent
if(0>swapstdout()) return EXIT_FAILURE:
fputs("your code 1\n", stdout);
}
int swapstdout(void)
{
if(0>fflush(stdout)) return -1;
if(0>dup2(STDOUT_FILENO,tmp)) return -1; /*really shouldn't happen*/
if(0>dup2(devnull,STDOUT_FILENO)) return -1; /*really shouldn't happen*/
if(0>tmp=dup(devnull)) return -1; /*really shouldn't happen unless we're multithreaded and another thread steals the fd spot*/
}
Either solution depends on your code being single threaded.
In any case, well behaved library functions should leave files they don't own alone, unless you explicitly request them to do something with such files.
I understand, there are thousands of problems like this, but I haven't managed to find the solution to my issue. Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
int main()
{
FILE *inputFile=fopen("I:\\Test\main.cpp","R");
FILE *outFile=fopen("I:\\Test\main2.cpp", "W");
if (inputFile==NULL) {
printf("Unable to locate source file");
_getch();
return 1;
}
int c;
int inSingleLine=0;
int inMultiLine=0;
int d=fgetc(inputFile);
while(c=fgetc(inputFile)!=EOF){
if (d==EOF) break;
if((c=='/') && (d=='*')) inMultiLine=1;
if ((c='*') && (d=='/')) inMultiLine=0;
if((c=='/')&& (d=='/')) inSingleLine=1;
if (c='\n') inSingleLine=0;
if (!inSingleLine && !inMultiLine) {
putc(c,outFile);
}
d=getc(inputFile);
}
// This is a test string
fclose(inputFile);
fclose(outFile);
/* And this is not a test
Actually not
*/
return 0;
}
No matter what I do, whether I put main.cpp to the same folder with the exe file and make it FILE *inputFile=fopen("main.cpp","R"); or specify an absolute path, I get "Unable to locate source file" all the time.
Please help!
The mode strings for read and write mode are "r" and "w", not "R" and "W". Using an invalid mode is probably what's causing fopen to fail.
int main()
{
FILE *inputFile=fopen("I:\\Test\main.cpp","R"); <-- This results in the string "I:\Testain.cpp"
...
Make sure you use two "\" symbols (escape both back-slashes), and use lower-case "w" and "r":
FILE *inputFile=fopen("I:\\Test\\main.cpp","r");
As above, you must "escape" a backslash with a double one. You should always check the return value from fopen() and then you can obtain a message based on errno. When I tried the following with a lower-case "r" I got a compiler warning about the invalid escape sequence \m but the program was well behaved.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
FILE *inputFile=fopen("I:\\Test\main.cpp","r");
printf("After trying to open\n");
if (inputFile == NULL)
printf ("%s\n", strerror(errno));
else
fclose(inputFile);
return 0;
}
I got:
After trying to open
No such file or directory
But when I tried it with an upper-case "R" the program hung (MSVC), I don't know why.
There are probably several problems with the code below. Found it online after searching for a way to get keyboard input in linux. I've verified the correct event for keyboard input. The reason it seems fishy to me is regardless of what i put in the filepath, it always seems to pass the error check (the open call returns something greater than 0). Something is obviously wrong, so suggestions are welcome.
This won't run correctly unless you run the exe as su.
When i want to read in my keystroke, do i just use something like fgets on the file descriptor in an infinite while loop(would that even work)? I want it to be constantly polling for keyboard inputs. Any tips on decoding the inputs from the keyboard event?
Thanks again! This project of mine may be overly ambitious, as it's been a really long time since i've done any coding.
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <fcntl.h>
#include <linux/input.h>
#include <unistd.h>
// Edit this line to reflect your filepath
#define FILE_PATH "/dev/input/event4"
int main()
{
printf("Starting KeyEvent Module\n");
size_t file; //will change this to int file; to make it possible to be negative
const char *str = FILE_PATH;
printf("File Path: %s\n", str);
error check here
if((file = open(str, O_RDONLY)) < 0)
{
printf("ERROR:File can not open\n");
exit(0);
}
struct input_event event[64];
size_t reader;
reader = read(file, event, sizeof(struct input_event) * 64);
printf("DO NOT COME HERE...\n");
close(file);
return 0;
}
the problem is here:
size_t file;
size_t is unsigned, so it will always be >=0
it should have been:
int file;
the open call returns something greater than 0
open returns int, but you put in in an unsigned variable (size_t is usually unsigned), so you fail to detect when it is <0
I have the following Config.cfg file and I want to read the values of Device
[BBDD]
user=**
password=***
database=***
IPServidor=*
port=3***
[Device]
dev=8
Temperatura=5=1001
Humedad=7=1002
Link=8=1003
Volt=9=1004
[Device]
dev=10
Temperatura=5=1012
Humedad=7=1013
Link=8=1014
Volt=9=1015
So I try with libconfig library. I wrote the following code but it returns me nothing. Am I missing something? Or is there any problem with libconfig? I tried also with glib but because of the same keyword Device I cannot use it.
#include <stdio.h> // standard input / output functions
#include <string.h> // string function definitions
#include <stdlib.h>
#include <libconfig.h>
#include <glib.h>
int main()
{
config_t cfg; //returns all parameters in this structure
config_setting_t *setting;
const char *str1, *str2;
int tmp;
config_init(&cfg);
if(config_read_file(&cfg, "Config.cfg"))
{
fprintf(stderr, "%s=%d\n", config_error_file(&cfg),config_error_line(&cfg),config_error_text(&cfg));
config_destroy(&cfg);
return(EXIT_FAILURE);
}
//Read the parameter group
setting = config_lookup(&cfg, "Device");
if (setting!= NULL)
{
//Read the string
if(config_setting_lookup_string(setting, "dev", &str1))
{
printf("\n Device: &s", str1);
}
else
printf("\n No 'Device' setting in configuration file");
printf("\n");
}
config_destroy(&cfg);
}
I tried both with Device and [Device] as keyword and also config_setting_lookup_string and config_setting_lookup_int to return the values of dev but nothing happens. My command returns me a simple
Process returned 0. execution time: 0.115sec
Your configuration doesn't seem to be a valid libconfig configuration file.
Check the libconfig documentation.
My first post :), am starting out with C language as basic learning step into programming arena. I am using following code which reads string from text file, makes directory with that string name and opens a file for writing in that created directory. But am not able to create a file inside directory made, here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <direct.h>
#include <string.h>
int main()
{
char file_name[25], cwd[100];
FILE *fp, *op;
fp = fopen("myfile.txt", "r");
if (fp == NULL)
{
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
fgets(file_name, 25, fp);
_mkdir(file_name);
if (_getcwd(cwd,sizeof(cwd)) != 0)
{
fprintf(stdout, "Your dir name: %s\\%s\n", cwd,file_name);
op = fopen("cwd\\file_name\\mynewfile.txt","w");
fclose(op);
}
fclose(fp);
return 0;
}
What you need is to store the file name (with the path) in a c-string before opening. What you are opening is cwd\file_name\mynewfile.txt. I doubt that your directory is named cwd.
A sample could could be:
char file_path[150];
sprintf(file_path, "%s\\%s\\mynewfile.txt", cwd, file_name);
op = fopen(file_path,"w");
use
#include <sys/stat.h>
#include <sys/types.h>
instead of
#include <direct.h>
and modify
op = fopen("cwd\\file_name\\mynewfile.txt","w”);
I see you are using the return values. That is a good start for a beginner. You can refine your error messages by including "errno.h". Instead of printing your own error messages call
printf("%s", strerror(errno));
You get more precise error messages that way.
op = fopen("cwd\\file_name\\mynewfile.txt","w”);
You’re actually passing the string literals “cwd” and “file_name” as part of the path of the file, when I think you actually mean to put the contents of the variables with those names in there. You will probably have to piece together a string for the path. Try looking into strcat()
http://www.cplusplus.com/reference/cstring/strcat/