Hi im trying to use strtok to seperate a file read.
the text file just has a list of names read into one char array at first stored in to data.
ive removed the file reading bit and shown the array for simplicity.
int main()
{
struct Node* head = NULL;
char data[128] = "john smith\nbob jones\nrobert brown";
char *argv [50];
char * token = strtok(data, "\n"); // separates data into lines
while( token != NULL )
{
insertAtBeginning(&head, token); //LL the data gets stored in
token = strtok(NULL, "\n");
}
}
I have managed to split the data into lines, however i want to split the one line - token into an array by the " ".
so i want argv[0] = "john" and argv[1] = smith.
this argv array then gets stored into the linked list instead of "token" at the line.
thanks any help will be much appreciated.
Related
I was hoping to get some help with a function I am writing.
In a separate header file, I have a struct. it is structured as follows:
typedef struct data{
int id;
char name[100];
char text[200];
struct data *next;
}listData;
Using this struct, I am trying to populate the list with data from a file, which has a format of
id, name, text\n
My function prototype looks as follows:
void loadDataFromFile(listData** dataList);
Because of the commas in between each of the variables, I am not sure how to read the file into the list without getting an error.
Anyone have any ideas?
What you could try doing is reading the file, and then read line by line, in which you can then split up the line by the comma with strtok()
char read_buffer[] = "File content";
char * file_content = read_buffer;
while(file_content) {
char * next_line = strchr(file_content, '\n');
if (next_line) *next_line = '\0'; // Terminate next line so you can read the current line
char * answer = strtok(file_content, ","); // Split the current line by comma
answer = strtok(NULL, ","); // Gets the next value after first comma, do with rest on the line
if (nextLine) *nextLine = '\n'; // Bring the next line back
config = nextLine ? (nextLine+1) : NULL; // Config is equal to the next line (if it exists)
}
I am trying to get the address of a certain line in a text file. This line contains the following;
Kmart, 7055 East Broadway, Tucson AZ
I am using strcpy and strtok functions to extract the address (7055 East Broadway), but so far I've only been able to extract the name of the store (Kmart) using my code.
char strLine[] gets the line from the file and I would like to return it to char strAddress[]
How would I extract just the address and possibly the city and state?
#define MAX_CHARS_PER_LINE 80
void getAddress(char strAddress[], const char strLine[])
{
char newLine[MAX_CHARS_PER_LINE+1];
strcpy(newLine,strLine);
char* token = strtok(newLine, ",");
strAddress = token;
printf("%s\n",strAddress);
}
Assuming,
The address is the second element in the line
It is demarcated with commas.
You can use strtok to get the address as below.
void getAddress(char strAddress[], const char strLine[])
{
char newLine[MAX_CHARS_PER_LINE+1];
strcpy(newLine,strLine);
char* token = strtok(newLine, ",");
if (token != NULL)
{
token = strtok(NULL, ",");
}
if (token != NULL)
{
strcpy (strAddress,token);
}
return;
}
To get the city and state just call token = strtok(NULL, ","); one more time
What if I wanted to separate the city-state and just get the city and get the state separately?
This is a more complex job as you do not have a comma in between the city and the state. You also need to take care of the case where the city can have two words e.g. New Orleans.
You can possibly assume that the state has 2 characters. In this case, a suggested route is
Isolate City + State in a string
Remove spaces at the end of the string
The last 2 characters of the string are the state.
I was having some issues dealing with char*'s from an array of char*'s and used this for reference: Splitting C char array into words
So what I'm trying to do is read in char arrays and split them with a space delimiter so I can do stuff with it. For example if the first token in my char* is "Dog" I would send it to a different function that dealt with dogs. My problem is that I'm getting a strange output.
For example:
INPUT: *cmd = "Dog needs a vet appointment."
OUTPUT: (from print statements) "Doneeds a vet appntment."
I've checked for memory leaks using valgrind and I have none of them or other errors.
void parseCmd(char* cmd){ //passing in an individual char* from a char**
char** p_args = calloc(100, sizeof(char*));
int i = 0;
char* token;
token = strtok(cmd, " ");
while (token != NULL){
p_args[i++] = token;
printf("%s",token); //trying to debug
token = strtok(NULL, cmd);
}
free(p_args);
}
Any advice? I am new to C so please bear with me if I did something stupid. Thank you.
In your case,
token = strtok(NULL, cmd);
is not what you should be doing. You instead need:
token = strtok(NULL, " ");
As per the ISO standard:
char *strtok(char * restrict s1, const char * restrict s2);
A sequence of calls to the strtok function breaks the string pointed to by s1 into a sequence of tokens, each of which is delimited by a character from the string pointed to by s2.
The only difference between the first and subsequent calls (assuming, as per this case, you want the same delimiters) should be using NULL as the input string rather than the actual string. By using the input string as the delimiter list in subsequent calls, you change the behaviour.
You can see exactly what's happening if you try the following code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void parseCmd(char* cmd) {
char* token = strtok(cmd, " ");
while (token != NULL) {
printf("[%s] [%s]\n", cmd, token);
token = strtok(NULL, cmd);
}
}
int main(void) {
char x[] = "Dog needs a vet appointment.";
parseCmd(x);
return 0;
}
which outputs (first column will be search string to use next iteration, second is result of this iteration):
[Dog] [Dog]
[Dog] [needs a vet app]
[Dog] [intment.]
The first step worked fine since you were using space as the delimiter and it modified the string by placing a \0 at the end of Dog.
That means the next attempt (with the wrong spearator) would use one of the letters from {D,o,g} to split. The first matching letter for that set is the o in appointment which is why you see needs a vet app. The third attempt finds none of the candidate letters so you just get back the rest of the string, intment..
token = strtok(NULL, cmd); should be token = strtok(NULL, " ");.
The second argument is for delimiter.
http://man7.org/linux/man-pages/man3/strtok.3.html
I am using strtok_r from string.h to parse the line in a string and the token gives individual line. how can I bind this all lines in a array and return in the caller function.
void call_strtok(char *str)
{
char *token, *remstr ;
token = strtok_r(str,"\n",&remstr);
// printf("token=%c",token[0]);
while(token != NULL)
{
if(token[0] = ' ')
{
token = col_trim_whitespace(token);
if(strcmp(token,"")==0)
{
token = strtok_r(NULL, "\n", &remstr);
continue;
}
}
printf("token=%s\n",token);
_syslog_data_t *data = create_new_syslog_data_t(token);
token = strtok_r(NULL,"\n",&remstr);
}
}
int main()
{
char str[] = " this \n is \n the \n test\n program";
call_strtok(str);
return 0;
}
I can have more lines in the string thus the array to be returned must be dynamic and thus be accessed in the caller main function.
Because at the start it is not known how many tokens you will read, you don't know the size of the array to allocate. Then you could create a linked list and append tokens to this list until done. Now you know the size of the array and can allocate it with malloc and place the tokens read in the array.
When constructing the list, allocate room for each token, i.e. strlen(token)+1 and copy token to it.
You must inform the caller of the size of the array. There are two ways: as a parameter or by defining that the last array entry is NULL, indicating the end.
I was having a problem with my function yesterday that turned out to be a simple fix, and now I am have a different issue with it that is baffling me. The function is a tokenizer:
void tokenizer(FILE *file, struct Set *set) {
int nbytes = 100;
int bytesread;
char *buffer;
char *token;
buffer = (char *) malloc(nbytes + 1);
while((bytesread = getLine(&buffer,&nbytes,file)) != -1) {
token = strtok(buffer," ");
while(token != NULL) {
add(set,token);
token = strtok(NULL," ");
}
}
}
I know that the input(a text file) is getting broken into tokens correctly because in the second while loop I can add printf("%s",token) to display each token. However, the problem is with add. It is only adding the first token to my list, but at the same time still breaks every token down correctly. For example, if my input text was "blah herp derp" I would get
token = blah
token = herp
token = derp
but the list would only contain the first token, blah. I don't believe that the problem is with add because it works on its own, ie I could use
add(set,"blah");
add(set,"herp");
add(set,"derp");
and the result will be a list that contains all three words.
Thank you for any help!
strtok() returns a pointer into the string buffer. You need to strdup() that string and add the result to your tree instead. Don't forget to free() it when you clean up the tree.