What is wrong with my strcmp function? - c

My code is:
getline(&cmd, &len, stdin);
cmd[strcspn(cmd,"\n")] = 0;
char *ncmd = (char*)malloc(strlen(cmd) + 1);
memset(ncmd, '\0', strlen(cmd));
strcpy(ncmd,cmd);
const char *tok = strtok(ncmd, " ");
// token is just string from stdin
if(!strcmp(tok, "bye")){
printf("bye");
} else if (!strcmp(tok, "help")){
printf("help");
} else if (!strcmp(tok, "list")){
......
}
ie. For input: help and bye
Result: TOK: help
strcmp(tok, "bye"): 6
strcmp(tok, "help"): 0
strcmp(tok, "list"): -10
Result: TOK: bye
strcmp(tok, "bye"): 0
strcmp(tok, "help"): -6
strcmp(tok, "list"): -4
Whatever I type, I can't seem to pull out the correct if statement.
How do I fix the "strcmp" function so it goes to the correct if statements?

As the code and if statement are correct, I think tok has extra characters, such as a newline. Then tok will never be equal to any of your words.

When creating a buffer to use with strtok(), often times the same buffer will be used several times. Therefore, instead of declaring it as:
const char *tok = strtok(ncmd, " "); //tok cannot be changed (const keyword)
Create it so it can be changed:
char *tok = strtok(ncmd, " ");//tok can be changed (removed const keyword)
Example:
char string[] = {"this is \n a string \t with embedded \r non-printables"};
char *tok = {0}; //declare and initialize
tok = strtok(string, " \n\r\t");
while(tok)
{
tok = strtok(NULL, " \n\r\t");//tok will be a different value each iteration
// 1 - this
// 2 - is
// 3 - a
// 4 - string
// and so on
}
...

I didn't understand your code properly, but I hope this is what you are trying to achieve in your code:
int main()
{
char list[] = "bye help list";
char *delim = " ";
char *pch = strtok(list,delim);
int count = 0;
while(pch) {
if(!strcmp(pch,"bye")) {
printf("i found bye at %d\n",count);
} else if (!strcmp(pch,"help")) {
printf("i found help at %d\n",count);
} else if (!strcmp(pch,"list")) {
printf("i found list at %d",count);
}
count++;
pch = strtok(NULL,delim);
}
printf("\n");
return 0;
}

Related

Error when reading strings from CSV (Core Dumped)

I keep getting the same error, I'm new to programming so I'm not so sure if the Syntax is correct.
Every time I run it, it returns Segmentation Fault(core dumped), I'm not even sure If I can open a file with a string (address) instead of the filename in extense.
Also the files I'm reading from are CSV but in txt format.
I'm using C99
#define BUFFER_SIZE 1024
#define TAM_PERGUNTAS 128
struct question{
char category[TAM_PERGUNTAS];
char question[TAM_PERGUNTAS];
char option1[TAM_PERGUNTAS];
char option2[TAM_PERGUNTAS];
char option3[TAM_PERGUNTAS];
char correct[TAM_PERGUNTAS];
};
struct question vec_question[BUFFER_SIZE];
void questions() {
FILE *perguntas;
int numaleat=0;
int num_questions, counter = 0, index, temp_randomizer=0;
char line[BUFFER_SIZE];
char answer[32];
char address[TAM_PERGUNTAS];
address[0] = '\0';
srand(time(NULL));
printf("Digite agora o numero de perguntas desejadas.(MAX 20) : "); //Insert Number of questions
scanf("%d", &num_questions);
printf("\n");
for (counter = 0; counter < num_questions; counter++) {
temp_randomizer = rand() % j; //j Represents the number o CATEGORIES at play and acts as a marker in the SELECTION string
sprintf(address, "%s.txt", SELECTION[temp_randomizer]);
perguntas = fopen(address, "r");
if (perguntas == NULL) {
printf("ERROR OPENING FILE!");
}
index = 0;
while (fgets(line, sizeof(line), perguntas) != NULL) {
strcpy(vec_question[index].category, strtok(line, ";"));
strcpy(vec_question[index].question, strtok(NULL, ";"));
strcpy(vec_question[index].option1, strtok(NULL, ";"));
strcpy(vec_question[index].option2, strtok(NULL, ";"));
strcpy(vec_question[index].option3, strtok(NULL, ";"));
strcpy(vec_question[index].correct, strtok(NULL, ";"));
vec_question[index].correct[strlen(vec_question[index].correct) - 1] = '\0';
index++;
}
fclose(perguntas);
index = 20;
numaleat = rand() % index;
printf("%s : %s\n%s\n%s\n%s",vec_question[numaleat].category,vec_question[numaleat].question,vec_question[numaleat].option1,vec_question[numaleat].option2,vec_question[numaleat].option3);
for (int i = 0; i < num_users; i++) {
printf("\n%s: ", &users[i][20]);
scanf("%s", &answer[32]);
if (answer == vec_question[numaleat].correct)
userspoints[i] += 1;
}
}
}
In general one should assume that functions like strtok can fail.
Sometimes it fails and returns a NULL value. A short record in your input is a likely cause.
Consider using it with a loop, and breaking out of the loop once strtok returns NULL.
I found a simple example here.
#include <string.h>
#include <stdio.h>
int main () {
char str[80] = "This is - www.tutorialspoint.com - website";
const char s[2] = "-";
char *token;
/* get the first token */
token = strtok(str, s);
/* walk through other tokens */
while( token != NULL ) {
printf( " %s\n", token );
token = strtok(NULL, s);
}
return(0);
}
Note that it does one strtok to get the first token. That might return NULL in which case the loop doesn't run. If it doesn't return NULL then it prints that token, and asks strtok for the next token. It keeps doing that until strtok returns NULL.

