Strtok + If Statement - c

im new in here and im having a headache with my program,the thing is that i need to get a input from the keyboard and then separate it using strtok but have to separate the tokens using 4 diferent cases and in each case i need to print the result and save it to a string like this:
input String : Label Instruction #50,Y; Label <with>
and the output should look like this:
Label: Label
Instruction: Instruction
Character [1]: #50
Character [2]: Y
Comentaries: Label <with>
also it has to be able to reconize if a instruction is missed like this:
Input String: adda
Output String
Label: -----
Instruction: adda
Character 1: -----
Comentaries: -----
My code can accept the first and correct instruction but when i type a incorrect one like in the second input it ignores it and continue like the first atempt just ading sometimes,i have tryed to use if to be able to separate each token with its delimeter but everitime i compile it it ignores the if statement no matter what argument i gave it i dont know what else to do
Heres my code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <ctype.h>
int main() { char word[256];
fgets(word,256,stdin);
char *token;
while (token != NULL){
char delimiter[]="\n , ;";
token=strtok (word,delimiter);
//if(token != "\n") //{
//char delimiter[]="\n , ;";
//token=strtok (word,delimiter);
//if (delimiter != " "||"\t" || "_")
printf("Label \"%s\"\n", token);
token = strtok (NULL, "\n , ;"); //(NULL, "_,.-")//}
//token=strtok (word,delimiter); //}
//printf("Label ----------\n");
if (delimiter != "\n"||"\t")//{
printf("Instruction \"%s\"\n", token);
token = strtok (NULL, "\n , ;"); //(NULL, "_,.-")//}
printf("Character \"%s\"\n", token);
token = strtok (NULL, "\n , ;"); //(NULL, "_,.-")
printf("Character 2 \"%s\"\n", token);
token = strtok (NULL, "\n , ;"); //(NULL, "_,.-")
printf("Comentaries \"%s\"\n",token);
token = strtok (NULL, ";");
// printf("Character 2\"%s\"\n", token);
// token = strtok (NULL, "\n , ;"); //(NULL, "_,.-")
token = NULL;}
//token = NULL;
//printf("Comentaries \"%s\"\n", token);
//token = NULL;
return(0);
}
the // coments are all my failed attempts to try to make it work =(
Can someone help me please?

char *token;
while (token != NULL){
where is token initialized?
Then:
if (delimiter != "\n"||"\t")
You are only comparing pointers in the if controlling expression: use strcmp function to compare strings.

I could see various problems with your code, as listed below:
1.Your while loop is based on token which is not initialized. Better use a do/while.
2.delimiter is a string and cannot be compared using != operator. Use strcmp/strncmp.
3.What is the point of checking delimiter in every iteration when it is the assigned the same value everytime? I am not sure what are you trying to achieve by doing that. AFAIK, the value of delimiter is not changed on a call to strtok.
4.token should pass through a NULL check before every call to strtok as you area allowed to enter a "wrong" string.
5.Nothing wrong with it, but why exactly was fgets used for taking input from stdin, when you could simply do a scanf?
Hope above solves your issues.

Related

strtok twice a char* [duplicate]

I am trying to use strtok() in nested loops but this is not giving me desired results,
possibly because they are using the same memory location. My code is of the form:-
char *token1 = strtok(Str1, "%");
while (token1 != NULL)
{
char *token2 = strtok(Str2, "%");
while (token2 != NULL)
{
//Do something
token2 = strtok(NULL, "%");
}
// Do something more
token1 = strtok(NULL, "%");
}
Yes, strtok(), indeed, uses some static memory to save its context between invocations. Use a reentrant version of strtok(), strtok_r() instead, or strtok_s() if you are using VS (identical to strtok_r()).
It has an additional context argument, and you can use different contexts in different loops.
char *tok, *saved;
for (tok = strtok_r(str, "%", &saved); tok; tok = strtok_r(NULL, "%", &saved))
{
/* Do something with "tok" */
}
strtok is using a static buffer.
In your case you should use strtok_r. This function is using a buffer provided by the user.
WayneAKing posted an alternative in the Microsoft Developer Center.
Citing him:
Go here
http://cpp.snippets.org/code/
and download this file
stptok.c Improved tokenizing
function
You can also download the needed
header files from the same site.
This is a modified version of strtok
which places the parsed tokens
(substrings) in a separate buffer. You
should be able to modify it to
accommodate your needs.
Wayne
P.S. - Note that these files may be in
*nix format with respect to end-of-lines. i.e. - 0x0A only and not
0x0D 0x0A
This is an alternative if you don't have the Microsoft libraries in your environment.

C - Reading CSV file in char array

I have a very little experience in C programming, particularly File Handling. I am developing a project in which I'm supposed to create a Sign Up/Log In system. I have a .csv file in which the data are separated by ,
What I am trying to do is reading the first and second column into two char arrays respectively.
char userLogin[100];
char userPassword[100];
FILE *file3 = fopen("C:\\Users\\Kshitiz\\Desktop\\BAAS\\signup_db.csv","r");
if(file3 != NULL){
while(!feof(file3)){
fscanf(file3,"%[^,],%s",userLogin,userPassword);
puts(userLogin);
puts(userPassword);
}
}
fclose(file3);
Content of signup_db.csv:
Username,Password
SBI063DDN,Qazwsx1234
ICICIDDN456,WSXEDC1234r
Expected Output:
Username
Password
SBI063DDN
Qazwsx1234
ICICIDDN456
WSXEDC1234r
Output which I'm getting:
Username
Password
SBI063DDN
Qazwsx1234
ICICIDDN456
WSXEDC1234r
WSXEDC1234r
Can anyone please help me how can I resolve this issue? Thank you!
The 'fscanf()' function returns the number of items of the argument list successfully filled. So instead try this:
while(fscanf(file3,"%[^,],%s",userLogin,userPassword) == 2)
{
puts(userLogin);
puts(userPassword);
}
The problem you mentioned is probably because of a new line character at the end of your file. When you read the last line, you have not yet reached the end of file. The above code solves this issue.
In my case I have the expected results, but I don't know if there is a difference with the compiler or if my csv file is different (I've tried to recreate it). Here is another way to parse the file, check if you have the expected results:
#include <stdio.h>
#include <string.h>
#define LINE_LENGTH 1000
int main(void) {
char userLogin[100];
char userPassword[100];
char line[LINE_LENGTH];
char *delimiter = ",";
char *token;
FILE *file3 = fopen("signup_db.csv", "r");
while(fgets(line, LINE_LENGTH, file3) != NULL) {
token = strtok(line, delimiter);
printf("%s\n", token);
token = strtok(NULL, delimiter);
printf("%s\n", token);
}
fclose(file3);
}

