0

I have this file with multiple lines. Each line follows a format of

`userID:$An Integer$$String:`

For example:

pyc1:$1$$Tnq7a6/C1wwyKyt0V/.BP/:
pyc2:$6$$Tnq7a6/C1wwyKyt0V/.BP/:

How should I use fscanf() to retrieve the userID, the integer, and the string between $$ and :`?

This is what I have now, but it is not working.

int main(){
    FILE * file = fopen("shadow.txt", "r");
    char line[256] = {0};
    char userID[30] = {0};
    int hashType;
    char hash[256] = {0};
    int result = fscanf(file, "%s :$ %d $$ %s :", userID, &hashType, hash);
    printf("%s\n", userID );
    printf("%d\n", hashType );
    printf("%s\n", hash );

}

I don't know much about the format I should specify for fscanf() to achieve this. Please help.

8
  • Does the line end at the colon? Commented Dec 7, 2017 at 13:34
  • @unwind the line in the file end with a carriage return Commented Dec 7, 2017 at 13:38
  • 2
    What does "not working" mean? Commented Dec 7, 2017 at 13:39
  • 1
    @MadPhysicist The userID, Integer and hash is not scanning into the variables. It appears as the whole line from the file is scanned into userID Commented Dec 7, 2017 at 13:44
  • Why is that not part of your question ? Commented Dec 7, 2017 at 15:11

2 Answers 2

3

Try a regex, like this for example:

fscanf (file, "%[^:]:$%d$$%[^:]:", userID, &hashType, hash);

I created a regex101 link that explains the regex expression used above.


PS: Don't forget to check for the return value of fscanf(), in order to ensure that everything was read parsed correctly. You want to parse three elements, thus the return value should be 3.

Sign up to request clarification or add additional context in comments.

5 Comments

Thank you so much. It works. So my understand for %[^:] is it will scan in any character except for : Is that correct?
Does all the regex rules can be applied inside %[]? Such as * for any number of characters
There are many things you can do with a regex expression @Anlinyang. Play around with it in the link I posted, if you like!
the '%[^:]' will input any characters, but will stop (and not input) the ':' when a ':' is encountered
this fails to check the returned value from fscanf(), so errors can occur and the code would not catch those errors. Strongly suggest checking the returned value against 3. Any other returned value means an error occurred
0

Try this:

while(ret = fscanf(file," %[^:] : $ %d $$ %[^:] :",userID,&hashtype,hash))
{

    if(ret == EOF)
    {
        break;
    }

    printf("value of ret: %d\n",ret);
    printf("%s , %d , %s",userid,id,str);

    // . . .

}

here, int ret is:

  • EOF, if the pointer is reached end of file.
  • 0, if no input matched with the variable
  • >0, number of matched variables with the file input

1 Comment

the correct value to be checking as returned from fscanf() is (in the current scenario) 3. There are other error events possible besides EOF

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.