Trying to use the Yajl example code, don't know how to give the input to the program - c

I've compiled the code provided by YAJL library in C. Don't know why the compiled program not parsing my file or is my file format is wrong?
I'm quite new in parsing JSON file.
This is where C code example located at https://lloyd.github.io/yajl/
Don't know do I need to paste the entire code or link is fine?
Myfile.
cat input_file.json
helllooooooooooo
When I ran the program ./a.out json_reformat input_file.json, it doesn't do anything. ./a.out -m json_reformat input_file.json this also didnt work.
I tried with -u and -m option nothing worked.
It print out the usage in STDOUT like this.
usage: json_reformat [options]
-m minimize json rather than beautify (default)
-u allow invalid UTF8 inside strings during parsing

Related

How to compare ./a.out and a .txt file with diff?

So I have a c program, e.g. test1.c, and I wanted to compare it to a text file called test1expectedoutput.txt.
How would I do this?
I compiled the c file (written in nano) by doing gcc test1.c, but how do I compare it?
Comparing the .c file to the .txt obviously does not work as it just prints both of them out in full randomly, but if I try compare in that file directory with diff using:
diff ./a.out test1expectedoutput.txt
To which I get the message:
Binary files ./a.out and test1expectedoutput.txt differ
So I'm not 100% sure how to compare them and know what the differences are? To put it simply, say the program in test1.c just says:
printf("Hello\n");
and the test1expectedoutput.txt just reads (with cat):
Hello
How could I compare these after compiling?
I understand you mean to compare the output of your c program with the txt file.
In that case you can first store the output to another file by redirecting standard output to a .txt file:
./a.out > output.txt
diff output.txt test1expectedoutput.txt
diff command also supports a - notation for filename, that tells it to read from standard input. So you can do it without storing it into another file by simply redirecting standard output into diff command's standard input, with a single command:
./a.out | diff test1expectedoutput.txt -
You can try to dump the contents of ./a.out into a file.
Try this: ./a.out > actualoutput.txt
Then run diff actualoutput.txt test1expectedoutput.txt
Both Sanat and Mythos are correct.
What I ended up doing was doing the ./a.out > output.txt then using diff, the diff (if the file is correct) doesn't output something so what I like to use is diff -s text1.txt text2.txt which will then, if identical to double check, output that they are identical.
The problem is, it was not identical and it wouldn't tell me why, no matter what I tried and colours, so I manually nano'ed both text files, and went in, and just after messing around found that one randomly had an extra space, normally it would colour the differences but it doesn't colour spaces... so that was fun.

using a shared library : custom myfopen(), myfrwrite()

Hello I have created a shared library named logger.so. This library is my custom fopen() and fwrite(). It collects some data and produce a file with these data.
Now I am writing a bash script and I want to use this library as well. Producing a txt file I would be able to see the extra file that produce my custom fopen(). So when I use the command fopen() in a c file this extra file is produced.
My Question is which commands are using fopen() and fwrite() functions in bash?
I have already preloaded my shared library but It doesn't work. Maybe these commands don't use fopen(),fwrite()
export LD_PRELOAD=./logger.so
read -p 'Enter the number of your files to create: [ENTER]: ' file_number
for ((i=1; i<=file_number; i++))
do
echo file_"$i" > "file_${i}"
done
This may require some trial and error. I see two ways to do this. One is to run potential commands that deal with files in bash and see if when traced they call fopen:
strace bash -c "read a < /dev/null"`
or
strace bash -c "read a < /dev/null"` 2&>1 | fgrep fopen
This shows that that read uses open, not fopen.
Another way is to grep through the source code of bash as #oguz suggested. When I did this I found several places where fopen is called, but I did not investigate further:
curl https://mirrors.tripadvisor.com/gnu/bash/bash-5.1-rc3.tar.gz|tar -z -x --to-stdout --wildcards \*.c | fgrep fopen
You'll want to unarchive the whole package and search through the .c files one by one, e.g.:
curl https://mirrors.tripadvisor.com/gnu/bash/bash-5.1-rc3.tar.gz|tar -z -v -x --wildcards \*.c
You can also FTP the file or save it via a browser and do the tar standalone if you don't have curl (wget will also work).
Hopefully you can trace the relevant commands but it might not be easy.
Not necessarily every program uses C standard library stdio functions fopen and fwrite.
But every program uses open and write syscalls to open and write files, which you can interpose / monkey-patch.
Modern programs that use io_uring require a different method of interposing.

Can't read file generated by bash line

