While loop not stopping when arguments are equal [duplicate] - c

This question already has answers here:
How to compare strings in an "if" statement? [duplicate]
(5 answers)
Closed 8 years ago.
I am running this program with with ./crack 50yoN9fp966dU
50yoN9fp966dU is crimson encrypted. which is on the word list. My program is as follow:
#define _XOPEN_SOURCE
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
if(argc > 2)
{
printf("Invalid Argument \n");
return 1;
}
else
{
FILE *fp1;
fp1 = fopen("/usr/share/dict/words", "r");
char line[9];
while (fgets(line, 9, fp1) != NULL)
{
char *EncryptLine1;
char *EncryptLine2;
printf("%s", line);
EncryptLine1 = crypt(line, "50");
if(argv[1] == EncryptLine1)
{
printf("%s \n", line);
}
EncryptLine2 = crypt(line, "HA");
if(argv[1] == EncryptLine2)
{
printf("%s \n", EncryptLine2);
}
}
}
}
If I add a printf("%s", EncryptLine1), I see the argv[1], i.e 50yoN9fp966dU, but the loop continue and does not print the answer.

You are doing pointer comparison instead of contents (pointed data) comparison.
Change this:
if (argv[1] == EncryptLine1)
To this:
if (strcmp(argv[1],EncryptLine1) == 0)
And this:
if (argv[1] == EncryptLine2)
To this:
if (strcmp(argv[1],EncryptLine2) == 0)

You have some problems in your code:
You blithely assume argc will never be smaller than 2. Check for unequal 2 instead of bigger two in your first condition.
Anyway, if you return out of an if-block, using else and doing deeper nesting is really superfluous.
Strings cannot be compared with ==, use strcmp.:
if( ! strcmp(argv[1], EncryptLine1))
You need to add a break to break out of the loop or a return to leave the function in your conditional block after printing success, if you want to end the loop there.
if( ! strcmp(argv[1], EncryptLine1)) {
printf("%s \n", line);
break;
}
BTW: Why don't you reuse EncryptLine1 (not that you need any temporary at all there)?

argv[1], EncryptLine1 and EncryptLine2 are all char*s. operator== on two char*s simply checks to see if they are pointing to the same memory location. What you want is to compare the contents of the strings they represent. So, the ifs should look like this:
if(!strcmp(argv[1], EncryptLine1))

Related

Verify if the argv 1 have a determined value [duplicate]

This question already has answers here:
How do I properly compare strings in C?
(10 answers)
Closed 2 years ago.
Problem
I've this simple script to verify the argv. The problem is that if I try to input the argv 1 to "-help" it don't print the string "banner". Why it is not printing the string?
I think that is important to say that I'm noobie with the C language.
Script
#include <stdio.h>
#include <conio.h>
void main(int argc, char *argv[ ]){
int cont;
printf("argv 1 -> %s", argv[1]);
if(argv[1] == "-help"){
printf("banner");
}
if(("%s", argv[1]) == "-help"){
printf("banner");
}
//main
}
argv[1] == "-help" is comparing pointers, not the contents of strings. It will never be true because it is comparing variable region and fixed region.
("%s", argv[1]) == "-help" has the same meaning with argv[1] == "-help". , here is a comma operator.
You should use strcmp() to compare strings in C. Also don't forget to check if argv[1] has meaningful value.
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[ ]){
if (argc >= 2) {
printf("argv 1 -> %s", argv[1]);
if(strcmp(argv[1], "-help") == 0){
printf("banner");
}
}
//main
}

Segmentation Fault With Strcmp With One Input

