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.
Related
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;
}
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.
I am trying to open the utmp file in Linux and read the contents into an array of utmp structures. After that I display the ut_user and ut_type from each structure in the array. I have this working when I open the file with File *file and use the fopen() and fread() functions but when I try to do the same task with just a file descriptor int file and the open() and read() functions I get address locations when trying to access members of the utmp structure.
So in the below program you can see I commented out three lines of code which together I could use to successfully perform the task of reading the utmp file into an array of utmp structures and print out two of their members values. But when I try doing the exact same thing with the three lines of code (denoted "new way") in place of the old way that worked I get a bunch of address locations rather than the values of ut_user and ut_id.
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <utmp.h>
void utmpprint(struct utmp *log) {
printf("\n ut_user: %s \n ut_type: %ld \n", log->ut_user, log->ut_type);
}
int main() {
int logsize = 10;
//FILE *file; //Working way
int file; //New way
struct utmp log[logsize];
int i = 0;
//file = fopen("/var/run/utmp", "rb"); //Working way
file = open("/var/run/utmp", O_RDONLY); //New way
if( file < 0 ) { //New way
printf("Failed to open");
return(0);
}
if (file) {
//fread(&log, sizeof(struct utmp), logsize, file); //Working way
read(file, &log, logsize); //New way
for(i = 0; i < logsize; i++) {
utmpprint(&log[i]);
}
close(file); //New way
} else {
return(0);
}
return(0);
}
Here is some of the output for the working way:
And here is the output for the new way that is not working:
I have tried looking online for more information on this matter but I can't seem to find anything that uses the file descriptor and not File. I also tried changing around some of the pointers and references but that did not improve any of the results.
I am very new to C and I think I am probably using the read() function incorrectly in this case because I am passing a simple buffer into the read function when I think I should be somehow passing it the utmp structure array.
You are not reading enough data from the file.
read(file, &log, logsize);
should be:
read(file, &log, sizeof(log));
// or
read(file, &log, logsize * sizeof (struct utmp));
Also, in both cases, you should check the return value to see how many bytes were actually read.
Even though you could manipulate data from the utmp file by using the open() system call or functions derived from open(), it is impractical.
You could include the "utmp.h" header in your project and use predefined functions and data structures.
Here you can find the utmp.h file documentation.
Below is some code to print the ut_user and ut_type using the utmp.h data structures and functions.
#include <utmp.h>
#include <stdio.h>
#include <string.h>
int main()
{
struct utmp* data;
char aux[50];
data = getutent();
//getutent() populates the data structure with information
while(data != NULL )
{
/*make sure to use strncpy
*because most data fiels in the utmp struct
*have ___nonstring___ atribute */
strncpy(aux, data->ut_user, 32);
aux[32] = '\0';
printf("ut_user: %s\n", aux);
printf("ut_type: %hi\n\n", data->ut_type);
data = getutent();
}
return 0;
}
The output of the code is:
ut_user: reboot
ut_type: 2
ut_user: alc
ut_type: 7
ut_user: runlevel
ut_type: 1
How can I walk through all the commits of a branch using libgit2?
I have already the following bit of code, but it doesn't compile.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <git2.h>
int main(int argc, char *argv[]){
git_repository *repo;
git_repository_open(&repo, ".");
git_odb *obj_db;
obj_db = git_repository_database(repo);
git_object commit;
git_revparse_single(&commit, repo, "HEAD");
git_repository_free(repo);
return 0;
}
GCC reports:
log.c: In function ‘main’:
log.c:11:9: warning: assignment makes pointer from integer without a cast [enabled by default]
log.c:13:13: error: storage size of ‘commit’ isn’t known
I compiled with the -lgit2 flag. Is there a fast possibility to walk through all the commits, beginning from the root-commit?
Update
The new code looks like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <git2.h>
int main(int argc, char *argv[]){
git_repository *repo;
git_repository_open(&repo, ".");
git_odb *obj_db;
obj_db = git_repository_database(repo);
git_object *commit;
git_revparse_single(&commit, repo, "HEAD");
git_repository_free(repo);
return 0;
}
I get the following error messages:
log.c:11: undefined reference to `git_repository_database'
log.c:14: undefined reference to `git_revparse_single'
Finally, I created a working version using libgit2. Carlos Martín Nieto pointed in the right direction, the following example works great with libgit2 0.16. It took me some time to study the general.c I found in the libgit2-examples repository on github. git revwalk was exactly what I was looking for.
I noted that git adds an newline at the end of my commit messages, probably because I'm always using nano to write them, so I don't printf out the last character in my example code.
If anyone reads this and has the same problem as I had, here's the working code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <git2.h>
#define REPO ".git"
int main(void){
git_repository *repo;
if(git_repository_open(&repo, REPO) != GIT_SUCCESS){
fprintf(stderr, "Failed opening repository: '%s'\n", REPO);
return 1;
}
// Read HEAD on master
char head_filepath[512];
FILE *head_fileptr;
char head_rev[41];
strcpy(head_filepath, REPO);
if(strrchr(REPO, '/') != (REPO+strlen(REPO)))
strcat(head_filepath, "/refs/heads/master");
else
strcat(head_filepath, "refs/heads/master");
if((head_fileptr = fopen(head_filepath, "r")) == NULL){
fprintf(stderr, "Error opening '%s'\n", head_filepath);
return 1;
}
if(fread(head_rev, 40, 1, head_fileptr) != 1){
fprintf(stderr, "Error reading from '%s'\n", head_filepath);
fclose(head_fileptr);
return 1;
}
fclose(head_fileptr);
git_oid oid;
git_revwalk *walker;
git_commit *commit;
if(git_oid_fromstr(&oid, head_rev) != GIT_SUCCESS){
fprintf(stderr, "Invalid git object: '%s'\n", head_rev);
return 1;
}
git_revwalk_new(&walker, repo);
git_revwalk_sorting(walker, GIT_SORT_TOPOLOGICAL);
git_revwalk_push(walker, &oid);
const char *commit_message;
const git_signature *commit_author;
while(git_revwalk_next(&oid, walker) == GIT_SUCCESS) {
if(git_commit_lookup(&commit, repo, &oid)){
fprintf(stderr, "Failed to lookup the next object\n");
return 1;
}
commit_message = git_commit_message(commit);
commit_author = git_commit_committer(commit);
// Don't print the \n in the commit_message
printf("'%.*s' by %s <%s>\n", strlen(commit_message)-1, commit_message, commit_author->name, commit_author->email);
git_commit_free(commit);
}
git_revwalk_free(walker);
return 0;
}
Thanks!
I have already the following bit of code, but it doesn't compile
A git_commit is an opaque type, which means that your compiler doesn't know what it is, only that it exists. Thus you cannot allocate a git_commit on the stack. The library will allocate it on the heap for you.
You must use a pointer in your code and pass a pointer to that to the library's functions, as you can see in its documentation and the examples it links to.
Is there a fast possibility to walk through all the commits, beginning from the root-commit?
Those revwalk tests, demonstrating different walking strategies, may provide you with some help.
Adding to Pentax's answer above. If you just want to 'walk' the head, instead of doing all that work to get the old to the head to initialize the walker with:
git_revwalk_push(walker, &oid);
One could simply use:
git_revwalk_push_head(walker);
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/