strcasecmp is not returning zero - c

I want to know why strcasecmp() is returning 0 the first time I use it but not the second.
In this example i'm specifically entering "hello world" into standard input.
Instead of printing 0 0 it's printing 0 10. I have the following code.
#include "stdio.h"
#include "string.h"
int main(void) {
char input[1000];
char *a;
fgets(input, 1000, stdin);
a = strtok(input, " ");
printf("%d\n",strcasecmp(a,"hello")); //returns 0
a = strtok(NULL, " ");
printf("%d\n",strcasecmp(a,"world")); //returns 10
return 0;
}
What am I doing wrong?

The newline, you have entered after hello world is part of the world token because you use space as token separator.
If you use strtok(input, " \n"); instead of strtok(input, " "); the program will behave correctly. In fact, you probably want to use tabulator as token separator as well.
The whole program will be:
#include "stdio.h"
#include "string.h"
int main(void) {
char input[1000];
char *a;
fgets(input, 1000, stdin);
a = strtok(input, " \n\t");
if (a == NULL) return(-1);
printf("%d\n",strcasecmp(a,"hello"));
a = strtok(NULL, " \n\t");
if (a == NULL) return(-1);
printf("%d\n",strcasecmp(a,"world"));
return 0;
}

Related

How to parse through a string of STDIN word by word in C

I would like to read standard input of a command and its argument in a C program, for instance:
ATTACK 50 30
I would like my program to parse through the input using whitespace and assign each word to a variable but right now I would just like to print each word. However, when I tried the program only returned ATTACK and not ATTACK 50 30.
I tried:
int main(){
// Grid size declaration //
int *x, *y;
char command[20];
char user_input[100];
scanf("%s", user_input);
printf("%s", user_input);
return 0;
}
As I said I used ATTACK 50 30 as my STDIN but my printf function only returned ATTACK. I thought of maybe using a while loop to keep scanning until the character interpreted is the return key (which I believe in this case would just be the null character?). I tried it using the code below:
int main(){
// Grid size declaration //
int *x, *y;
char command[20];
char user_input[100];
while(scanf("%s", user_input)!="\0"){
scanf("%s", user_input);
printf("%s", user_input);
}
return 0;
}
This did not work, the error produced declared I was comparing a pointer to an integer.
Since you are dealing with stdin it would probably be a better idea to utilize the fgets function in lieu of the scanf function, and then parse the inputted line of data utilizing the strtok string function.
Utilizing that strategy, following is a snippet of code allowing for the parsing of entered text where each word or data group is identified.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 64
int main()
{
char line[MAX + 1];
const char delim[2] = " ";
char * wd;
printf("Enter some text or type \"quit\" to end: ");
while (fgets(line, MAX, stdin))
{
line[strlen(line) - 1] = ' '; /* Replace newline character at the end with a space */
wd = strtok(line, delim);
while (wd != NULL)
{
if (strcmp(wd, "quit") == 0)
{
return 0;
}
printf("%s\n", wd);
wd = strtok(NULL, delim);
}
printf("Enter some text or type \"quit\" to end: ");
}
return 0;
}
Testing out this code utilizing your text example yielded the following terminal output.
#Dev:~/C_Programs/Console/ParseWord/bin/Release$ ./ParseWord
Enter some text or type "quit" to end: ATTACK 50 30
ATTACK
50
30
Enter some text or type "quit" to end: quit
#Dev:~/C_Programs/Console/ParseWord/bin/Release$
This is just a springboard from where you might go, but test that out and see if it meets the spirit of your project.

How to seperate user input word delimiter as space using strtok