I am having an issue with the following code.
I have a global variable
char tokens[512][80];
Along with code:
int main(int argc, char** argv) {
char *input = malloc(sizeof(char) * 80);
while (1) {
printf("mini-shell>");
fgets(input, 80, stdin);
parse(input);
if (strcmp(tokens[0], "cd") == 0) {
cd();
}
else if (strcmp(tokens[0], "exit") == 0) {
exit(1);
}
}
}
void parse(char str[]) {
int index = 0;
char* str_ptr = strtok(str, " ");
while (str_ptr != NULL) {
strcpy(tokens[index], str_ptr);
str_ptr = strtok(NULL, " \0\r\n");
//printf("%d\n", index);
index = index + 1;
}
}
I found that if I enter exit for stdin I get a Segmentation fault, but if I enter cd .. for stdin I don't. Why is this so?
We don't know what the definition of the cd() function is, but there are a number of things that you may wish to consider in this program.
First, I don't believe there's any benefit to dynamically allocating 80 bytes of memory for the input buffer when you can easily do so automatically on the stack with char input[80]; - this is free and easy and requires no deallocation when you're done.
If you do this, you derive the size with fgets(input, sizeof input, stdin) where if you change the size of your input line from 80 to some other number, you only have to change it once: the sizeof on an array pulls the size directly.
Your parse() routine needs a little bit of help also. It's a really good idea to declare the function via the extern as shown so that when the compiler sees you call the function in the loop (right after the fgets), it knows the parameter and return types. Otherwise it has to make assumptions.
Because parse() is splitting apart the line you read from input, it's not required to copy the strings to some other place, so you can turn tokens from a multi-dimensional array into a simple array of pointers. As you run strtok() through the line to split up the parameters, you can store just the pointer, knowing that they will be pointing to stable data until the next fgets().
Also: your code does not strictly require or use this, but adding a NULL pointer to the end of the tokens list is a really good idea: otherwise, how does the caller know how many parameters were actually entered? This code checks whether the user entered just a blank line or not.
We've also change the loop around a little bit so the strtok() is called just once instead of twice, including the \n as noted in the comments.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *tokens[512];
extern void parse(char *str);
int main(int argc, char** argv) {
char input[80];
while (1) {
printf("mini-shell> "); fflush(stdout); // make sure user sees prompt
fgets(input, sizeof input, stdin);
parse(input);
if (tokens[0] == NULL) continue; // user entered blank line
if (strcmp(tokens[0], "cd") == 0) {
cd();
}
else if (strcmp(tokens[0], "exit") == 0) {
exit(1);
}
}
}
void parse(char *str) {
int index = 0;
char* str_ptr;
while ( (str_ptr = strtok(str, " \n")) != NULL)
{
tokens[index++] = str_ptr;
str = NULL; // for next strtok() loop
}
tokens[index] = NULL;
}

Check if two files are the same [duplicate]

