2

Here is the text file

Username:user1  Password:pass1
Username:user2  Password:pass2

I want to read the username and password from the text. the problem is there is not way to change the format of the text. i tried to read but as there is not space between colon(:), it gives whole username:user1 as string but i want only user1. i referred to this question but it did not help as there is no space between colon.

I tried :

 while ((fscanf(fp,"Username:%s Password:%s",username,password))!=EOF)

but it gives many undefined characters after user1 and loop never ends.

Jay Joshi
  • 868
  • 8
  • 24
  • 1
    You should consult the relevant documentation about the meaning of `fscanf()`s return value. – EOF Nov 15 '17 at 10:07

2 Answers2

1

Try the following code:

#include <stdio.h>
#include <string.h>

int main (int argc, char *argv[])
{
    char username[128];
    char password[128];
    FILE *fp;
    int ret;

    fp = fopen("read.txt", "r");
    if (!fp) {
        printf("Failed to open a file\n");
        return 1;
    }

    while (1) {
        ret = fscanf(fp, "Username:%s Password:%s\n",username,password);
        if (ret == EOF)
            break;
        if (ret == 2)
            printf("%s %s\n", username, password);
        else {
            printf("%d\n", ret);
            perror("fscanf:");
            break;
        }
    }

    fclose(fp);
    return 0;
}
Prabhakar Lad
  • 1,248
  • 1
  • 8
  • 12
  • 2
    `fscanf(fp, "Username:%s Password:%s\n",username,password)` -- note that it is bad practice to use trailing whitespace characters in `scanf()` format strings. Since the input is from a file, this will work as expected, but this is a common error when using `scanf()` for interactive input where it causes problems. Better to place a space at the beginning of the format string to consume previous newline characters: `fscanf(fp, " Username:%s Password:%s",username,password)`. – ad absurdum Nov 15 '17 at 10:29
  • 1
    Also, maximum widths should be specified when reading strings using `%s` or `%[]` to avoid buffer overflow: `fscanf(fp, " Username:%127s Password:%127s",username,password)`. – ad absurdum Nov 15 '17 at 10:33
  • why you checked ret value to be 2 ? in if(ret == 2) ? – Jay Joshi Nov 15 '17 at 10:36
  • 2
    @JayJoshi you need to look at fscanf function return value: On success, these functions return the number of input items successfully matched and assigned; this can be fewer than provided for, or even zero, in the event of an early matching failure. The value EOF is returned if the end of input is reached before either the first successful conversion or a matching failure occurs. EOF is also returned if a read error occurs, in which case the error indicator for the stream (see ferror(3)) is set, and errno is set to indicate the error. – Prabhakar Lad Nov 15 '17 at 10:38
  • 1
    @PrabhakarLad -- "EOF is also returned if a read error occurs, in which case the error indicator for the stream (see ferror(3)) is set, and errno is set to indicate the error. " Note that this is not in the Standard, but is a POSIX extension. – ad absurdum Nov 15 '17 at 11:03
  • @DavidBowling thank you that was more clearer explanation. – Prabhakar Lad Nov 15 '17 at 11:20
  • the call to `printf()` modifies the value of `errno`. so the first couple of lines of the read loop should be: `while (1) { if( 2 != fscanf(fp, " Username:%127s Password:%127s", username, password ) ) { perror( "fscanf failed" ); fclose(fp); exit( EXIT_FAILURE ); } // implied else, fread successful printf("%s %s\n", username, password); }` – user3629249 Nov 16 '17 at 10:38
0

I would use this algorithm:

  1. Read while char read isn't ':'

  2. Start storing all next chars on username var while the char read is !=' '

  3. Remove the last space on the username string

  4. Repeat step 1.

  5. Same as step 2 but now we store the read data on password value while the read char is != ''\n'

  6. Repeat while ! end of file