-1

I'm asking this question because the solutions I found to similar questions, here on stackoverflow, didn't allow me to solve my problem. I have a .txt file which is as follow:

VarA 10.0 20.0 30.0
VarBB 10
VarCz 1 2 3 4
VarDab 10 20 30 40 50
...

I'm trying to output (e.g. store them in a variable) the numbers associated to a specific variable using the sscanf function. For example, when looking for the string VarDab in the file, I want to store the numbers 10, 20, 30, 40, 50 in a variable. Because the number of numbers found for a specific string variable is not constant, I was trying to use the sscanf function in a loop. However, I'm not getting the result that I want. The code I have done so far:

FILE *fid;
char nameOfVariable[] = "VarDab";
int i;
while(!feof(fid))
{
    fgets(Line, maxLengthOfLine, fid);
    sscanf(Line, "%s", varString);
    if (strcmp(nameOfVariable, varString) == 0)
    {
        for (i = 0; i < maxLengthOfLine; i++)
        {
            sscanf(Line, "%lf%n", &varNumbers[i]);
        }
    }
}
flcose(fid);

EDIT

From the comments, I was able to modify my current implementation by adding an offset to the Line at each increment in the loop. It seems to work:

FILE *fid;
char nameOfVariable[] = "VarDab";
int i;
int variableIsFound = 1;
int offset = 0;
int numberOfNumbers = 5;

while(fgets(Line, maxLengthOfLine, fid) != NULL && variableIsFound)
{
    sscanf(Line, "%s %n", varString, &offset);
    if (strcmp(nameOfVariable, varString) == 0)
    {
        Line += offset;
        for (i = 0; i < numberOfNumbers; i++) {
            sscanf(Line, "%lf %n", &y[i], &offset);
            Line += offset;
        }
        variableIsFound = 0;
    }
}
fclose(fid);
m_power
  • 3,156
  • 5
  • 33
  • 54
  • 1
    Please post [mcve] and the results - the expected and the actual. – Eugene Sh. Sep 11 '19 at 19:31
  • Warning for `sscanf`: not enough arguments passed. I suppose you intend to advance a string pointer with each field, however the first read will fail trying to read a `double` from a string beginning with `"VarDab"`. – Weather Vane Sep 11 '19 at 19:34
  • @WeatherVane Yes, I think I'll have to use some kind of offset to modify the `Line` that I read with `sscanf`. – m_power Sep 11 '19 at 19:40
  • 1
    There is quite a lot wrong with the code. Another is that you attempt to scan `maxLengthOfLine` values without making any attempt to find where it ends. You *must* check the return value from `sscanf`. But personally, I would solve this with `strtok()`. – Weather Vane Sep 11 '19 at 19:41
  • regarding; `file *fid;` The C language is case sensitive. The `FILE` is a typedef name for a struct that describes a file. so: 1) must have: `#include ` 2) the correct syntax is: `FILE *fid;` – user3629249 Sep 11 '19 at 22:37
  • 1
    please read: [why while(!feof(fid)) is always wrong](https://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong) Suggest using: `while( fgets(Line, maxLengthOfLine, fid) ) {` – user3629249 Sep 11 '19 at 22:41
  • 1
    regarding: `sscanf(Line, "%s", varString);` and `sscanf(Line, "%lf%n", &varNumbers[i]);` 1) when using '%s' or '%[...]' always include a MAX characters modifier that is one less than the length of the input buffer because those specifiers always append a NUL byte to the input. This also avoid buffer overflow and the attendant undefined behavior. 2) always check the returned value (not the the parameter values). in this case, any returned value other than 1 indicates an error occurred. 3) do NOT put '\n' in the format string – user3629249 Sep 11 '19 at 22:46
  • @WeatherVane, I provided an update of my code which now includes the length of the input buffer. – m_power Sep 12 '19 at 13:50
  • @user3629249, I modified my code with the change you proposed (i.e. `while( fgets...)`). – m_power Sep 12 '19 at 14:11
  • regarding: `sscanf(Line, "%lf %n", &y[i], &offset);` as you stated, the number of following values is an unknown, should be checking the returned value from the call to `sscanf()` to be able to exit the loop when no more data is available – user3629249 Sep 13 '19 at 15:07

1 Answers1

1

You should use strtok to split line into tokens, example:

char *tok;
tok = strtok(Line, " "); // this is your String (first token in line)

tok = strtok(NULL, " "); // skip to next token (first number)
while (tok != NULL)
{
    printf("%s\n", tok); // use sscanf on tok to handle the numbers
    tok = strtok(NULL, " "); // skip to next token
}
david72
  • 7,151
  • 3
  • 37
  • 59
  • With this approach, how do I get access to the string in order to validate that I'm on the correct line in my text file? – m_power Sep 11 '19 at 19:58