This question already has answers here:
How do I properly compare strings in C?
(10 answers)
Closed 3 years ago.
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
int main()
{
int status = 0;
FILE * fPointer;
FILE * gPointer;
fPointer = fopen("file1.txt", "r");
gPointer = fopen("file2.txt", "r");
char singleLine[150];
char secondLine[150];
while(fgets(singleLine,150,fPointer)!=NULL && fgets(secondLine,150,gPoi$
{
//fgets(singleLine,150,fPointer);
//fgets(secondLine,150,gPointer);
printf("singleLine: %s\n",singleLine);
printf("secondLine: %s\n",secondLine);
if (singleLine != secondLine)
{
status = 1;
}
}
printf("final status: %d\n", status);
if (status == 0)
{
printf("same\n");
}
else if (status == 1)
{
printf("not same\n");
}
fclose(fPointer);
fclose(gPointer);
return 0;
}
The contents of both files are "hello" and "hello". But for some reason the output I get is
singleLine: hello
secondLine: hello
final status: 1
which equals "not the same".
I checked by printing what singleLine and secondLine are at each iteration and they are the same.
What am I doing wrong?
The following doesn't quite work as you think it does:
if (singleLine != secondLine)
That is because singleLine and secondLine are arrays (treated as strings). Equality/inequality operators in C, when used for arrays, simply check whether the two arrays reside at the same address in memory (i.e. are the same variable). Which in your case are not, so your if statement is always true.
Since you are treating both arrays as strings, the correct function to use is strcmp or strncmp, both defined in <string.h>. This is the standard way of performing string comparisons in C (hence the name of the functions).
Your if statement, in this case should be:
if (strcmp(singleLine, secondLine) != 0)
{
status = 1;
}

How do I find if a substring exists in a string using a specifier?

I have a file with radio frequences of this type
Radio One 104.3
Radio Two 106.3
And I have to pass to the program the name of the radio or the frequence. If I pass the name of the radio or a float number it goes in segmentation fault. I have to use the specifier %[^set] to find the name of the radio in the cass that I pass a frequence in the terminal. How can I do?
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int main(int argc, char *argv[]){
FILE *in;
in = fopen("frequenze.txt", "r");
char radio[100];
float frequenza;
if(isalpha(argv[1]) != 0){
while(fgets(radio, 100, in) == radio){
if(strncmp(argv[1], radio, strlen(argv[1])) == 0){
printf("%s\n", radio);
}
}
}
if(isdigit(argv[1]) != 0){
while(fscanf(in, "%[^%f]", &frequenza) == 1){
if(frequenza == atof(argv[1])){
fgets(radio, 100, in);
printf("%s\n", radio);
}
}
}
return 0;
}
Small as it is, this program still offers quite some opportunities for more or less subtle errors.
It should be checked whether a program argument is given at all.
With isalpha() and isdigit(), only a character can be tested, not a whole string. Perhaps you meant isalpha(*argv[1]) and isdigit(*argv[1]).
Using a conversion specification in a character class (as [^%f]) is imaginative, but not working. Also you cannot re-read a line from in from the beginning without an fseek operation. Better read name and frequency together right from the outset.
The comparison frequenza == atof(argv[1]) fails due to the different precision of the operands (float frequenza vs. double atof()).
if (argc < 2) return 1;
if (isalpha(*argv[1]))
while (fgets(radio, 100, in) == radio)
if (strncmp(argv[1], radio, strlen(argv[1])) == 0)
printf("%s", radio);
if (isdigit(*argv[1]))
while (fscanf(in, "%[^0-9]%f ", radio, &frequenza) == 2)
if (frequenza == (float)atof(argv[1]))
printf("%s%g\n", radio, frequenza);

get input from the file in C

i am new in programming and in stackoverflow that is why i sometime maybe can have simple questions when i code something and want to get input fromthe file`
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
int len1=0;
FILE* p;
char a;
char b[10];
p = fopen(argv[1],"r");
while (1)
{
a = fgetc(p);
if(a == ' ') break;
else
{
len1++;
b[len1-1] = a;
}
}
printf("%c\n", b0);
return 0;
}
it gives segmentation fault and what is the reason?
You have a buffer overrun. If you change your while loop to stop after reading ten characters, even if space has not been reached, you should do fine.
Additionally, you are passing a character at b[len1] into printf, and have it interpreted as a pointer. This will segfault no matter what.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
int len1=0;
FILE* p;
char a;
char b[10+1]; // <<== need one more byte for the terminator
if (argc != 2)
{
fprintf(stderr, "Need to supply a filename\n");
return (-1);
}
p = fopen(argv[1],"r");
if (p == NULL)
{
fprintf(stderr, "Cannot open file %s\n", argv[1]);
return(-2);
}
while (len1 < 10) // <<== avoid buffer overruns
{
a = fgetc(p);
if(a == ' ') break;
else
{
len1++;
b[len1-1] = a;
}
}
b[len1] = '\0'; // <<== Don't forget to zero-terminate
printf("%s\n", b); // <<== Pass the buffer, not the last character from it
return 0;
}
char b[10] only has 10 elements. len1 is incremented every iteration of an infinite loop. This quickly becomes > 10. Eventually somewhere past 10 you write into some memory you don't have access too. Hence the seg fault.
Instead of the while (1), you should test the loop index against the size of your table b (so 10)
What do you want to do exactly ?
You have two problems
What happens when you read the file and the first 10 characters are not a space? The array b will be esxhausted.
printf is trying to print a string. b[len1] is a character.
There are two logical bugs in your program ::
1.while(1) you are having an non-terminating loop, it will result into stackoverflow.
2. char b[10] here, b is a char array of size 10 i.e. b[0] to b[9], but as in your program len1++ is executing for every iteration, which will access memory beyond b[9].
To overcome these issues use while(len1<10).

Resources