Why am I getting a segmentation fault after only reading one word?
If I enter "why is this not work"
I only get back
why
and then I get a segmentation fault.
I've seen other examples but none have used user input like I am trying to do here. I can only read one word and it won't work. I tried changing all the %c to %s but it is not helping me. I also realize segmentation fault is pointer pointing to somewhere not in memory but I cannot see what is wrong with it. Please help me understand.
#include <stdio.h>
#include <string.h>
int main()
{
char word[100];
printf("Enter a sentence: ");
scanf("%s", word);
char *tok = strtok(word, " ");
printf("%s\n", tok);
while(tok != NULL)
{
tok = strtok(NULL, " ");
printf("%s\n", tok);
if(tok == NULL)
printf("finished\n");
}
return 0;
}
EDIT: I changed scanf("%s", word); to fgets(word, 100, stdin); and now it prints everything but I get a Segmentation fault.
As pointed in comments, there is at least two problems in your first code.
Do not use scanf to read a string that you want to parse. Use fgets instead.
You do not test that tok is not NULL before using it (inside the while loop)
Such problems would have been easily detected with debugging, so I encourage you to read how to debug small programs
Corrected code should be like:
#include <stdio.h>
#include <string.h>
int main(void)
{
char word[100];
printf("Enter a sentence: ");
/* read from stdin
note the `sizeof char`, if you need to change the size of `word`,
you won't have to change this line. */
fgets(word, sizeof word, stdin);
/* initialize parser */
char *tok = strtok(word, " ");
while (tok != NULL)
{
/* printf token: it cannot be NULL here */
printf("%s\n", tok);
/* get next token*/
tok = strtok(NULL, " ");
}
printf("finished\n");
return 0;
}
This code is not correct
while(tok != NULL)
{
tok = strtok(NULL, " ");
printf("%s\n", tok);
if(tok == NULL)
printf("finished\n");
}
suppose you get to the last pass through the loop.... it gets into the loop as you got last time.... so you make a tok = strtok(NULL, " "); which returns (and assigns) NULL as there is no more stuff.... then you printf(3) it, which produced the seg fault.
Just change that into this, so you don't enter into the loop if no more tokens are available.
while((tok = strtok(NULL, " ")) != NULL)
{
printf("%s\n", tok);
/* you don't touch tok inside the loop, so you don't need to
* test it again once you get inside */
}
/* if(tok == NULL) <-- you always have tok == NULL here */
printf("finished\n");
or simpler
while(tok = strtok(NULL, " "))
{
printf("%s\n", tok);
}
printf("finished\n");
Also, add \n to the second parameter of strtok(3) call (in the two calls you have in your listing, as you can have only one token, and the final line ending has to be dropped from the first call), as when you use fgets(3) you normally will get a \n at the end of the string (which you don't want):
char *tok = strtok(word, " \n");
printf("%s\n", tok);
while(tok = strtok(NULL, " \n"))
{
printf("%s\n", tok);
}
printf("finished\n");

Take user input and then do execvp

So I have the following C code which asks the user to give a command (valid in unix), and then I have to take the string and split it in an array in order to execute the command that the user gave with execvp(). It compiles but the execvp doesn't seem to work. Is something wrong in the way I split the user's input in an array? PS: Some of the includes aren't neccessary but it's not the final program.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <signal.h>
main() {
char str[64];
int i =0;
char *p = strtok(str," ");
printf("Please give me a Unix command! :\n");
gets(str);
char *array[sizeof(str)];
while (p!=NULL) {
array[i++] = p;
p = strtok (NULL, " ");
}
execvp(str ,array);
perror("execvp");
}
The output I get when I run this is:
Please give me a Unix command! :
ls -l
execvp: No such file or directory
You're calling strtok(str, " ") before str has any information.
Simply call it after you get input:
main() {
char str[64];
char *array[sizeof(str)];
char *p = NULL;
int i = 0;
printf("Please give me a Unix command! :\n");
fgets(str, sizeof(str), stdin); // Use fgets instead of gets.
p = strtok(str," ");
while (p != NULL) {
array[i++] = p;
p = strtok(NULL, " ");
}
execvp(str, array);
}
The first problem as I see here is with
char *p = strtok(str," ");
as you're trying to read indeterminate values. str is not initialized, there's no guarantee that there is a null-terminator present there which makes this a string. So, you're essentially invoking undefined behavior.
That said,
gets(), it is dangerous as it lead to buffer overflow. use fgets() instead.
for an array variable, sizeof(str) does not give you the size of the content, it returns you the size of the whole array. You might want to use strlen() to get the length of the string, but remember, strlen() does not count the null-terminator.

Taking a string, and parsing/tokenizing into smaller strings using hyphen delimiter

I am tasked with writing a C program that will take a string with hyphens in it, and check to see that the first group of the string (before the hyphen) is alphabet/letter only, the next group is numeric only, and the last group is alphabet/letter only. It is similar to this project: http://wps.aw.com/wps/media/objects/7257/7431666/Case_Studies/GaddisJavaCSO_CS6.pdf
So far I am stuck on splitting the string into 3 variables. I have read about strtok and manipulating the scanf function, but I haven't been successful:
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main ()
{
char serial [50];
char * part1 = NULL, part2 = NULL, part3 = NULL;
printf("Enter Serial Number:\n");
scanf("%s", serial);
part1 = strtok (serial, "-");
part2 = strtok(NULL, "-");
part3 = strtok(NULL, "-");
printf("You entered %s\n", part1);
printf("You entered %s\n", part2);
printf("You entered %s\n", part3);
return 0;
}
you are using strtok wrong, pass parameters to it and it should work fine.
char * pch = strtok (serial, "-" );
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, "-");
}
or in your example you need to define each as a char* :
char * part1= strtok (serial, "-");
char * part2 = strtok(NULL, "-");
char* part3 = strtok(NULL, "-")
StrTok + example
strcpy(part1, strtok(serial, "-"));//premise: string has hyphen
strcpy(part2, strtok(NULL, "-"));
strcpy(part3, strtok(NULL, "-"));
You could utilize scanf's formatting rules to read your strings directly from the input line.
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main ()
{
char part1[40], part2[40], part3[40];
int count, n;
do{
n = 0;
flushall();
printf("Enter Serial Number:\n");
count = scanf(" %39[A-Za-z]-%39[0-9]-%39[A-Za-z]%n", part1, part2, part3, &n);
if( count != 3 || n == 0 ){
printf("Recognize %i parts, %s\n", count, n == 0 ? "did not parse to the end" : "parsed to the end");
}
}while(count != 3 || n == 0);
printf("You entered %s\n", part1);
printf("You entered %s\n", part2);
printf("You entered %s\n", part3);
return 0;
}
This is quite a strict form of parsing the input and requires the user to keep the outer form. You can easily filter allowed strings by not using %s but rather something like %[0-9]. The best way for me to filter serialnumber inputs was always Regex if available... but i dont think this is part of your homework yet :)

