strtok with comma spaces and tab - c

So consider this string:
1,2.2, 3.5 ,6, 7.7
And i want to separate each number, so until now i try this:
void readuserinput(char *ch)
{
char* buffer;
buffer = strtok(ch, ",");
while (buffer) {
printf("%s\n", buffer);
buffer = strtok(NULL, ",");
while (buffer && *buffer == '\040')
buffer++;
}
}
But this ignored theTab and print the number 7.7 with tab before.

As you can see in strtok documentation you can specify multiple delimiters to it. So you don't have to manually deal with whitespaces. strtok will do that for you:
void readuserinput(char *ch)
{
ch = strtok(ch, ", \t");
while (ch)
{
printf("%s\n", ch);
ch = strtok(NULL, ", \t");
}
}

Related

Trying to split text into lines, and then tabs. Get only first line

I have a char array (buf) that exists out of multiple lines and each line is split up by multiple tabs. I want to separate this. I use the following code for this:
char copy[4096];
char* split_request = strtok(buf, "\r\n");
strcpy(copy, split_request);
while(split_request != NULL) {
if (strchr(copy, '\t') != NULL) {
printf("We have a tab");
//If I uncomment this line I get an assertion error
//char* temp = strtok(copy, '\t');
}
printf(split_request);
split_request = strtok(NULL, "\r\n");
if (split_request != NULL) {
strcpy(copy, split_request);
}
printf("\n");
}
If I uncomment that one line of code, only the first line is processed. In addition, it is printed 5 times, and each time one tabbed column disappears. It feels like despite the strcpy, the original string is still affected...
I was experimenting with an alternative approach to your problem. I have used strtok_r for separating lines and each line is processed using strtok for tabs. The code is given below.
void lineParser(char *singleLine){
const char tab[] = "\t";
char *token = NULL;
if(strchr(singleLine, '\t') != NULL){
token = strtok(singleLine, tab);
while(token != NULL){
printf("%s\n", token);
token = strtok(NULL, tab);
}
}
}
int main()
{
char buf[] = "Stack\tOverFlow\r\nStack\tExchange\r\n";
char *rest = buf;;
char* token = NULL;
const char tab[] = "\t";
const char newline[] = "\r\n";
while ((token = strtok_r(rest, " ", &rest))) {
lineParser(token);
token = strtok_r(rest, newline, &rest);
}
}

Removing a word from a given string