Breaking a string in C with multiple spaces

Ok, so my code currently splits a single string like this: "hello world" into:
hello
world
But when I have multiple spaces in between, before or after within the string, my code doesn't behave. It takes that space and counts it as a word/number to be analyzed. For example, if I put in two spaces in between hello and world my code would produce:
hello
(a space character)
world
The space is actually counted as a word/token.
int counter = 0;
int index = strcur->current_index;
char *string = strcur->myString;
char token_buffer = string[index];
while(strcur->current_index <= strcur->end_index)
{
counter = 0;
token_buffer = string[counter+index];
while(!is_delimiter(token_buffer) && (index+counter)<=strcur->end_index)//delimiters are: '\0','\n','\r',' '
{
counter++;
token_buffer = string[index+counter];
}
char *output_token = malloc(counter+1);
strncpy(output_token,string+index,counter);
printf("%s \n", output_token);
TKProcessing(output_token);
//update information
counter++;
strcur->current_index += counter;
index += counter;
}
I can see the problem area in my loop, but I'm a bit stumped as to how to fix this. Any help would be must appreciated.
From a coding stand point, if you wanted to know how to do this without a library as an exercise, what's happening is your loop breaks after you run into the first delimeter. Then when you loop to the second delimeter, you don't enter the second while loop and print a new line again. You can put
//update information
while(is_delimiter(token_buffer) && (index+counter)<=strcur->end_index)
{
counter++;
token_buffer = string[index+counter];
}
Use the standard C library function strtok().
Rather than redevelop such a standard function.
Here's the related related manual page.
Can use as following in your case:
#include <string.h>
char *token;
token = strtok (string, " \r\n");
// do something with your first token
while (token != NULL)
{
// do something with subsequents tokens
token = strtok (NULL, " \r\n");
}
As you can observe, each subsequent call to strtok using the same arguments will send you back a char* adressing to the next token.
In the case you're working on a threaded program, you might use strtok_r() C function.
First call to it should be the same as strtok(), but subsequent calls are done passing NULL as the first argument. :
#include <string.h>
char *token;
char *saveptr;
token = strtok_r(string, " \r\n", &saveptr)
// do something with your first token
while (token != NULL)
{
// do something with subsequents tokens
token = strtok_r(NULL, " \r\n", &saveptr)
}
Just put the process token logic into aif(counter > 0){...}, which makes malloc happen only when there was a real token. like this
if(counter > 0){ // it means has a real word, not delimeters
char *output_token = malloc(counter+1);
strncpy(output_token,string+index,counter);
printf("%s \n", output_token);
TKProcessing(output_token);
}

