giozh
giozh

Reputation: 10068

compare string acquired with fgets and fscanf

i need to compare a string acquired from stdin by fgets, with onother one acquired from file by fscanf (and write on file with fprintf). I necessarily have to use the two functions for read from stdin and file. How i can do that? because i've see that fgets store also "\0" byte, but fscanf no.

this is the code:

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

typedef struct asd {
    char a[20];
    char b[20];
} struttura;


void stampa_file() {
struttura *tmp = NULL;
struttura *letto = NULL;
FILE *file;

tmp = (struttura *)malloc(sizeof(struttura));
letto = (struttura *)malloc(sizeof(struttura));
file = fopen("nuovoFile", "r");
printf("compare:\n");\
fgets(letto->a, sizeof(letto->a), stdin);
fgets(letto->b, sizeof(letto->b), stdin);
while(!feof(file)) {
    fscanf(file, "%s %s\n", tmp->a, tmp->b);
    printf("a: %s, b: %s\n", tmp->a, tmp->b);
    if(strcmp(letto->a, tmp->a) == 0 && strcmp(letto->b, tmp->b)) {
        printf("find matching\n");
    }
}
free(tmp);
free(letto);
}

int main() {
struttura *s = NULL;
FILE *file;

s = (struttura *)malloc(sizeof(struttura));

file = fopen("nuovoFile", "a+");
printf("");
fgets(s->a, sizeof(s->a), stdin);
printf("");
fgets(s->b, sizeof(s->b), stdin);
fprintf(file, "%s%s\n", s->a, s->b);
fclose(file);
stampa_file();

free(s);
return 0;
}

Upvotes: 0

Views: 1996

Answers (3)

Chris Dodd
Chris Dodd

Reputation: 126195

Lots of potential issues here depending on what you are trying to do

  • fgets reads a line (up to and including a newline) whereas fscanf(.."%s"..) reads a token delimited by whitespace. Not at all the same thing.

  • fscanf(.."%s"..) doesn't check the bounds on the buffer you give it to write to. You really want fscanf(.."%19s"..) to ensure that it doesn't write more than 20 bytes (including the NUL terminator) to your 20 byte buffer.

  • while(!feof(fp)) is almost always wrong. feof doesn't tell you if you're at the end of the file, it tells you if you've tried to read past the end of the file. So if you've just read to the end of the file and haven't yet read past it, feof will return false, but the next read will fail.

  • You really want to check the return value of fscanf to make sure it read what you wanted it to read (and actually wrote something to the output buffers.) Combined with the above, it means you probably want your loop to be something like:

    while (fscanf(fp, "%19s%19s", tmp->a, tmp->b) == 2) {
            :
    

Upvotes: 2

fkl
fkl

Reputation: 5535

scanf or fscanf when passed with %s terminates the string on newline OR space char. Where as fgets waits until the \n.

Hence if you call

fscanf(stdin, "%s", str);

vs

fgets(str);

and the file contains "Hello there"

fscanf would only contain "Hello" where as fgets would return the entire string

Upvotes: 0

user529758
user529758

Reputation:

How i can do that? because i've see that fgets store also "\0" byte, but fscanf no.

I just read the documentation for fscanf and tested it, and this worked fine:

#include <stdio.h>

int main()
{
    char str[100] = { 1 }; // intentionally initialized to nonzero junk
    fscanf(stdin, "%s", str);
    if (strcmp(str, "H2CO3") == 0)
        printf("This is me\n");
    else
        printf("This is not me\n");
    return 0;
}

Upvotes: 0

Related Questions