I have been trying to write a code to remove a word from an inputted string as part of my homework. But the thing is the outputted "modified" string never really gets modified and it actually always outputs the inputted string. I'm new to strings so I don't have a perfect understanding of how the string.h library functions work.
#include<stdio.h>
#include<string.h>
int main(void)
{
char str[60], strtemp[60], word[10], * token;
printf("Enter the sentence: ");
gets_s(str);
printf("Enter the word to be deleted: ");
gets_s(word);
int i = 0;
token = strtok(str, " ");
while (token != NULL) {
if (!i && token != word)
strcpy(strtemp, token);
else if (token == word) {
token = strtok(NULL, " ");
continue;
}
else {
strcat(strtemp, " ");
strcat(strtemp, token);
}
token = strtok(NULL, " ");
i++;
}
strcpy(str, strtemp);
printf("Modified string: %s \n", str);
}
Add the following:
char *strremove(char *str, const char *sub) {
size_t len = strlen(sub);
if (len > 0) {
char *p = str;
while ((p = strstr(p, sub)) != NULL) {
memmove(p, p + len, strlen(p + len) + 1);
}
}
return str;
}
You should use the memmove() (written on your post's comment too.)
Reference: this thread of SO.

Trying to read in two lines using fgets. Why is it only reading the first line?

I am trying to read in two lines using fgets, but only the first line is read and then returns a segmentation fault. I'm not sure what I would need to change for it to read in the second line. Any help would be appreciated!
int main(void)
{
char str[100];
char *word;
//First Line
fgets(str, 100, stdin);
printf("%s", str);
word = strtok(str," ");
printf("%s\n", word);
while(word != NULL)
{
word = strtok(NULL," ");
printf("%s\n", word);
}
//Second Line
fgets(str, 100, stdin);
printf("%s", str);
word = strtok(str," ");
printf("%s\n", word);
while(word != NULL)
{
word = strtok(NULL," ");
printf("%s\n", word);
}
return 0;
}
You got the order of function calls wrong in two parts of your code; Your are calling printf() after calling strtok() without checking for NULL. Fix it as follows:
int main(void)
{
char str[100];
char *word;
//First Line
fgets(str, 100, stdin);
printf("Printing entire string: %s\n", str);
word = strtok(str, " ");
printf("Printing tokens:\n");
while (word != NULL)
{
printf("%s\n", word);
word = strtok(NULL, " ");
}
//Second Line
fgets(str, 100, stdin);
printf("Printing entire string: %s\n", str);
word = strtok(str, " ");
printf("Printing tokens:\n");
while (word != NULL)
{
printf("%s\n", word);
word = strtok(NULL, " ");
}
return 0;
}
regarding:
word = strtok(str," ");
printf("%s\n", word);
while(word != NULL)
{
word = strtok(NULL," ");
printf("%s\n", word);
}
the function: strtok() can return NULL.
The result is the call to printf() will be trying to print a value from address 0.
That is what is causing the seg fault.
Suggest:
word = strtok(str," ");
while(word != NULL)
{
printf("%s\n", word);
word = strtok(NULL," ");
}

Remove trailing newline character using fgets

I am making a program to read a file and determine if a word is a palindrome. I am running into an issue where the last token has a trailing newline and won't register as a palindrome.
Here is the file input:
leVel CompUtER Science theORY radar
And this is my code:
#include<stdio.h>
#include<string.h>
void palindrome(char str[]){
int length = strlen(str);
int i = 0;
int j = length - 1;
for(i = 0; i < length; i++){
if(str[i] != str[j]){
printf("String %s is not a palindrome.\n", str);
return;
}
j--;
}
printf("String %s is a palindrome.\n", str);
return;
}
int main() {
char line1[100];
fgets(line1, 100, stdin);
printf("%s", line1);
char *token;
token = strtok(line1, " ");
while(token != NULL){
printf("%s\n", token);
palindrome(token);
token = strtok(NULL, " ");
}
Thanks for the help!
If you are using strtok, then you can use " \n" as the delimiter and the newline will be taken care of.
int main() {
char line1[100];
fgets(line1, 100, stdin);
printf("%s", line1);
const char *delim = " \n";
char *token;
token = strtok(line1, delim);
while(token != NULL){
printf("%s\n", token);
palindrome(token);
token = strtok(NULL, delim);
}
...
}
Another great method to remove the newline is to use strcspn like this:
char line[1024];
fgets(line, sizeof line, stdin);
line[strcspn(line, "\n")] = 0; // removing newline if one is found
Why not just use fgetc and stop at the newline? You could also even just find the newline character in the string and assign '\0' to it, and it will be gone.

How to tokenize input for variable amount of words

In here I am trying to tokenize the user input e.g. load sml.txt.
The load command works fine because it has 2 tokens, but if I try to use a single word input like display, it crashes and gives me a segfault. I assume its because the second token is NULL, but I have no idea how to circumvent this issue. Can you help?
For your reference COMMAND_LOAD = "load" and COMMAND_DISPLAY = "display".
int main(int argc, char **argv)
{
AddressBookList *addressBookList;
char input[BUFSIZ];
char load[BUFSIZ];
char fileN[BUFSIZ];
char *fileName;
char *token;
showStudentInformation();
do
{
printf("Enter your command: \n");
fgets(input, sizeof(input), stdin);
input[strlen(input) - 1] = '\0';
token = strtok(input, " ");
strcpy(load, token);
token = strtok(NULL, " ");
strcpy(fileN, token);
fileName = fileN;
if (strcmp(load, COMMAND_LOAD) == 0)
{
addressBookList = commandLoad(fileName);
}
else if (strcmp(load, COMMAND_UNLOAD) == 0)
{
/*commandUnload(fileName);*/
}
else if (strcmp(load, COMMAND_DISPLAY) == 0)
{
if (fileN == NULL)
{
printf("> No file loaded");
}
else
{
commandDisplay(addressBookList);
}
}
else
{
printf("> Invalid input\n\n");
}
} while (strcmp(load, COMMAND_QUIT) != 0);
return EXIT_SUCCESS;
}
strtok() returns NULL when there's no more tokens, you can check for this. If there's no token, I empty the target string by assigning '\0' to the first character, instead of calling strcpy().
do
{
printf("Enter your command: \n");
fgets(input, sizeof(input), stdin);
token = strtok(input, " \n");
if (token) {
strcpy(load, token);
} else {
load[0] = '\0';
}
token = strtok(NULL, " \n");
if (token) {
strcpy(fileN, token);
} else {
fileN[0] = '\0';
}
...
} while (strcmp(load, COMMAND_QUIT) != 0);
There's also no need to replace the last character in the string with \0. Just include \n in the strtok() delimiters, so it won't include the newline at the end in the token.

Resources