Get each word from a line in a text file - c

I am trying to read a txt file, and I can get the line which I want, but I can not print every words in this line one by one;
for example: the line looks like:
hello world 1 2 3
and I need print them one by one which looks like:
hello
world
1
2
3
I got the segmentation fault core dumped error
char temp[256];
while(fgets(temp, 256, fp) != NULL) {
...
int tempLength = strlen(temp);
char *tempCopy = (char*) calloc(tempLength + 1, sizeof(char));
strncpy(temCopy, temp, tempLength); // segmentation fault core dumped here;
// works fine with temp as "name country"
name = strtok_r(tempCopy, delimiter, &context);
country = strtok_r(Null, delimiter, &context);
printf("%s\n", name);
printf("%s\n", country);
}
Can anyone help me fix the code?
Thanks!

Impleted with strtok()
char *p;
char temp[256];
while(fgets(temp,256,fp) != NULL){
p = strtok (temp," ");
while (p != NULL)
{
printf ("%s\n",p);
p = strtok (NULL, " ");
}
}
If you see man strtok You will found
BUGS
Be cautious when using these functions. If you do use them, note that:
* These functions modify their first argument.
* These functions cannot be used on constant strings.
* The identity of the delimiting character is lost.
* The strtok() function uses a static buffer while parsing, so it's not thread safe. Use strtok_r() if this matters to you.
Try to make changes with strtok_r()

While read a line from a file you can invoke the following function:
if( fgets (str, 60, fp)!=NULL ) {
puts(str);
token = strtok(str," ");
while(token != NULL)
{
printf("%s\n",token);
token = strtok(NULL," ");
}
}

Related

How to get first and last word from lines in C?

I have a problem with code. I want to take first and last words from each lines from txt file. I wrote this code for now:
void StartEnd(char * word)
{
FILE* fp;
fp = fopen("linie.txt", "r");
if (fp == NULL) {
printf("! ");
return;
}
char store[MAX_LINE];
while (fgets(store, MAX_LINE - 1, fp)){
char * FirstWord = strtok(store," ");
char * LastWord;
char * token = strtok (store," ");
while (token != NULL){
LastWord = token;
token = strtok (NULL," ");
}
printf("%s\n",LastWord);
}
fclose(fp);
}
It is working for last word but only if i dont use FirstWord with strtok and i dont know why :(.
I would be grateful for any answer. Thanks!
On a first call, the function expects a C string as argument for str,
whose first character is used as the starting location to scan for
tokens. In subsequent calls, the function expects a null pointer and
uses the position right after the end of the last token as the new
starting location for scanning.
On subsequent calls to strtok, you are supposed to pass a NULL pointer. Doing that makes the function work properly:
void StartEnd(char * word)
{
FILE* fp;
fp = fopen("linie.txt", "r");
if (fp == NULL) {
printf("! ");
return;
}
char store[MAX_LINE];
while (fgets(store, MAX_LINE - 1, fp)){
char * FirstWord = strtok(store," ");
char * LastWord;
char * token = strtok (NULL, " ");
while (token != NULL){
LastWord = token;
token = strtok (NULL," ");
}
printf("%s\n",LastWord);
printf("%s\n",FirstWord);
}
fclose(fp);
}
Keep in mind that fgets reads n-1 characters or until it encounters a newline or EOF character. however a newline character is also considered a valid character and stored in the string. That means LastWord may end with a newline character. To fix that, pass " \n" instead of " " to strtok. Then both a newline and a blankspace are considered delimiters.

C tokenizing the input from stdin

I am work in parsing the commands that we get from stdin. My code nearly works. It prints all tokens except the first token. below is my code
/* Read a command line */
if (!fgets(line, 1024, stdin))
return 0;
char *p = strtok (line, " \n");
while (p != NULL)
{
Array[tokenscounter++] = p;
p = strtok (NULL, " \n");
}
}
return 0;
}
when i print all tokens stored in an array, it does not print the first one. any reason why is it behaving like that?

Segmentation fault (core dumped) c

Here is a weird problem:
token = strtok(NULL, s);
printf(" %s\n", token); // these two lines can read the token and print
However!
token = strtok(NULL, s);
printf("%s\n", token); // these two lines give me a segmentation fault
Idk whats happened, because I just add a space before %s\n, and I can see the value of token.
my code:
int main() {
FILE *bi;
struct _record buffer;
const char s[2] = ",";
char str[1000];
const char *token;
bi = fopen(DATABASENAME, "wb+");
/*get strings from input, and devides it into seperate struct*/
while(fgets(str, sizeof(str), stdin)!= NULL) {
printf("%s\n", str); // can print string line by line
token = strtok(str, s);
strcpy(buffer.id, token);
printf("%s\n", buffer.id); //can print the value in the struct
while(token != NULL){
token = strtok(NULL, s);
printf("%s\n", token); // problem starts here
/*strcpy(buffer.lname, token);
printf("%s\n", buffer.lname); // cant do anything with token */
}}
fclose(bi);
return 1;}
Here is the example of string I read from stdin and after parsed(I just tried to strtok the first two elements to see if it works):
<15322101,MOZNETT,JOSE,n/a,n/a,2/23/1943,MALE,824-75-8088,42 SMITH AVENUE,n/a,11706,n/a,n/a,BAYSHORE,NY,518-215-5848,n/a,n/a,n/a
<
< 15322101
< MOZNETT
In the first version your compiler transforms printf() into a
puts() and puts does not allow null pointers, because internally
invokes the strlen() to determine the lenght of the string.
In the case of the second version you add a space in front of format
specifier. This makes it impossible for the compiler to call puts
without appending this two string together. So it invokes the actual
printf() function, which can handle NULL pointers. And your code
works.
Your problem reduces to the following question What is the behavior of printing NULL with printf's %s specifier?
.
In short NULL as an argument to a printf("%s") is undefined. So you need to check for NULL as suggested by #kninnug
You need to change you printf as follows:
token = strtok(NULL, s);
if (token != NULL) printf("%s\n", token);
Or else
printf ("%s\n", token == NULL ? "" : token);

