I'm trying to make my code use the command dot -Tpng -o file.png file.dot but it doesn't seem to work with system("dot -Tpng -o file.png file.dot").
It returns 0 but no files are created.
I also tried to do execl("dot","-Tpng -o file.png file.dot",NULL)but I don't think this is the correct syntax or way to do it.
Is there a way to make my C program (on Linux) execute the command line ?
Here is my code :
FILE *f = fopen("file.dot","w");
fprintf(f, "digraph graphname {\n\ta->b [label = 1]\n}");
system("dot -Tpng -o file.png file.dot");
fclose(f);
return 0;
EDIT :
I moved the fclose(f)before the system() call and it worked.
I guess it had something to do with f not being closed.
Related
I'm working on a homework problem that reads characters from an input.txt file and outputs the first word read into an output.txt, the second into an error.txt, then the third to output.txt again, and so on until it reaches the end of the input.txt file.
I should note this is all done using Ubuntu 18.04
I was given a custom Makefile and had to edit a C program called split.c which would take the input.txt through the stdin and output to stdout/stderr. I can write my C program and have it listed below, however I can't test if it's correct because I do not understand how to run make, how to set up my files correctly and if my C program is correctly reading and outputing as it should.
I have tried running the 'make' command in the terminal but I receive:
make: No targets specified and no makefile found. Stop.
I have looked at countless articles on Linux, making 'make files', etc. but I don't know what I'm being asked or what to do so I am at a stand still. Guidance is greatly appreciated!
The custom makefile looks like this and is called Makefile.dat:
CC=gcc
CFLAGS=-Wall
EXEC=split
SRC=$(EXEC).c
TEXT_DIR=test
TEST_INPUT=$(TEST_DIR)/input.txt
OUT=$(TEST_DIR)/stdout.txt
ERR=$(TEST_DIR)/stderr.txt
EXP_OUT=$(TEST_DIR)/output.txt
EXP_ERR=$(TEST_DIR)/error.txt
TEST_REQS=$(TEST_INPUT) $(EXP_OUT) $(EXP_ERR)
DIFF=diff -bBqa
all: $(EXEC)
$(EXEC): $(SRC)
$(CC) $(CFLAGS) $(SRC) -o $(EXEC)
.PHONY: test
test: $(TEST_REQS) $(EXEC)
./$(EXEC) < $(TEST_INPUT) > $(OUT) 2> $(ERR)
$(DIFF) $(EXP_OUT) $(OUT)
$(DIFF) $(EXP_ERR) $(ERR)
echo TEST PASSED!
.PHONY: clean
clean:
$(RM) $(EXEC)
And my C program looks like this and is called split.c:
#include <stdio.h>
int main(){
int input;
// keep getting characters until end-of-file
while((input = fgetc(stdin)) != EOF){
// prints to stdout
printf(stdout, "%d", input);
if(input = " ")
printf("\n"); // encounters whitespace so print new line
// prints to stderr
printf(stderr, "%d", input);
if(input = " ")
printf("\n"); // encounters whitespace so print new line
}
return 0;
}
With the idea being that it takes the input file, then it'll print each letter into it's respective file, and if it encounters a space it'll print a new line before adding the next character into the other file.
For example:
input.txt has the text:
"How do I do this stuff?"
output.txt will have:
How
I
this
error.txt will have:
do
do
stuff?
I fully expect that my C program is missing code. My thinking when writing the program was, print to stdout, then if whitespace is encounterd, print a new line, then begin printing to stderr, and repeat until EOF is reached.
Either rename Makefile.dat to Makefile, like this:
mv Makefile.dat Makefile
make
or run make with the -f option and an argument of your Makefile:
make -f Makefile.dat
Make sure all your files (split.c, test/input.txt, Makefile) are present in the same directory as the Makefile, otherwise this won't work.
Note some issues with your C code:
if(input = " ")
is wrong. First of all, it's assigning a string with a space in it " " (which is a pointer to char) to input, instead of checking if input is a space character.
To fix the issue, use this:
if(input == ' ')
in both cases.
For example I have a C program with executable target prog and a file file.txt
Is there a way in my C program to make stdin to read and accept the file.txt without its extension. Currently my code to read the stdin is..
while (scanf("%d ", &n) != EOF)
For this I would have to do ./prog < file.txt
But I want to do this ./prog < file
But I want to do this ./prog < file
No, that won't work. You'll just have to be explicit and use:
./prog < file.txt
Change your program so that instead of redirecting using the OS, you take the file as a command line argument and open+read it yourself.
That way you can do whatever string manipulation on the file name you think is necessary.
I'm fairly new to C and am completely new to using the command prompt and GCC to compile and run my programs. I'm struggling to find the right words to ask this question properly so please bear with me, I am doing my best.
I need to use GCC to compile and run this C program but I'm getting an error that I do not understand. In this example program, I was told to use these lines to compile and run the code:
$ gcc -Wall -std=c99 -o anagrams anagrams.c
$ ./anagrams dictionary1.txt output1.txt
So that is what I did. GCC does compile the program file, so the first line does not give me any error. But GCC does not like the second line, as shown below:
C:\Users\...\Example>gcc -Wall -std=c99 -o anagrams anagrams.c
C:\Users\...\Example>./anagrams dictionary1.txt output1.txt
'.' is not recognized as an internal or external command,
operable program or batch file.
Everywhere I look, it says to use "./filename" to run the program after compiling so I don't understand why it is not working for me. Any help or advice would be really appreciated.
Also, here is the main() of the program to show why those two .txt files are needed:
int main(int argc, char *argv[])
{
AryElement *ary;
int aryLen;
if (argc != 3) {
printf("Wrong number of arguments to program.\n");
printf("Usage: ./anagrams infile outfile\n");
exit(EXIT_FAILURE);
}
char *inFile = argv[1];
char *outFile = argv[2];
ary = buildAnagramArray(inFile,&aryLen);
printAnagramArray(outFile,ary,aryLen);
freeAnagramArray(ary,aryLen);
return EXIT_SUCCESS;
}
'.' is not recognized as an internal or external command
This is not a GCC error. The error is issued by the shell when trying to run a command.
On Windows this
./anagrams dictionary1.txt output1.txt
should be
.\anagrams dictionary1.txt output1.txt
as on Windows the path delimiter is \ as opposedto IX'ish systems where it is /.
On both systems . denotes the current directory.
The reason for the crash you mention in your comment is not obvious from the minimal sources you show. Also this is a different question.
I have this code:
#include <stdio.h>
int main ( int argc, char *argv[] )
{
FILE *file;
int x;
if ( argc != 2 )
printf( "Use: %s file name", argv[0] );
else {
if ((file=fopen( argv[1], "r" ))== 0 )
printf( “Couldn't open the file.\n" );
else {
while (( x = fgetc( file ) ) != EOF) printf( "%c", x );
fclose( file );
}
}
return 0;
}
Now, having this code, how do I execute a file from terminal (that is on the pic as well as my configuration of NetBeans). http://i.stack.imgur.com/6WRh3.png
First, better replace your statement (in your program above)
printf( “Couldn't open the file.\n" );
with
perror(argv[1]);
then, simply compile your program in your terminal, e.g. type there a shell command similar to
gcc -Wall -g mysource.c -o myprog
(Read more about invoking GCC: the -Wall option asks for nearly all warnings and is very useful -so never miss it-; you could even add -Wextra to get even more warnings; the -g is asking for DWARF debugging information in the ELF executable and enables you to use later gdb)
assuming your source code is in a file named mysource.c in the current working directory (use pwd command to query that current directory, ls -al to list it, and cd builtin command to change it)
at last, run your program as
./myprog sometestfile.txt
You might want to use the debugger. Read first about GDB, and try perhaps
gdb ./myprog
(I am guessing you are on Linux or some other POSIX compliant operating system, and using GCC compiler)
Read more about perror(3), command line interface, shells, globbing, glob(7), PATH variable
Later, you'll want to have some bigger program of yours made in several translation units, having some common header file (to be #included in all of them). Then you'll use a builder like GNU make. You could use a good editor like emacs, some version control like git, etc...
(you might realize that NetBeans is not very useful, because you can have even better developing comfort with your own collection of tools; having the freedom to choose your tools is worthwhile!)
PS. Perhaps replace printf( "%c", x ); with the shorter and more efficient putchar(x); ...
I have two (Ubuntu Linux) bash scripts which take input arguments. They need to be run simultaneously. I tried execve with arguments e.g.
char *argv[10] = { "/mnt/hgfs/F/working/script.sh", "file1", "file2", NULL };
execve(argv[0], argv, NULL)
but the bash script can't seem to find any arguments at e.g. $0, $1, $2.
printf "gcc -c ./%s.c -o ./%s.o\n" $1 $1;
gcc -c ./$1.c -o ./$1.o -g
exit 0;
output is gcc -c ./main.c -o ./main.o
and then a lot of errors like /usr/include/libio.h:53:21: error: stdarg.h: No such file or directory
What's missing?
Does your script start with the hashbang line? I think that's a must, something like:
#!/bin/bash
For example, see the following C program:
#include <stdio.h>
#include <unistd.h>
char *argv[10] = { "./qq.sh", "file1", NULL };
int main (void) {
int rc = execve (argv[0], argv, NULL);
printf ("rc = %d\n", rc);
return 0;
}
When this is compiled and run with the following qq.sh file, it outputs rc = -1:
echo $1
when you change the file to:
#!/bin/bash
echo $1
it outputs:
file1
as expected.
The other thing you need to watch out for is with using these VMWare shared folders, evidenced by /mnt/hgfs. If the file was created with a Windows-type editor, it may have the "DOS" line endings of carriage-return/line-feed - that may well be causing problems with the execution of the scripts.
You can check for this by running:
od -xcb /mnt/hgfs/F/working/script.sh
and seeing if any \r characters appear.
For example, if I use the shell script with the hashbang line in it (but appen a carriage return to the line), I also get the rc = -1 output, meaning it couldn't find the shell.
And, now, based on your edits, your script has no trouble interpreting the arguments at all. The fact that it outputs:
gcc -c ./main.c -o ./main.o
is proof positive of this since it's seeing $1 as main.
The problem you actually have is that the compiler is working but it cannot find strdarg.h included from your libio.h file - this has nothing to do with whether bash can see those arguments.
My suggestion is to try and compile it manually with that command and see if you get the same errors. If so, it's a problem with what you're trying to compile rather than a bash or exec issue.
If it does compile okay, it may be because of the destruction of the environment variables in your execve call.