strtok return string?

just having a little issue with strtok and strcmp.
I'm trying to compare the input of a user via fgets to some predetermined string:
char *token[100];
fgets(s, sizeof(s), stdin)
token[0] = strtok(s, " "); // Get first word
printf("tok: %s", token[0]);
printf("cmp: %d\n", strcmp(token[0], "/bin/echo");
Obviously it's not all the code but this shows my problem - if I enter "/bin/echo ..." (or anything for that matter), it will be put into token[0], and get printed. It prints correctly but when it prints the cmp value it's never 0. For /bin/echo, the cmp value is 1 for some reason.
Thanks.
EDIT to clear up confusion about s and token:
char s[1024];
char *token[100];
EDIT 2 - Added some other test cases:
I entered "/bin/echo hello world" to stdin
token[0] = strtok(s, " \n\0"); // Get first word
printf("token[0] is: %s", token[0]);
printf("cmp: %d\n", strcmp(token[0], "/bin/echo"));
Output:
token[0] is: /bin/echo
cmp: 1
And then I tried hardcoding the tokened string:
char str[] = "/bin/echo hello world";
token[0] = strtok(str, " ");
printf("token[0] is: %s", token[0]);
printf("cmp: %d\n", strcmp(token[0], "/bin/echo"));
Output:
token[0] is: /bin/echo
cmp: 0
here i have made small program
#include<string.h>
#include<stdio.h>
int main()
{
char str[] ="/bin/echo this is something";
char * token[100];
token[0] = strtok (str," ");
token[0] = strtok(str, " "); // Get first word
printf("cmp: %d\n", strcmp(token[0], "/bin/echo"));
return 0;
}
Here i have statically stored input string instead of fgets()
That works fine.
see http://codepad.org/IrGAXT8f
Use
char token[1000];
strcpy(token,strtok(s," "));
string's can't be assigned directly like this in c :)
also, include string.h
One needs to allocate memory dynamically for copying strings. Read about dynamic memory management first (malloc, calloc, etc...)
EDIT:
http://ideone.com/0UxEwO - works for me
#include <stdio.h>
#include <string.h>
int main()
{
char s[1024];
char *token[100];
fgets(s, sizeof(s), stdin);
token[0] = strtok(s, " \n\0");
printf("token[0] is: %s", token[0]);
printf("cmp: %d\n", strcmp(token[0], "/bin/echo"));
}

Resources