How can I split an input using multiple delimiters?

I want to split into tokens an lessons.txt file. This file has some people and these people's lessons. How can I do it ?
There is my lessons.txt file :
George Adam :Math,Science,Germany
Elizabeth McCurry :Music,Math,History
Tom Hans :Science,Music
Firstly, I want to split into ":". And I want to store names in an array. Secondly , I want to split into "," and these lessons I want to store an different array. How can I this ?
There is my code below :
char names[100] , *token, *lecture;
file=fopen("C:\\lessons.txt","r");
while(!feof(file))
{
fgets(names,sizeof(names),file);
printf("%s",names);
token=strtok(names,":");
while(token!=NULL)
{
token=strtok(NULL,":");
printf(" \n %s",token);
lecture=strtok(token,",");
while(lecture!=NULL)
{
lecture=strtok(NULL,",");
printf(" \n\n %s",lecture);
}
}
}
fclose(file);
So you want names to be stored in a separate array, and lessons to be stored in another?
You will need two separate tokens, you are using the same token for names and lessons.
Try this :
FILE *file;
file = fopen("C:\\lessons.txt", "r");
char names[100], *token, *difftok;
while (fgets(names, sizeof(names), file) != NULL) {
token = strtok(names, ":")
//puts(token); ---> George Adams
difftok = strtok(NULL, ",");
//puts(difftok); ---> Math
difftok = strtok(NULL, ",");
//puts(difftok); ---> Science
difftok = strtok(NULL, "\n");
//puts(difftok); ---> Germany
}
fclose(fp);
}
In my excerpt, token will always represent names, and difftok will always be lectures, from here I think you can figure out how to store the tokens into an array. Token goes into one, difftok into another.
Also, your EOF condition is wrong, feof returns a non-zero when it reaches end of file :
while(!feof(file))
Should be:
while(feof(file) == 0)
However, in this case I used fgets(...) != NULL because fgets return NULL when it reached end of file. You should probably use my condition as feof(file) == 0 encounters some end of file problems when used with your code and messes up the way the tokens parse the string.

Creating a terminal menu with a challenge

What I wont to do is to create a terminal menu that takes various types of arguments and place it in a array param. Under is the code: Here is some trouble that I have and cant find a good solution for.
if i just type 'list' I will get Not a valid command, I have to type “list “ (list and space).
Menu choice new should be like this: new “My name is hello”. param[0] = new and param[1] = My name is hello , (sow I can create a message with spaces).
How can I accomplish this?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
int menu()
{
printf(">");
char line[LINE_MAX];
int i = 0;
char *param[4];
while(fgets(line, LINE_MAX, stdin) != NULL) {
param[i++] = strtok(line, " \n");
if(param[0] != NULL) {
char *argument;
while((argument = strtok(NULL, "\n")) != NULL) {
param[i++] = argument;
}
}
if(strcmp(param[0], "new") == 0) {
//new(param[1]);
menu();
} else if(strcmp(param[0], "list") == 0) {
//list();
menu();
} else {
printf("Not a valid command.\n\n");
menu();
}
}
return 0;
}
You're delimiting on " ".
fgets reads the ENTER.
So, when you type "listENTER" and tokenise at spaces you get one token, namely "listENTER". Later you compare with "list" and, of course, it doesn't match.
Try
strtok(line, " \n"); /* maybe include tabs too? */
PS. Why are you calling menu recursively? You already have a while in the function ...
Your problem is param[i++] = strtok(line, " "); will only split on space, not on \n (newline). Try adding this to your array of delimeters.
Oh, and congratulations for some decent looking code that's clean and well formatted. A pleasant change.
I'm not sure if this causes your problem but these lines
/*new(param[1]);
/*list();
Start a comment that is never terminated.
If you want one line comments you can use:
// comment
(atleast in C++ and from C99 on)
But comments starting with /*must be ended with a */and not nested:
/* comment */
/* also multi line
allowed */
Since you start a comment in a comment your compiler should have emmited a warning, actually this shouldn't compile at all.
The reason you need to type "list " is that your first strtok tokenizes until a space character, so you need to enter one in this case. Try allowing both '\n' and space as separators, i.e. replace the second parameter of strtok with " \n".
As for quotes, you need to re-combine parameters starting from the one beginning with a quote to the one ending with one by replacing the characters in between them with spaces. Or do away with strtok and parse by manually iterating through the characters in line.

Resources