QT how to parse objects inside an array json - arrays

I've got a JSON with the following structure
[{
"primul": "Thor",
"alDoilea": "Odin",
"alTreilea": "Loki"
},
{
"s": 1,
"d": 7,
"hp": 39
},
{
"1": "sabie",
"2": "scut",
"3": "coif"
}
]
Basically it's an array with x objects inside.
I've tried using QVariant to transform the data into a list and then map the elements of the list but it keeps throwing me cannot convert const char to int when using QVariantMap
Where am I going wrong?
Here is my code
QFile file2("../JsonExemplu/exampleArray.json");
if (!file2.exists()) {
qDebug()<<"Fisierul nu a fost gasit ";
exit(1);
}
if(!file2.open(QIODevice::ReadOnly)){
qDebug()<<"Nu s-a putut deschide fisierul JSON ";
exit(1);
}
QTextStream file_text(&file2);
QString json_string;
json_string = file_text.readAll();
file2.close();
QByteArray json_bytes = json_string.toLocal8Bit();
auto json_doc=QJsonDocument::fromJson(json_bytes);
if(!json_doc.isArray()){
qDebug() << "Formatul nu e de tip arrray.";
exit(1);
}
QJsonArray json_array = json_doc.array();
if(json_array.isEmpty()){
qDebug() << "JSON gol";
exit(1);
}
QVariantList root_map = json_array.toVariantList();
QVariantMap stat_map = root_map["nume"].toMap();
QVariantMap stat_map2 = root_map["statistici"].toMap();
QVariantMap stat_map3 = root_map["inventar"].toMap();
QStringList key_list = stat_map.keys();
for(int i=0; i< json_array.count(); ++i){
QString key=key_list.at(i);
QString stat_val = stat_map[key.toLocal8Bit()].toString();
qDebug() << key << ": " << stat_val;
}
}

The problem is that your convert QJsonArray to a list of variants. However you refer to that list as if it's a map - this will, of course, not compile. To fix the problem you need to use the appropriate QList API, i.e:
QVariantList root_map = json_array.toVariantList(); // This is a list, not a map!
// There are three items in the list.
// The code below can be put into a loop.
QVariantMap stat_map = root_map.at(0).toMap();
QVariantMap stat_map2 = root_map.at(1).toMap();
QVariantMap stat_map3 = root_map.at(2).toMap();
QStringList key_list = stat_map.keys();
for (int i = 0; i< key_list.count(); ++i)
{
QString key = key_list.at(i);
QString stat_val = stat_map[key.toLocal8Bit()].toString();
}

Related

array packetizer in JSON format in C

I am developing the JSON array packetizer in C to send response back to http server
example format in JSON array
"fat": [
23,
152689,
"Segmentation Fault"
]
Code in C
void arrFunc(char* buffer, const char* name, const int* value, int count)
{
if ((buffer == NULL) || (name == NULL))
{
return;
}
char numberChar[VALUE_FIELD_LENGTH];
strncat(buffer, "\"", 1);
strncat(buffer, name, strlen(name));
strncat(buffer, "\":", 2);
strncat(buffer, "[", 1);
if (value != NULL)
{
for (int i = 0; i < count; i++)
- {
snprintf(numberChar, VALUE_FIELD_LENGTH, "%u", value[i]);
strncat(buffer, numberChar, 1);
if(i<count-1)
strncat(buffer, ",", 1);
numberChar[i] = '\0';
}
}
strncat(buffer, "]", 1);
}
/* main *//
int arr[5] = { 1,2,3,4,5 };
char* msg;
if (msg != NULL)
{
msg[0] = '\0';
arrFunc(msg, "fat",(const int *) arr,3);
}
Output :
"fat": [
1,
2,
3
]
I am able to achieve array packetizer of similar data types like integer but how to achive for
different data type [23,152689,"Segmentation Fault"]
There's many ways to solve this problem, but one of them is tagged unions.
#include <stdio.h>
// TODO: include an implementation of a map
struct map {};
// TODO: include a dynamic array that knows size of data it holds
struct array {};
enum DataType {
JSON_MAP,
JSON_ARRAY,
JSON_NUMBER,
JSON_STRING
};
union Data {
float number;
char* string;
struct map map;
struct array array;
};
struct Json {
enum DataType kind;
union Data data;
};
// TODO: turn this into json serializer
void print_json(struct Json data) {
switch(data.kind) {
case JSON_NUMBER:
printf("%d\n", data.data.number);
break;
case JSON_STRING:
puts(data.data.string);
break;
default:
puts("TODO: print map and array");
}
}
int main() {
struct Json data1 = { .kind = JSON_NUMBER, .data.number = 12.34 };
struct Json data2 = { .kind = JSON_STRING, .data.string = "Hello, Json!" };
// invalid, but we never read it in this example
struct Json data3 = { .kind = JSON_ARRAY };
print_json(data1);
print_json(data2);
print_json(data3);
}
I don't think this requires further explanation but keep in mind that both the map and array should hold elements of type struct Json too, which is how you can build structures such as:
{ // JSON_MAP
"example": [ // JSON_ARRAY
1, // JSON_NUMBER
"42", // JSON_STRING
{ "etc": { "1": 2, "a": [3, 2, 1] } } // JSON_MAP (again)
]
}

