I want to get my program to use the command line arguments with getchar to then encode a message. My problem is that getchar is only paying attention to what I type after the program has executed. How can I make it read the command line arguments instead?
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int pin, charin, charout;
// this verifies that a key was given at for the first argument
if (atoi(argv[1]) == 0){
printf("ERROR, no key was found..");
return 0;
}
else {
srand(atoi(argv[1]));
pin = rand() % 27;
}
while( (charin=getchar()) != EOF){
charout = charin + pin;
putchar(charout);
}
}
getchar to read from command line arguments
That's the problem - if you are getting command line arguments you don't do it with getchar: use argc to get the count of arguments and argv[] to get particular arguments.
I don't think you need getchar in this program at all.
These are also good suggestions, please take a look at the parts about argument handling:
encode program using getchar from command line argument and putchar to send to decode
I think you are trying to write a program that behaves like this:
program pin message
and then it will use some sort of Caesar cipher on message to obfuscate the output. Is that right?
If so, then you need to also get argv[2] and use printf to output the results.
Related
For e.g i have the following program in windows.
#include <stdio.h>
int main(int argc, char *argv[]) {
char *input = argv[1];
printf("your input: %s", input);
return 0;
}
When i run a cmd shell and invoke
C:\>whoami | main.exe
i get as output
your input: (null)
The first argument argv[0] (the filename itself) is passed correct. How to receive the output of whoami as input to my program?
Edit: Since people mostly ask for code if you ask a question, i will also provide code in my answer. Just to be fair. The solution i use (thanks to Gerardo Zinno) is to read from stdin - so i use scanf.
char input[1024] = {0};
read(STDIN_FILENO, input, 1024);
input[strcspn(input, "\n")] = '\0';
printf("you wrote: %s", input);
return 0;
You have to read from the stdin just like if the input was coming from a user typing in the terminal. The pipe will send (link) the stdout of whoami to the stdin of your program.
There are many options to read from the stdin. You can use fread with stdin as last parameter, scanf, fscanf(stdin,...),...
For some reason, scanf isn't working properly after using c redirection to pass input to stdin.
I've tested the same code with no c redirection and it works perfectly fine.
Also, I've tried flushing stdin before doing scanf operations with fflush(stdin) and that also did not work.
Running my executable like
./3240Assignment0 < test-input.txt
The code for running the scanf operation looks as follows
int main(int argc, char** argv){
fflush(stdin);
char input[100];
char *output = "Thank you for your message!";
puts("Tell me something nice:");
scanf("%s", input);
printf("%s\n\n", output);
}
The problem is the terminal doesn't give me the opportunity to enter
any information or input.
Script of my terminal
Joes-MacBook-Pro:a0 joemanto$ make test
./3240Assignment0 < test-input.txt
Tell me something nice:
Thank you for your message!
Joes-MacBook-Pro:a0 joemanto$
It accepts input, it just accepts input from the file you've told it to accept input from.
You have three options with STDIN:
assignment: Interactive input
assignment < input.txt: Take input from file
command | assignment: Take input from the result of command command (pipe)
Since you're using the second form you can't take interactive input as well. It's one input source and one only.
i wanted to ask you, how to read from file using in C language:
your_program <file.txt
cat file.txt
Line one
Line two
Line three
i have something like that, but it is not working. Thanks a lot
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int vstup;
input = getchar();
while( input != '\n')
printf("End of line!\n");
return 0;
}
You could use freopen() to make stdin refer to the input file instead of the keyboard.
This can be used for input or output redirection.
In your case, do
freopen("file.txt", "r", stdin);
Now stdin is associated with the file file.txt and when you read using functions like scanf(), you are actually reading from file.txt.
freopen() will close the old stream (which is stdin here) "otherwise, the function behaves just like fopen()". It will return NULL if some error occurred. So you better check the value returned by freopen().
Read more about freopen() here and here.
And as others have pointed out, the code as you posted it is probably having an infinite loop as the value of input never changes inside the loop.
compile/link the proposed code into some file, lets call that executable: run
when running the following proposed code, redirect 'stdin' from the input file
./run < file.txt
Here is the proposed code:
// <<-- document why a header is being included
#include <stdio.h> // getchar(), EOF, printf()
//#include <stdlib.h> <<-- don't include header files those contents are not used
int main( void ) // <<-- since the 'main()' parameters are not used,
// use this signature
{
int input; // <<-- 'getchar()' returns an integer and EOF is an integer
while( (input = getchar() ) != EOF ) // <<-- input one char per loop until EOF
{
if( '\n' == input ) // is that char a newline?
{
printf("End of line!\n"); // yes, then print message
}
}
return 0;
} // end function: main <<-- document key items in your code
I am using the crypt function in C, where I am giving the command line input an encrypted word. I use the words in /usr/share/dict/words and encrypt them using the crypt function and then compare the encrypted output of the crypt function with the command line input. If the words are the same, then I give out the non-encrypted code as the output using a printf statement.
The code is given below.
#include<stdio.h>
#define _XOPEN_SOURCE
#include<unistd.h>
#include<cs50.h>
#include<string.h>
int
main(int argc, string argv[]){
char line[80];
string crypto;
if(argc>2||argc<2)
{
printf("ERROR. Enter only one crypt");
return 1;
}
string crypti=argv[1];
FILE *fr;
string as;
fr=fopen("/usr/share/dict/words","r");
if(!fr)
{
printf("File can't be read");
exit(-1);
}
while(fgets(line,80,fr)!=NULL)
{
as=crypt(line,"50");
if(strcmp(as,crypti)==0)
{
printf("%s",line);
break;
}
}
fclose(fr);
}
The code seems to work fine just for 1 input i.e when I give "./a.out 50q.zrL5e0Sak"(without quotes). However, if I use any other input for the crypt, the code seems to fail. Another example for password:encrypted password is abaca:50TZxhJSbeG1I. The word abaca is present in the list but fails to identify. I am not able to fix this code to work for all inputs.
Add the following snippet to the beginning of while (fgets...) body:
size_t len = strlen(line);
if (len)
line[len-1]='\0';
There is usually a newline \n (when it was read) in the end of the buffer read by fgets.
Your original code works with "password" because only 8 first characters of the key are actually used by crypt. It would work with any word of length 8 or more as well.
Also, make sure that the output is flushed after you print the result, by adding a newline to your format string or (if you don't want to output an extra newline) calling fflush(stdout):
printf("%s\n",line);
/* or */
printf("%s",line);
fflush(stdout);
I have this C program that gets the input from the user and sends it to a method:
#include <stdio.h>
#include <string.h>
#include "constants.h"
#include "lines.h"
#include "compare.h"
//gets arguments and sends to compare.c
int main() {
int op = 1;
char filename[20];
scanf("%d ", &op);
gets(filename);
if ((char) op + '0' < 49 || (char) op + '0' > 57) {
printf("Error: Invalid input");
exit(0);
}
readstdin(filename, op);
return 0;
}
but instead of executing the program and reading from stdin, I want it to read from the unix terminal so that:
./sort [field] < input_file
will read into the file. ([field] is option if no input is put in, default is 1).
For example the command to execute the C program in UNIX would look like this:
./sort 1 < test.txt
How do I go about doing this?
Any help is much appreicated
Thanks!
For a start, you're getting your arguments the wrong way in your code. If what you're wanting is to run your program such as ./sort <option> <filename>, then you don't use stdin to retrieve these arguments.
The arguments in a C program are passed to main using the following function signature:
int main(int argc, char *argv[])
argc is the number of command line arguments passed to the program, and argv is the array of strings of those arguments.
With a run of ./sort 5 test.in:
argc will equal 3
argv[0] will be "./sort"
argv[1] will be "5"
argv[2] will be "test.in"
You should check that the value of argc is 3 to ensure that 2 arguments have been passed ("5", "test.in"), as well as the filename ("./sort") for a total of 3.
If you want to have optional fields, it would be better to have them after the compulsory ones, or better yet is to use something like getopt where you could instead have something like: ./sort --file test.in or ./sort --opt 5 --file test.in. It's probably unnecessary for this case, but it's an option.
You can parse the integer option using atoi or strtol, however you like, to convert it from a string (char*) to an integral type and fopen, fgets, fclose to read from the input file.