I have written a C code where the bash script lines are used inside this C code, and this is how I wrote it:
printf("wc -l < smallerthan > number_lines\n");
if( (fr=fopen(fname_rcut,"r"))==NULL ) { printf("error in rcut file: %s\n",fname_rcut); exit(1); }
I need to read the file "number_lines" which is generated from "smallerthan" file, the problem is when I source the C code to run automatically like:
$gcc myC_code.c -lm
$./a.out > run.sh
$source run.sh
Then if I view the run.sh
& vi run.sh
I get this inside run.sh:
wc -l < smallerthan > number_lines
ls
error in rcut file: /home/number_lines
which mean the code upto this point didn't find my "number_lines" file yet since the number_lines file is yet to appear, but if I copy the line and run it separately, instead of "automatically", then it works because the file is there now.
My question is, how to make my code run automatically and my C code to read the file which is generated by bash line or how to generate the file and read it properly?
Any idea please because I'm really new to programming and I have to use bash inside C for my work.
Note: the above is only small part of my C code but I used several bash lines inside my C code.
There are a number of observations in your code. I assume that char *fname_rcut indeed points to "/home/number_lines".
First observation: if you write commands to a file, they will not be executed.So the file number_lines is created only after you run run.sh. Therefore, the file will not exist during the execution of your C program. You might look into int system(const char *command) (man 3 system).
Second observation: /home/number_lines is probably not the correct filename. It would probably be /home/your_name/number_lines; try a pwd to see what the exact directory name is.
Third observation: Why do you want to source run.sh? Source executes the file in the current shell. There is usually no need for that.
I have solved it :
what we need actually is using system(command) after each shell command
for example :
printf("wc -l < smallerthan > number_lines\n");
will be after solving :
sprintf(command1,"wc -l < smallerthan > number_lines\n");
system(command1);

C input and output redirection error?

I am encountering this weird message at the moment with my file.
I have a very basic C file that reads from a file and outputs upon request.
I am running the following command in Linux:
filename <filenametest.txt >filenameoutput
and it brings the following message:
filename: command not found
Any idea why it's not working?
Really frustrating.
Assuming that filename is the name of the executable generated on compiling your C code, maybe you should try using
./filename < filename.txt > filenameoutput.
Since filename is not in the search path by default.

Cannot execute binary file when calling Java from Bash

I'm using Ubuntu 14.04.
There are 4 files involved: 'compile.sh', 'execute.sh', 'work.c', 'tester.sh'.
In 'compile.sh', it compiles the 'work.c' file and outputs an executable file called 'execute.sh'. In my own testing process, I do ./compile.sh, then ./execute.sh to run my C program. This works.
Now, the 'tester.sh' is a script that calls a Java program and this Java program does the same thing. It will run my 'compile.sh' first and then excute 'execute.sh'. It checks the correctness of my program outputs.
The problem is that when I do ./tester.sh, I get the error below
Reading first line from program...
./execute.sh: ./execute.sh: cannot execute binary file
First line of execution should match: Created \d heaps of sizes .+
Failed to execute (error executing ./execute.sh)
You can ignore the third line "First line of execution...."; it tries to check whether my output matches exactly with the tester. Since the binary file cannot be executed, then the first line does not match for sure.
So why does it say "cannot execute binary file"?
Content in compile.sh
#!/bin/bash
gcc -Wall work.c -o execute.sh
Content in tester.sh
#!/bin/bash
java -cp bin/tester.jar edu.ssu.cs153.work1.Tester
(bin/tester.jar is in my local machine; we can assume there is nothing wrong with the tester script.)
Diagnosis
It is weird, but not disallowed, to name an executable with the .sh extension. Your problem is that the Java code is trying to run it as a shell script (e.g. bash ./execute.sh), and it isn't a shell script so it fails. You need to change the Java to run the .sh file as an executable instead of as a shell script. Or, better (since you probably can't fix the Java), fix the compilation so that it produces an executable with a different name (e.g. work), and have execute.sh execute ./work.
File execute.sh is just an output file from compiling the work.c file. It is just like a.out by default from gcc. I can run ./execute.sh from the terminal and see all the correct outputs.
The trouble is, when you run it, you do ./execute.sh and the shell executes directly. The Java is running it as bash ./execute.sh, and that generates the error. Try it at the command line.
Prescription
On the face of it, you need to change compile.sh, perhaps like this (generating a program work from work.c):
#!/bin/bash
gcc -o work -Wall work.c
And you write a shell script called executable.sh that reads:
#!/bin/bash
exec ./work "$#"
This script runs your program with any command line arguments it is given. The exec means the shell replaces itself with your program; there are minor advantages to doing it that way, though it'll be OK if you omit the exec from the script.

Resources