Reputation: 364
I've got a text file as follows:
sf5 sd6 sh7
or sh7 sd6 sf5
(any order of the two or the other possible 27 combinations).
I'm trying to extract the values 5,6, and 7
from it
However, I want to do this in any order possible, so sf(somenumber) can be in any of those 3 positions, as well as the other two. Thus, I'm trying to use strstr
as one of my macros.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
typedef struct test
{
char * values;
}test;
int main(int argc, char * argv[])
{
test t;
FILE * file;
char str[100];
int a,b,c;
if(argc > 1)
{
file = fopen(argv[1],"r");
if(file == NULL)
{
exit(1);
}
}
else
{
exit(1);
}
while(fgets(str,100,file) != NULL)
{
t.values = strtok(str," \n");
if(t.values == NULL)
exit(1);
if(strstr(t.values,"sf"))
{
a = atol(t.values+2); // the number two positions after the letter
}
if(strstr(t.values,"sd"))
{
b = atol(t.values+2); // the number two positions after the letter
}
if(strstr(t.values,"sh"))
{
c = atol(t.values+2); // the number two positions after the letter
}
printf("Value of a: %d\n Value of b: %d\n Value of c: %d\n",a,b,c);
}
}
However the output is only correct for the first value "sf5", as if the second two aren't being parsed. Also, if I move "sf5" to the end, it's value provides to be zero which again makes no sense.
Basically, only the first if
statement ever works successfully. Any help would be much appreciated!
Upvotes: 1
Views: 149
Reputation: 73366
Your code has two issues :
in the use of strstr()
you don't use the return pointer, so that if encountering the string but not at the beginning, it vwill look for the digit at the wrong place;
you don't loop on strtok()
to find the subsequent substrings. As strtok()
cuts the string in pieces, you won't find anythning beyond the first separator with strstr()
;
Here an alternative solution based on your original approach (but as I'm very slow in typing, in the meanttime there are already 2 other valuable solutions ;-) )
while (fgets(str, 100, file) != NULL)
{
t.values = strtok(str, " \t\n");
while (t.values) { // loop to analyse each substring
if (p = strstr(t.values, "sf"))
a = atol(p + 2); // the number two positions after the FOUND string
else if (p = strstr(t.values, "sd"))
b = atol(p + 2); // the number two positions after the letter
else if (p = strstr(t.values, "sh"))
c = atol(p + 2); // the number two positions after the letter
t.values = strtok(NULL, " \t\n");
}
printf("Value of a: %d\n Value of b: %d\n Value of c: %d\n", a, b, c);
}
Now if you enter aaasf5 he will find 5 for a, while it found 0 before.
This code (nor yours) address the case where one of the value isn't found. You should therefore initialize your a,b,c to a defautlt value, for example 0.
Upvotes: 0
Reputation: 366
It may be helpful to print the value of t.values before each if block. It shows that t.values does not change. Only the first if block's expression will be true.
If you want to do this using strtok... "Subsequent calls with a null pointer for str1 will cause the previous position saved to be restored and begins searching from that point..."
So maybe insert calls of strtok(NULL, " \n"), like this:
t.values = strtok(str," \n");
if(strstr(t.values,"sf"))
{
a = atol(t.values+2); // the number two positions after the letter
}
t.values = strtok(NULL," \n"); // get pointer to next token
if(strstr(t.values,"sd"))
{
b = atol(t.values+2); // the number two positions after the letter
}
t.values = strtok(NULL," \n"); // get pointer to next token
if(strstr(t.values,"sh"))
{
c = atol(t.values+2); // the number two positions after the letter
}
printf("Value of a: %d\n Value of b: %d\n Value of c: %d\n",a,b,c);
Now the output is
Value of a: 5
Value of b: 6
Value of c: 7
Upvotes: 0
Reputation: 1842
The strstr function gives the position of the searched string or NULL if it's not found. You have to use this result in the atol function in order to get the value associated.
In the code below I use the variable token
to store the result of strstr:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
int main(int argc, char * argv[])
{
FILE * file;
char str[100];
int a,b,c;
if(argc > 1)
{
file = fopen(argv[1],"r");
if(file == NULL)
{
exit(1);
}
}
else
{
exit(1);
}
while(fgets(str,100,file) != NULL)
{
char *token;
token = strstr(str,"sf"));
if (token != NULL)
{
a = atol(token+2); // the number two positions after the letter
}
token = strstr(str,"sd"));
if (token != NULL)
{
b = atol(token+2); // the number two positions after the letter
}
token = strstr(str,"sh"));
if (token != NULL)
{
c = atol(token+2); // the number two positions after the letter
}
printf("Value of a: %d\n Value of b: %d\n Value of c: %d\n",a,b,c);
}
fclose(file);
}
Upvotes: 2