Segmentation fault on line with fgets() - C

I have this code in my program:
char* tok = NULL;
char move[100];
if (fgets(move, 100, stdin) != NULL)
{
/* then split into tokens using strtok */
tok = strtok(move, " ");
while (tok != NULL)
{
printf("Element: %s\n", tok);
tok = strtok(NULL, " ");
}
}
I have tried adding printf statements before and after fgets, and the one before gets printed, but the one after does not.
I cannot see why this fgets call is causing a segmentation failure.
If someone has any idea, I would much appreciate it.
Thanks
Corey
The strtok runtime function works like this
the first time you call strtok you provide a string that you want to tokenize
char s[] = "this is a string";
in the above string space seems to be a good delimiter between words so lets use that:
char* p = strtok(s, " ");
what happens now is that 's' is searched until the space character is found, the first token is returned ('this') and p points to that token (string)
in order to get next token and to continue with the same string NULL is passed as first argument since strtok maintains a static pointer to your previous passed string:
p = strtok(NULL," ");
p now points to 'is'
and so on until no more spaces can be found, then the last string is returned as the last token 'string'.
more conveniently you could write it like this instead to print out all tokens:
for (char *p = strtok(s," "); p != NULL; p = strtok(NULL, " "))
{
puts(p);
}
EDITED HERE:
If you want to store the returned values from strtok you need to copy the token to another buffer e.g. strdup(p); since the original string (pointed to by the static pointer inside strtok) is modified between iterations in order to return the token.

How would i Use strtok to compare word by word

I've been reading up on strtok and thought it would be the best way for me to compare two files word by word. So far i can't really figure out how i would do it though
Here is my function that perfoms it:
int wordcmp(FILE *fp1, FILE *fp2)
{
char *s1;
char *s2;
char *tok;
char *tok2;
char line[BUFSIZE];
char line2[BUFSIZE];
char comp1[BUFSIZE];
char comp2[BUFSIZE];
char temp[BUFSIZE];
int word = 1;
size_t i = 0;
while((s1 = fgets(line,BUFSIZE, fp1)) && (s2 = fgets(line2,BUFSIZE, fp2)))
{
;
}
tok = strtok(line, " ");
tok2 = strtok(line, " ");
while(tok != NULL)
{
tok = strtok (NULL, " ");
}
return 0;
}
Don't mind the unused variables, I've been at this for 3 hours and have tried all possible ways I can think of to compare the values of the first and second strtok. Also I would to know how i would check which file reaches EOF first.
when i tried
if(s1 == EOF && s2 != EOF)
{
return -1;
}
It returns -1 even when the files are the same! Is it because in order for it to reach the if statement outside of the loop both files have reached EOF which makes the program always go to this if statement?
Thanks in advance!
If you want to check if files are same try doing,
do {
s1 = fgetc(fp1);
s2 = fgetc(fp2);
if (s1 == s2) {
if (s1 == EOF) {
return 1; // RETURN TRUE
}
continue;
}
else {
return -1; // RETURN FALSE
}
} while (1);
Good Luck :)
When you use strtok() you typically use code like this:
tok = strtok(line, " ");
while (NULL != tok)
{
tok = strtok(NULL, " ");
}
The NULL in the call in the loop tells strtok to continue from after the previously found token until it finds the null terminating character in the value you originally passed (line) or until there are no more tokens. The current pointer is stored in the run time library, and once strtok() returns NULL to indicate no more tokens any more calls to strtok() using NULL as the first parameter (to continue) will result in NULL. You need to call it with another value (e.g. another call to strtok(line, " ")) to get it to start again.
What this means is that to use strtok on two different strings at the same time you need to manually update the string position and pass in a modified value on each call.
tok = strtok(line, " ");
tok2 = strtok(line2, " ");
while (NULL != tok && NULL != tok2)
{
/* Do stuff with tok and tok2 here */
if (strcmp(tok, tok2)... {}
/* Update strtok pointers */
tok += strlen(tok) + 1;
tok2 += strlen(tok2) + 1;
/* Get next token */
tok = strtok(tok, " ");
tok2 = strtok(tok2, " ");
}
You'll still need to add logic for determining whether lines are different - you've not said whether the files are equivalent if a line break occurs at different position but the words surrounding it are the same. I assume it should be, given your description, but it makes the logic more awkward as you only need to perform the initial fgets() and strtok() for a file if you don't already have a token. You also need to look at how files are read in. Currently your first while loop just reads lines until the end of the file without processing them.

Resources