Unable to achieve expected parsing output with strtok

I have been working on this for a while now but I do not seem to be able to resolve this bug. Any insights will be greatly appreciated thanks.
I am writing code that will parse a string first by ";" and then by " ". The code I have below is as follows:
void arrayVis(char **arr, int size){
printf("[");
for(int i = 0; i < size; i++){
if(arr[i] == NULL || strcmp(arr[i], "") == 0){
break;
}
printf("%s,", arr[i]);
}
void parser2(char *line){
char *token = strtok(line, " ");
char *arr[10];
int index = 0;
while(token != NULL){
arr[index] = token;
token = strtok(NULL, " ");
index++;
}
arrayVis(arr, 10);
}
void parser1(char *line){
char *token = strtok(line, ";");
while(token != NULL){
parser2(token);
// myPrint(token);
printf("\n");
token = strtok(NULL, ";");
}
}
array vis will just allow me to visualize the array that is produced. When I pass "1 2 3;4 5 6;"
I am expecting an output of
[1,2,3
[4,5,6
but instead I just get the output
[1,2,3
Why is my output omitting the second portion of the parse? I have been thinking about this for a while now but I dont seem to understand why this happens. Any insights will be appreciated. Thank you.
int main(void) {
static const char *ROW_TOKENS=";";
static const char *COL_TOKENS=" ";
char buf[] = "data1;data2 data3;data4 data5";
char *aux_row,*cursor_row;
cursor_row = strtok_r(buf, ROW_TOKENS, &aux_row);
// printf("[A] buf: %p, cursor_row=%p, aux_row=%p\n", buf, cursor_row, aux_row);
while (cursor_row) {
char *aux_col,*cursor_col;
printf("[");
cursor_col = strtok_r(cursor_row, COL_TOKENS, &aux_col);
// printf("[B] cursor_row=%p, aux_row=%p, cursor_col=%p, aux_col=%p\n",
// cursor_row, aux_row, cursor_col, aux_col);
while (cursor_col) {
// printf("[C] cursor_row=%p, aux_row=%p, cursor_col=%p, aux_col=%p\n",
// cursor_row, aux_row, cursor_col, aux_col);
printf("%s,", cursor_col);
cursor_col = strtok_r(NULL, COL_TOKENS, &aux_col);
}
cursor_row = strtok_r(NULL, ROW_TOKENS, &aux_row);
printf("\n");
}
return 0;
}

Splitting c array using strtok

I'm making a custom C shell and currently splitting up commands using whitespace:
(Simplified example of what I'm doing currently)
char *buf[20];
char *tempVar;
tempvar = strtok(buf, " ");
For example:
sleep 5 would be split up into sleep and 5.
However, I'm wanting to split for & as well (to create background processes). So sleep 5& would be split into 3: sleep, 5 and &.
Any help would be greatly appreciated.
You can using a specific method to extract numbers, or just drop the character &. I've a thought here, maybe it's not the best solution. Hoping for further exchanges.
char buf[] = "sleep 5&";
char *cmd;
char *arg;
char *tmpArg;
int count = 0;
while (true) {
if (0 == count) {
cmd = strtok(buf, " ");
arg = strtok(NULL, " ");
} else {
cmd = strtok(NULL, " ");
arg = strtok(NULL, " ");
}
printf("%s\n", cmd);
if (NULL != cmd) {
if (strcmp("sleep", cmd) == 0) {
if (arg != NULL) {
// 1. introduce a method to extract digit or
// 2. using `&` to split the arg again, the shortcoming is that we omit character `&` here.
for (int i = 0; i < 2; ++i) {
if (0 == i) {
tmpArg = strtok(arg, "&");
} else {
tmpArg = strtok(NULL, "&");
}
printf("%s\n", tmpArg);
}
}
}
} else {
break;
}
++count;
}

how to remove extra spaces from string in C

I have an string that have an extra spaces string, for example:
char * s = " foo baa ";
I want to conver it to:
foo baa
I have wrote this function:
void trim (char ** src)
{
char * p = strdup(* src);
char * ret = malloc(strlen(*src) + 1);
assert(ret != NULL);
char * token;
token = strtok(p, " \t");
while( NULL != token ) {
while (*token) {
*(ret ++) = *(token ++);
}
token = strtok(NULL, " \t");
}
printf("ret = %s\n", ret);
}
but it given for me an empty string from ret variable value. someone may point out my mistake? thanks in advance.
You are incrementing ret in your while, store the original address or use subscript to access different chars of ret.
// snip
char * ret = malloc(strlen(*src) + 1);
assert(ret != NULL);
char * ret_start = ret;
//snap
printf("ret_start = %s\n", ret_start);
Other naive solution in c++(can be easily changed to c code )----- :)
initially count=0 and str-> your c++ string
for(i=0;i< str.size();i++)
{
if(str[i]!=' ')
{
str[j++]=str[i];
count=0;
}
else if(str[i]==' '&&count==0)
{
str[j++]=str[i];
count =1;
}
}

C programming strtok

I am having trouble with the strtok function. I keep getting a 'bus error.' I wrote a function to return all the words within a line. Could somebody please point out my error?
NOTE: I am used to higher level languages
void extract_words(char tokens[WORD_MAX][WORD_LEN], char* line, int* sizePtr)
{
printf("in extract words"); //for debugging
char* chPtr = NULL;
chPtr = strtok(line, " ");
int size = 1; //words has one element
while(chPtr != NULL)
{
strcpy(tokens[size++], chPtr);
chPtr = strtok(NULL, " "); //continue to tokenize the string
}
*sizePtr = size;
}
Thanks in advance!
strtok modifies the string you pass to it, so it can't be a string literal. You should be able to do something like this:
void extract_words(char tokens[WORD_MAX][WORD_LEN], const char* line_arg, int* sizePtr)
{
char line[(WORD_LEN+1)*WORD_MAX];
char* chPtr = NULL;
int size = 0;
strcpy(line,line_arg);
printf("in extract words"); //for debugging
chPtr = strtok(line, " ");
while(chPtr != NULL)
{
strcpy(tokens[size++], chPtr);
chPtr = strtok(NULL, " "); //continue to tokenize the string
}
*sizePtr = size;
}
Note that I also initialized size to zero, since array indices start at zero.
Well...
Should you try to use a separator?
That case, I have source code.
int split(char *src, char *div, char **result,int *size)
{
int i, j, slen, dlen, key=0, start=0;
slen=strlen(src);
dlen=strlen(div);
for(i=0;i<slen;i++)
{
for(j=0;j<dlen;j++)
{
if(src[i]==div[j])
{
src[i]=0x00;
result[key] = src+start;
key++;
start=i+1;
}
}
}
result[key]=src+start;
*size=key+1;
return 0;
}
using
split(chatData, " ", cmpData, &tok);
" " : token
&tok : count split word
chatData : original data
by korean Dalsam.

Resources