Something wrong while using crypt function in C - c

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);

Related

Reading contet from stdin file using <file.txt in C, fopen is forbidden

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

getchar to read from command line arguments

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.

junk characters from stdin after reading from file in C

After succesfully reading a re-directed file to my program from the console, I ask a user to enter a word, then use scanf() to read in the word.
The problem i'm having is that scanf() is immediately reading in junk characters and then the program continues. It doesn't even pause to let the user enter anything in the console. It doesn't happen when I don't open a file. EVERYTHING else works perfectly. What could be the issue:
**I tried everything suggested, still can't get it to work. I've made a new project that is just for getting this part to work, here it is. Ignore that scanf is only looking for a single character, even though I ask for a word. I did this just to see if the program would actually pause and allow me to enter something, but it doesn't. Just enters some garbage and program ends.
main(){
int n,i;
char ch;
char line[80];
while(fgets(line, 80, stdin) != NULL){
for(i=0;i<80;i++){
ch=line[i];
if(ch=='\n'){
printf("%c",ch);
break;
}
else{
printf("%c",ch);
}
}
}
printf("Please enter a word: ");
scanf("%c",&ch);
}
You can't re-direct stdin from a file and then also use the keyboard for input (that I know of). If you want to do that, it's simpler to have the program take the input file as a command-line argument and then run it like so: prog myfile.txt. Also, leave yourself a pad with fgets() -- use one less than the allocated array for maxlen. It's always safest with C char arrays to use one less than the allocated length for anything requiring a maximum length in case the maximum length is not including the '\0' terminating character.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc,char *argv[])
{
FILE *f;
int i;
char line[80];
if (argc<2)
{
printf("Usage: %s <inputfile>\n",argv[0]);
exit(10);
}
/* Open file and echo to stdout */
f=fopen(argv[1],"r");
if (f==NULL)
{
printf("Cannot open file %s for input.\n",argv[1]);
exit(20);
}
while (fgets(line, 79, f) != NULL)
printf("%s",line);
fclose(f);
/* Get user input from stdin */
printf("Please enter a word: ");
if (fgets(line,79,stdin)==NULL)
{
printf("Nothing entered. Program aborted.\n");
exit(30);
}
/* Remove CR/LF from end of line */
for (i=strlen(line)-1;i>=0 && (line[i]=='\n' || line[i]=='\r');i--)
;
line[i+1]='\0';
printf("The word entered is: '%s'\n",line);
return(0);
}
sscanf is used to input from a stream or a buffer, and in unix stdin is considered as file so u are supposed to use fscanf which inputs from a file so use fscanf(stdin,"%s",testword);

Input redirection is not working for my program

I'm trying to redirect the input of my program.
Here is the command I'm typing in the terminal:
./hello < name
"name" is a file containing a single string.
hello is a compiled C program consisting of the following code:
int main(int argc, char *argv[])
{
char message[100] = "Hello ";
if(argc>1)
{
strcat(message, argv[1]);
strcat(message, "\n");
}
else
{
strcat(message, "there\n");
}
printf("%s", message);
return 0;
}
As far as I've understood the argument should now be the content of the name file. However in the program I can't detect any arguments (and prints out "Hello there").
That is going to read the file name and put it in your standard input, not in the first argument.
You can read it using fgets, getchar, scanf, etc.
The equivalent:
int c;
printf("Hello ");
while((c = getchar()) != EOF) {
putchar(c);
}
puts("\nthere");
Giving input redirection is different than providing argument.
Input redirection means the provided file will work as standard input.
so if you need filename as an argument, just write like this
./hello name
but by looking at your program, I will say you might have made a logical error. By running the command which I have mentioned above, you will get 'Hello name' printed on your screen. The actual name which you have saved in a file named 'name' will not get printed.

fopen() always returns NULL

int main()
{
int i;
FILE *list,*file;
char temp[30];
list=fopen("filelist","rb");
while(fgets(temp,30,list)!=NULL)
{
file=fopen(temp,"r");
{
fclose(list);
return 0;
}
This is my code I basically want to open all files in filelist but my fopen call (exept the first one always returns a NULL am i missing something also this is my filelist
file1
file2
file3
file4
also i dont use file extensions and files exist in the same directory wtih executable.
fgets() stores the new-line character into the buffer it is populating so you need to remove it before calling fopen() within the while.
From the linked reference page for fgets():
Reads at most count - 1 characters from the given file stream and stores them in str. The produced character string is always NULL-terminated. Parsing stops if end-of-file occurs or a newline character is found, in which case str will contain that newline character.
Example code to remove the new-line:
char* nl = strrchr(temp, '\n');
if (nl) *nl = 0;
fgets leaves the newline on the end of the string, which you can plainly see if you add the following line afterwards:
printf ("[%s]\n", temp);
You'll see something like:
[file1
]
You need to remove it before use, which you can do this with something like:
size_t sz = strlen (temp);
if (sz > 0)
if (temp[sz-1] == '\n')
temp[sz-1] = '\0';
You can see this effect in action in the following complete program:
#include <stdio.h>
#include <string.h>
int main (void) {
size_t sz;
char temp[30];
printf ("\n> ");
while (fgets (temp, sizeof(temp), stdin) != NULL) {
printf ("before: [%s]\n", temp);
sz = strlen (temp);
if (sz > 0) {
if (temp[sz-1] == '\n') {
temp[sz-1] = '\0';
}
}
printf ("after : [%s]\n", temp);
printf ("\n> ");
}
return 0;
}
It basically uses your exact method to get a line using fgets (but from standard input) and then outputs the result both before and after removal of the trailing newline. A sample run follows:
pax> ./testprog
> hello
before: [hello
]
after : [hello]
> goodbye
before: [goodbye
]
after : [goodbye]
> [CTRL-D]
pax> _
You may also want to look at a few other things in that code segment:
the use of an open brace { at the end of the while loop.
the fact that you're opening the files within the loop and not doing anything with them (including closing them).
the use of "rb" open mode. Usually this is unnecessary, it's certainly unnecessary if you know it's a text file.
you should always check the return codes of functions that can fail (like fopen) before using them.
the canonical form of main in C where no arguments are needed is int main (void).
I'll state my case of which I am still uncertain: I thought my problem was with "fopen", but after trying every single solution, I ran into the extension problem, which I'm facing in Windows 10. It appears that Windows puts ".txt" automatically but, if you put ".txt" as extension, the name becomes ".txt.txt" at the end. So I left the file name with no extension, and put "file.txt" as argument of "fopen", and that was the only way it has worked for me.

Resources