the program is still very empty and "naked" because im just trying to get the logic out of the way before I actually start making functions. For some reason, whatever my argv[1] is, it always prints "The help message". What am I missing? I have a bad feeling about that for statement, but I dont know whats wrong with it.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void help()
{
printf("The help message\n");
exit(1);
}
void a()
{
printf("The a screen\n");
exit(1);
}
int main(int argc, char *argv[])
{
char recognised_commands[3] = {help(), a()};
int i;
if (argc != 2)
{
fprintf(stderr, "usage of sake: \"sake [option(s)]\"\nFor a full listing of all available commands type \"-help\" or \"--help\"\n\n");
exit(1);
}
for (i = recognised_commands[0]; i != recognised_commands; i++)
{
printf(argv[1]);
}
}
Edit 1: djikay: Fixed the -1 to 0,
Ricky: How do I correct the help() and the a() to only call the one the user inputs after the program name (EX: sake -a)? I also fixed the exit(0). Thanks
The line:
char recognised_commands[3] = {help(), a()};
causes both help and a to be called. help is called first, and it prints out the help message & exits the program.
char recognised_commands[3] = {help(), a()};
This line is definitely your issue. help() and a() are both being called, thus exiting your program.
Why are you trying to assign those function return values there? Both of the functions are void in return type, meaning they won't return anything anyways.
On a side note, calling exit() with 0 as the argument means your program exited without errors. I'd exit with 1 if it's because of an error (or even better, EXIT_SUCCESS and EXIT_FAILURE, respectively).
Related
I have a program that works like this
program1.exe program2.exe
I need to make it run like this
%USERPROFILE%\program1.exe program2.exe
How can that be done on C?
From what I could see, you're using Microsoft Windows.
There are (at least) two answers to your question, a simple one, and one tied to the Windows operating system interface, usually called Win32 API.
Let's use the simple one. If your prefer to have more control about the execution of the 2nd program, please comment.
#include <stdio.h> /* printf() */
#include <stdlib.h> /* system() */
int main(int argc, char* const* argv)
{
int rv;
if (argc < 2) {
printf("Please inform the name of the program to execute.\n");
return 1;
}
rv = system(argv[1]);
printf("Program execution returned %d\n", rv);
return 0;
}
Here is my code for user/sleep.c:
#include "kernel/types.h"
#include "user/user.h"
int
main(int argc, char *argv[])
{
if (argc < 2)
{
printf("You have forgotten to pass an argument.");
exit(1);
}
int arg = atoi(argv[1]);
sleep(arg);
exit(0);
// return 0;
}
All is fine but with the return 0 instead of exit(0), I get the following error:
usertrap(): unexpected scause 0x000000000000000d pid=4
sepc=0x00000000000000f6 stval=0x0000000000003008
Why is that?
It's because xv6 is not standard on this point:
see https://tnallen.people.clemson.edu/2019/03/04/intro-to-xv6.html
Returning after main is a special case that is not supported in XV6, so just remember to always exit() at the end of main instead of return. Otherwise, you will get a “trap 14,” which in this case is XV6-speak for “Segmentation Fault.” Finally, notice that our headers are different. There is no #include <stdio.h> as you might be used to. Again, this is because the standard library is different. Check out these headers to see what kind of user utilities you have available.
So why did we need exit() in xv6?
Because, when building a program with gcc for linux for instance, the tool chain add the required exit call: see https://en.wikipedia.org/wiki/Crt0
In short, on linux, your program don't start at main but at start:
void start(void) {
/* get argc, argv, env) */
int r = main(argc, argv, envp); /* << start calls the actual main */
exit(r);
}
On xv6, on contrary, the real starting point is main when OS try to return from main, it has no address to pop what cause a segfault
So i am trying to get this program to simply exit but i can seem to get it to work.
i tried a lot of things. one thing i found odd as well is if i made x = 0 in the while loop it would immediately exit the program so i had to make it x !=0. i dont understand what that is so if you can answer that as well that would be nice.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char a[256];
int x = 0;
while (x != 0) {
int y = strcmp(fgets(a, 256, stdin), "exit");
if (y==0) {
exit(0);
}
else {
printf("Line read:%s\n",a);
}
}
return 0;
}
so it should output right now something like this(i am also running this in a linux terminal):
//input://
hello
//output://
Line read: hello
//(program stays open for more inputs)//
//input//
exit
//(the program now closes in the terminal and you return to directory)//
The keyboard input contains a new line at the end. Change "exit" to "exit\n" in call to strcmp.
Hello i got a problem im trying to solve problem and learn how the learning from files works .I did this code by tutorial and when i execute instead of learning my file and write on console something like 1 4 6 5 1 etc.. its just spam only 0 0 0 0 0 0 0 and then repeat
If you would say me where is the problem it will be good thanks for ur time :)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define UNUSED(__ARG__) ((void)__ARG__)
int main(int argc, char** argv)
{
UNUSED(argc);
UNUSED(argv);
int i = 0;
FILE* x =fopen("cisla.txt","r");
fscanf(x,"%d",&i);
while (!feof (x))
{
printf("%d",i);
fscanf(x,"%d",&i);
}
fclose(x);
return 0;
}
Whatever tutorial this is, throw it out.
First, you need to check whether your file operations succeeded, otherwise the program will blindly continue along. Likely the fopen failed. It returns NULL on failure so you can check for that and get an error message with perror.
FILE *x = fopen("cisla.txt","r");
if( x == NULL ) {
perror("Could not open the file");
exit(1);
}
Then, as others have mentioned, you don't check for end of file. Instead do the IO operation and check whether it succeeded or failed. In this case, fscanf returns the number of matched items which should be 1.
while ( fscanf(x, "%d", &i) == 1 ) {
printf("%d",i);
}
Note that the scanf family is fraught with gotchas. But you'll get to them later.
Finally, that UNUSED stuff is very clever and totally unnecessary. Just declare main with no arguments. This is perfectly valid.
int main() {
I have the following c code. I want to display my file with less by calling execv()
however the following seems never work. The program terminates and noting pop out.
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int main(void){
int pid;
if(pid=fork()>0){
//read in from stdin and pass to pipe
}else if(pid==0){
//read from pipe
//write to out.txt
//everything up to here works fine
char* para[]={"less","/Desktop/out.txt"};
execv("/bin/less",para);
}
return 0;
}
(The original code contained execv("bin/less", para);.) Unless the current directory is the root directory, /, or unless there is a program less in the subdirectory ./bin/less, then one of your problems is that you have a probable typo in the name of the executable. That assumes the program is /bin/less and not /usr/bin/less. You might even use execvp() to do a PATH-based search for the program.
There's an additional problem: you need to include a null pointer to mark the end of the argument list.
Finally, you can print an error message after the execv() returns. The mere fact that it returns tells you it failed.
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
int main(void)
{
int pid;
if ((pid = fork()) != 0)
{
// read in from stdin and pass to pipe
// Need to test for fork() error here too
}
else
{
// read from pipe
// write to out.txt
// everything up to here works fine
char *para[] = { "/bin/less", "Desktop/out.txt", 0 };
execv(para[0], para);
fprintf(stderr, "Failed to execute %s\n", para[0]);
exit(1);
}
return 0;
}
Or:
char *para[] = { "less", "Desktop/out.txt", 0 };
execvp(para[0], para);
fprintf(stderr, "Failed to execute %s\n", para[0]);
The remarks in the code about pipes are puzzling since there is no sign of pipes other than in the comments. As it stands, less will read the file it is told to read. Note that less will not paginate its output if the output is not going to a terminal. Since we can see no I/O redirection, we have to assume, then, that less will ignore anything the program tries to write to it, and will not send any data back to the program.
char* para[]={"less","/Desktop/out.txt"};
execv("/bin/less",para);
How does execv know when to stop reading parameters?
I think if you'd put code in there to handle execv() returning an error you'd have found this. You're also not testing for errors from fork().