How to include the size of array into the for loop without triggering error

This is the login function that I want to implement.
The problem is that I want to use the syntax of sizeof(id) in the for loop without triggering error.
Any solution??
int login();
int login()
{
int i, att, num_i, status;
att = 1;
status = 0;
num_i = 999;
char* id[100], * pass[100];
char* inp_id[100], inp_pass[100];
id[0] = "id1"; ///Sample ID
id[1] = "id2";
id[2] = "id3";
pass[0] = "pass1"; ///Sample pass
pass[1] = "pass2";
pass[2] = "pass3";
while (att <= 3)
{
printf("ID:");
scanf("%s", &inp_id);
for (i = 0; i < 3; ++i) /// I wanted this to repeat accordingly to the size of ID that was stored
{
if (strcmp(inp_id, id[i]) == 0) /// Cuz when I declare i > 100 when it call for i[4] and it doesn't exist, error occured.
{
num_i = i;
break; /// wanted it to break out of the loop once it got the id that's similar to what was entered
}
}
printf("Password:");
scanf("%s", &inp_pass);
if (num_i < 100)
{
if (strcmp(inp_pass, pass[num_i]) == 0)///checking pass according to the positon of i on the ID
{
status = 1;
att = 999;
}
}
att++;
}
I've deleted a portion of the code due to it asking for more information.
A simplified example of what I described in my comment:
Or at least these are components to help you understand.
struct account {
char *id;
char *pass;
};
static const struct account account_list[] = {
{ .id = "id1", .pass = "pass1" },
{ .id = "id2", .pass = "pass2" },
{ .id = "id3", .pass = "pass3" },
{ NULL },
};
struct account *a;
for (a = account_list; a.id; a++) {
....
}
Something like this is much easier to work with.

jansson-change json value in file

I have a json file. And, the file is successfully loaded.
but, i would like to change the value such as below
and save the json file with the modification.
But, the value is not changed and saved at all.
How could i do?
from /home/pi/desktop/test.json
{
"new_one": 1,
"new_two" : "do not",
"new_three" : true
}
to /home/pi/desktop/test.json
{
"new_one": 234,
"new_two" : "do",
"new_three" : false
}
So, i did
int main()
{
json_t *json;
json_error_t error;
char *pos;
json_t *obj = json_object();
int rc =0 ;
json = json_load_file("./test.json", 0, &error);
if (!json)
{
fprintf(stderr, "process : json error on line %d: %s\n", error.line, error.text);
rc = 1;
}
const char *key;
json_t *value;
void *iter = json_object_iter( json );
while( iter )
{
key = json_object_iter_key(iter);
value = json_object_iter_value(iter);
if(!strcmp(key, "new_one")){
printf("Change Value\n" );
json_object_set(iter, "new_one", json_integer(1234));
}
if(!strcmp(key, "new_three")){
printf("Change Value\n" );
json_object_set(iter, "new_three", json_string("alert"));
}
iter = json_object_iter_next(json, iter);
}
return 0;
}
You are missing a call to json_dump_file(), which will save your modified JSON contents to file.
So, after your while() loop, add this:
rc = json_dump_file(json, "./test.json", 0);
if (rc) {
fprintf(stderr, "cannot save json to file\n");
}

libgit2 (git_status_byindex(status, i))->head_to_index->old_file.path is NULL, why? (libgit status example)

how can i get status in libgits2's examples to work? as i keep getting NULL for s->head_to_index->old_file.path and the docs https://libgit2.org/docs/guides/101-samples/#status and the api site https://libgit2.org/libgit2/#HEAD/group/status/git_status_byindex are of little help
and the original examples src/status.c crashes on git cloned repositories
Enter command line arguments.
> status --git-dir=../libgit2
# On branch master
# Changes not staged for commit:
# (use "git add/rm <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
SIGSEGV on thread : 1083740160
Yet if i copy the file to the repo and compile it it works but still is null
Enter command line arguments.
> status2
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: (null)
# new file: (null)
# new file: (null)
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# (null)
# (null)
# (null)
# (null)
however if i use a foreach instead
void gitprefix(parse_optsST)(struct opts *o, int argc, char *argv[]);
void gitprefix(show_branchST)(git_repository *repo, int format);
int gitprefix(ensure_there_are_changes_to_stash)(git_repository * repo);
void gitprefix(print_shortST)(git_repository *repo, git_status_list *status);
int gitprefix(print_submodST)(git_submodule *sm, const char *name, void *payload);
int gitprefix(status)(int argc, char *argv[])
{
git_repository *repo = NULL;
git_status_list *status;
struct gitprefix(optsST) o = { GIT_STATUS_OPTIONS_INIT, ".",0,0,0,0,0,0 };
git_libgit2_init();
o.statusopt.show = GIT_STATUS_SHOW_INDEX_AND_WORKDIR;
o.statusopt.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED |
GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX |
GIT_STATUS_OPT_SORT_CASE_SENSITIVELY;
gitprefix(parse_optsST)(&o, argc, argv);
/**
* Try to open the repository at the given path (or at the current
* directory if none was given).
*/
gitret(check_lg2(git_repository_open_ext(&repo, o.repodir, 0, NULL),
"Could not open repository", o.repodir));
if (git_repository_is_bare(repo))
gitret(fatal("Cannot report status on bare repository",
git_repository_path(repo)));
show_status:
if (o.repeat)
printf("\033[H\033[2J");
/**
* Run status on the repository
*
* We use `git_status_list_new()` to generate a list of status
* information which lets us iterate over it at our
* convenience and extract the data we want to show out of
* each entry.
*
* You can use `git_status_foreach()` or
* `git_status_foreach_ext()` if you'd prefer to execute a
* callback for each entry. The latter gives you more control
* about what results are presented.
*/
if (o.showsubmod) {
int submod_count = 0;
gitret(check_lg2(git_submodule_foreach(repo, gitprefix(print_submodST), &submod_count),
"Cannot iterate submodules", o.repodir));
}
if (o.format == FORMAT_LONG)
gitprefix(ensure_there_are_changes_to_stash)(repo);
else {
gitret(check_lg2(git_status_list_new(&status, repo, &o.statusopt),
"Could not get status", NULL));
gitprefix(print_shortST)(repo, status);
if (status) git_status_list_free(status);
}
if (o.repeat) {
sleep(o.repeat);
goto show_status;
}
if (repo) git_repository_free(repo);
git_libgit2_shutdown();
return 0;
}
/**
* If the user asked for the branch, let's show the short name of the
* branch.
*/
void gitprefix(show_branchST)(git_repository *repo, int format)
{
int error = 0;
const char *branch = NULL;
git_reference *head = NULL;
error = git_repository_head(&head, repo);
if (error == GIT_EUNBORNBRANCH || error == GIT_ENOTFOUND)
branch = NULL;
else if (!error) {
branch = git_reference_shorthand(head);
git_reference_free(head);
} else
gitret(check_lg2(error, "failed to get current branch", NULL));
if (format == FORMAT_LONG)
printf("# On branch %s\n",
branch ? branch : "Not currently on any branch.");
else
printf("## %s\n", branch ? branch : "HEAD (no branch)");
}
/**
* This function print out an output similar to git's status command
* in long form, including the command-line hints.
*/
struct collectlist {
const char * path;
git_status_t status;
void * payload;
} *status_list;
int status_list_index = 0;
static int gitprefix(collect_cb)(const char *path, git_status_t status, void *payload)
{
struct list * p = realloc(status_list, sizeof(*status_list)*(status_list_index+1));
if (p == NULL) {
puts("failed to reallocate list");
return 1;
}
status_list = p;
status_list[status_list_index].path = path;
status_list[status_list_index].status = status;
status_list[status_list_index].payload = payload;
status_list_index++;
return 0;
}
int nothing(void) {
int changes_in_index = 0, changed_in_workdir = 0, has_untracked_files = 0;
for (int i = 0; i < status_list_index; i++) {
char * istatus = NULL;
if (status_list[i].status == GIT_STATUS_CURRENT)
continue;
if (status_list[i].status & GIT_STATUS_INDEX_NEW)
istatus = "new file: ";
if (status_list[i].status & GIT_STATUS_INDEX_MODIFIED)
istatus = "modified: ";
if (status_list[i].status & GIT_STATUS_INDEX_DELETED)
istatus = "deleted: ";
if (status_list[i].status & GIT_STATUS_INDEX_RENAMED)
istatus = "renamed: ";
if (status_list[i].status & GIT_STATUS_INDEX_TYPECHANGE)
istatus = "typechange:";
if (istatus == NULL)
continue;
changes_in_index = 1;
}
for (int i = 0; i < status_list_index; i++) {
char *wstatus = NULL;
if (status_list[i].status & GIT_STATUS_WT_MODIFIED)
wstatus = "modified: ";
if (status_list[i].status & GIT_STATUS_WT_DELETED)
wstatus = "deleted: ";
if (status_list[i].status & GIT_STATUS_WT_RENAMED)
wstatus = "renamed: ";
if (status_list[i].status & GIT_STATUS_WT_TYPECHANGE)
wstatus = "typechange:";
if (wstatus == NULL)
continue;
changed_in_workdir = 1;
}
for (int i = 0; i < status_list_index; i++) if (status_list[i].status == GIT_STATUS_WT_NEW) has_untracked_files = 1;
if (!changes_in_index && !changed_in_workdir && !has_untracked_files) return -1;
return 0;
}
int gitprefix(ensure_there_are_changes_to_stash)(git_repository *repo)
{
int error;
git_status_options opts = GIT_STATUS_OPTIONS_INIT;
opts.show = GIT_STATUS_SHOW_INDEX_AND_WORKDIR;
//opts.flags = GIT_STATUS_OPT_EXCLUDE_SUBMODULES | GIT_STATUS_OPT_INCLUDE_UNTRACKED | GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS | GIT_STATUS_OPT_INCLUDE_IGNORED | GIT_STATUS_OPT_RECURSE_IGNORED_DIRS;
opts.flags = GIT_STATUS_OPT_EXCLUDE_SUBMODULES | GIT_STATUS_OPT_INCLUDE_UNTRACKED | GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS | GIT_STATUS_OPT_INCLUDE_IGNORED | GIT_STATUS_OPT_RECURSE_IGNORED_DIRS | GIT_STATUS_OPT_INCLUDE_UNREADABLE | GIT_STATUS_OPT_RENAMES_FROM_REWRITES | GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX | GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR;
status_list_index = 0;
/*
pi(GIT_STATUS_CURRENT)
pi(GIT_STATUS_INDEX_NEW)
pi(GIT_STATUS_INDEX_MODIFIED)
pi(GIT_STATUS_INDEX_DELETED)
pi(GIT_STATUS_INDEX_TYPECHANGE)
pi(GIT_STATUS_INDEX_RENAMED)
pi(GIT_STATUS_WT_NEW)
pi(GIT_STATUS_WT_MODIFIED)
pi(GIT_STATUS_WT_DELETED)
pi(GIT_STATUS_WT_TYPECHANGE)
pi(GIT_STATUS_WT_RENAMED)
pi(GIT_STATUS_WT_UNREADABLE)
pi(GIT_STATUS_IGNORED)
pi(GIT_STATUS_CONFLICTED)
*/
error = git_status_foreach_ext(repo, &opts, gitprefix(collect_cb), NULL);
if (error)
{
puts("an error has occured collecting status information");
if (status_list) free(status_list);
status_list = NULL;
status_list_index = 0;
return error;
}
if (nothing()) {
puts("nothing to commit");
status_list_index = 0;
if (status_list) free(status_list);
status_list = NULL;
return 0;
}
gitprefix(show_branchST)(repo, FORMAT_DEFAULT);
// info collected, print it
int header = 0, changes_in_index = 0, changed_in_workdir = 0, rm_in_workdir = 0;
const char *old_path, *new_path;
for (int i = 0; i < status_list_index; i++) {
char * istatus = NULL;
if (status_list[i].status == GIT_STATUS_CURRENT)
continue;
if (status_list[i].status & GIT_STATUS_WT_DELETED)
rm_in_workdir = 1;
if (status_list[i].status & GIT_STATUS_INDEX_NEW)
istatus = "new file: ";
if (status_list[i].status & GIT_STATUS_INDEX_MODIFIED)
istatus = "modified: ";
if (status_list[i].status & GIT_STATUS_INDEX_DELETED)
istatus = "deleted: ";
if (status_list[i].status & GIT_STATUS_INDEX_RENAMED)
istatus = "renamed: ";
if (status_list[i].status & GIT_STATUS_INDEX_TYPECHANGE)
istatus = "typechange:";
if (istatus == NULL)
continue;
if (!header) {
printf("# Changes to be committed:\n");
printf("# (use \"git reset HEAD <file>...\" to unstage)\n");
printf("#\n");
header = 1;
}
printf("#\t%s %s\n", istatus, status_list[i].path);
}
if (header) {
changes_in_index = 1;
printf("#\n");
}
header = 0;
for (int i = 0; i < status_list_index; i++) {
char *wstatus = NULL;
if (status_list[i].status & GIT_STATUS_WT_MODIFIED)
wstatus = "modified: ";
if (status_list[i].status & GIT_STATUS_WT_DELETED)
wstatus = "deleted: ";
if (status_list[i].status & GIT_STATUS_WT_RENAMED)
wstatus = "renamed: ";
if (status_list[i].status & GIT_STATUS_WT_TYPECHANGE)
wstatus = "typechange:";
if (wstatus == NULL)
continue;
if (!header) {
printf("# Changes not staged for commit:\n");
printf("# (use \"git add%s <file>...\" to update what will be committed)\n", rm_in_workdir ? "/rm" : "");
printf("# (use \"git checkout -- <file>...\" to discard changes in working directory)\n");
printf("#\n");
header = 1;
}
printf("#\t%s %s\n", wstatus, status_list[i].path);
}
if (header) {
changed_in_workdir = 1;
printf("#\n");
}
header = 0;
for (int i = 0; i < status_list_index; i++) {
if (status_list[i].status == GIT_STATUS_WT_NEW) {
if (!header) {
printf("# Untracked files:\n");
printf("# (use \"git add <file>...\" to include in what will be committed)\n");
printf("#\n");
header = 1;
}
printf("#\t%s\n", status_list[i].path);
}
}
header = 0;
for (int i = 0; i < status_list_index; i++) {
if (status_list[i].status == GIT_STATUS_IGNORED) {
if (!header) {
printf("# Ignored files:\n");
printf("# (use \"git add -f <file>...\" to include in what will be committed)\n");
printf("#\n");
header = 1;
}
printf("#\t%s\n", status_list[i].path);
}
}
if (!changes_in_index && changed_in_workdir) printf("no changes added to commit (use \"git add\" and/or \"git commit -a\")\n");
if (status_list) free(status_list);
status_list = NULL;
status_list_index = 0;
return 0;
}
then it works with
0> status
## master
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# renamed: b/j
# renamed: b/l
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# j/j
# j/l
# test_Copy.
no changes added to commit (use "git add" and/or "git commit -a")
0>
however i cannot detect renames
and the source code seems to do
https://github.com/libgit2/libgit2/blob/c43658f62ee268a0b5ee13f5764544882245063c/src/status.c#L398
const git_status_entry *git_status_byindex(git_status_list *status, size_t i)
{
assert(status);
return git_vector_get(&status->paired, i);
}
>
https://github.com/libgit2/libgit2/blob/45dc219f656ff05c06246eec2b36e6805cdf8012/src/vector.h#L60
GIT_INLINE(void *) git_vector_get(const git_vector *v, size_t position)
{
return (position < v->length) ? v->contents[position] : NULL;
}
And i cant seem to find the structures specified, specifically git_diff_delta, new_file, and old_file, but i did find this
typedef struct {
git_status_t status;
git_diff_delta *head_to_index;
git_diff_delta *index_to_workdir;
} git_status_entry;
and from help via C auto completiion (may be incomplete) i managed to build up a full structure of what it should look like:
s // git_status_entry *
s->head_to_index // git_diff_delta *
s->head_to_index->flags // uint32_t
s->head_to_index->new_file // git_diff_file
s->head_to_index->new_file.flags // uint32_t
s->head_to_index->new_file.id // git_oid
s->head_to_index->new_file.id_abbrev // uint16_t
s->head_to_index->new_file.mode // uint16_t
s->head_to_index->new_file.path // const char *
s->head_to_index->new_file.size // git_off_t
s->head_to_index->nfiles // uint16_t
s->head_to_index->old_file // git_diff_file
s->head_to_index->old_file.flags // uint32_t
s->head_to_index->old_file.id // git_oid
s->head_to_index->old_file.id_abbrev // uint16_t
s->head_to_index->old_file.mode // uint16_t
s->head_to_index->old_file.path // const char *
s->head_to_index->old_file.size // git_off_t
s->head_to_index->similarity // uint16_t
s->head_to_index->status // git_delta_t
s->index_to_workdir // git_diff_delta *
s->index_to_workdir->flags // uint32_t
s->index_to_workdir->new_file // git_diff_file
s->index_to_workdir->new_file.flags // uint32_t
s->index_to_workdir->new_file.id // git_oid
s->index_to_workdir->new_file.id_abbrev // uint16_t
s->index_to_workdir->new_file.mode // uint16_t
s->index_to_workdir->new_file.path // const char *
s->index_to_workdir->new_file.size // git_off_t
s->index_to_workdir->nfiles // uint16_t
s->index_to_workdir->old_file // git_diff_file
s->index_to_workdir->old_file.flags // uint32_t
s->index_to_workdir->old_file.id // git_oid
s->index_to_workdir->old_file.id_abbrev // uint16_t
s->index_to_workdir->old_file.mode // uint16_t
s->index_to_workdir->old_file.path // const char *
s->index_to_workdir->old_file.size // git_off_t
s->index_to_workdir->similarity // uint16_t
s->index_to_workdir->status // git_delta_t
s->status // git_status_t
output:
Enter command line arguments.
> status a/0
ret = 0 (none)
ret = 0 (none)
ret = 0 (the global/xdg file 'ignore' doesn't exist: No such file or directory)
s is not NULL
s->status is not NULL
s->head_to_index is not NULL
s->head_to_index->old_file is not NULL
s->head_to_index->old_file.path is NULL
s->head_to_index->old_file.path = (null)
s->head_to_index->new_file is not NULL
s->head_to_index->new_file.path is NULL
s->head_to_index->new_file.path = (null)
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
old_path = (null)
new_path = (null)
# new file: (null)
s is not NULL
s->status is not NULL
s->head_to_index is not NULL
s->head_to_index->old_file is not NULL
s->head_to_index->old_file.path is NULL
s->head_to_index->old_file.path = (null)
s->head_to_index->new_file is not NULL
s->head_to_index->new_file.path is NULL
s->head_to_index->new_file.path = (null)
old_path = (null)
new_path = (null)
# new file: (null)
s is not NULL
s->status is not NULL
s->head_to_index is not NULL
s->head_to_index->old_file is not NULL
s->head_to_index->old_file.path is NULL
s->head_to_index->old_file.path = (null)
s->head_to_index->new_file is not NULL
s->head_to_index->new_file.path is NULL
s->head_to_index->new_file.path = (null)
old_path = (null)
new_path = (null)
# new file: (null)
Status.c
#include <git2.h>
#include <stdio.h>
#include <unistd.h>
#define ps(x) printf("%s = %s\n", #x, x);
#define gitprefix(x) git_libgit_version_2_api_##x
#define giterr(x) { printf("%s = %d (%s)\n", #x, x, giterr_last()?giterr_last()->message:"none"); }
#define giterror(...) { \
printf("error: " __VA_ARGS__); \
printf(" (%s)", giterr_last()?giterr_last()->message:"none"); \
printf("\n"); \
return -2; \
}
#define giterrorn(...) { \
printf("error: " __VA_ARGS__); \
printf(" (%s)", giterr_last()?giterr_last()->message:"none"); \
printf("\n"); \
return NULL; \
}
#define gitret(x) { \
int ret = x ; \
if (ret) return ret; \
}
#define gitisnull(x) { \
if (x == NULL) printf("%s is NULL\n", #x); \
else printf("%s is not NULL\n", #x); \
}
int main(int argc, char *argv[])
{
git_repository *repo = NULL;
git_status_list *status;
git_status_options statusopt = { GIT_STATUS_OPTIONS_INIT };
git_libgit2_init();
statusopt.show = GIT_STATUS_SHOW_INDEX_AND_WORKDIR;
statusopt.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED |
GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX |
GIT_STATUS_OPT_SORT_CASE_SENSITIVELY;
/**
* Try to open the repository at the given path (or at the current
* directory if none was given).
*/
int ret = git_repository_open(&repo, argv[1]);
giterr(ret)
if (ret < 0) {
git_libgit2_shutdown();
giterror("Could not open repository %s", argv[1]);
}
ret = git_repository_head_unborn(repo);
giterr(ret)
if (ret == 1) {
git_libgit2_shutdown();
giterror("Cannot report status on bare repository %s", argv[1]);
}
/**
* Run status on the repository
*
* We use `git_status_list_new()` to generate a list of status
* information which lets us iterate over it at our
* convenience and extract the data we want to show out of
* each entry.
*
* You can use `git_status_foreach()` or
* `git_status_foreach_ext()` if you'd prefer to execute a
* callback for each entry. The latter gives you more control
* about what results are presented.
*/
ret = git_status_list_new(&status, repo, &statusopt);
giterr(ret)
if (ret < 0) {
git_libgit2_shutdown();
giterror("Could not get status of repository %s", argv[1]);
}
size_t i, maxi = git_status_list_entrycount(status);
const git_status_entry *s;
int header = 0, changes_in_index = 0;
int changed_in_workdir = 0, rm_in_workdir = 0;
const char *old_path, *new_path;
/** Print index changes. */
for (i = 0; i < maxi; ++i) {
char *istatus = NULL;
s = git_status_byindex(status, i);
gitisnull(s)
if (s!=NULL) {
gitisnull(s->status)
gitisnull(s->head_to_index)
if (s->head_to_index!=NULL) {
gitisnull(s->head_to_index->old_file)
gitisnull(s->head_to_index->old_file.path)
ps(s->head_to_index->old_file.path)
gitisnull(s->head_to_index->new_file)
gitisnull(s->head_to_index->new_file.path)
ps(s->head_to_index->new_file.path)
}
}
if (s->status == GIT_STATUS_CURRENT)
continue;
if (s->status & GIT_STATUS_WT_DELETED)
rm_in_workdir = 1;
if (s->status & GIT_STATUS_INDEX_NEW)
istatus = "new file: ";
if (s->status & GIT_STATUS_INDEX_MODIFIED)
istatus = "modified: ";
if (s->status & GIT_STATUS_INDEX_DELETED)
istatus = "deleted: ";
if (s->status & GIT_STATUS_INDEX_RENAMED)
istatus = "renamed: ";
if (s->status & GIT_STATUS_INDEX_TYPECHANGE)
istatus = "typechange:";
if (istatus == NULL)
continue;
if (!header) {
printf("# Changes to be committed:\n");
printf("# (use \"git reset HEAD <file>...\" to unstage)\n");
printf("#\n");
header = 1;
}
old_path = s->head_to_index->old_file.path;
new_path = s->head_to_index->new_file.path;
ps(old_path);
ps(new_path);
if (old_path && new_path && strcmp(old_path, new_path))
printf("#\t%s %s -> %s\n", istatus, old_path, new_path);
else
printf("#\t%s %s\n", istatus, old_path ? old_path : new_path);
}
git_status_list_free(status);
git_repository_free(repo);
git_libgit2_shutdown();
return 0;
}

Initializing a number and a char to a 2D array

I have to implement a deck of cards with a number and a letter. This is what I have done so far:
string deck [6][6] =
{
{1A, 1B, 1C, 1D},
{2A, 2B, 2C, 2D},
{3A, 3B, 3C, 3D},
{4A, 4B, 4C, 4D},
{ , , , };
};
int main ()
{
cout << deck[0][0] << endl;
}
I get an error:
invalid suffix 'A' on integer constant
You are getting this error because you need to wrap your strings in double quotations. If you want to use a static initialization/declaration, it should look something like this:
std::string deck[4][4] = {
{ "1A", "1B", "1C", "1D"},
{ "2A", "2B", "2C", "2D"},
{ "3A", "3B", "3C", "3D"},
{ "4A", "4B", "4C", "4D"}
};
You can display the entire contents of the deck by using two nested for loops:
for (int r=0; r < 4; ++r) {
for (int c=0; c < 4; ++c) {
if (c > 0) {
cout << " ";
}
cout << deck[r][c];
}
cout << "\n";
}

Resources