c - Multiple fscanf -
i have written following program intended read string file variable "title":
#include <stdio.h> #include <stdlib.h> int main() { int m, b; char *title; file *fp; fp = fopen("input2.txt", "r"); if (fp == null) { printf ("error: file cannot found\n"); return 1; } fscanf(fp, "<%d>\n<%d>", &m, &b); printf("%d\n%d", m, b); fscanf(fp, "<%s>", title); fclose(fp); return 0; } the above program crashes @ second call fscanf. why happen?
your main problem you've not allocated space string read into. can in multiple ways:
char title[256]; or:
char *title = malloc(256); if (title == null) { fprintf(stderr, "out of memory\n"); exit(1); } either of should used with:
if (fscanf(fp, " <%255[^>]>", title) != 1) { fprintf(stderr, "oops: format error\n"); exit(1); } or, if have system implementation of fscanf() that's compliant posix 2008, can use m modifier %s (or %c, or, in case, scanset %[...] — more on below):
char *title = 0; if (fscanf(fp, " <%m[^>]>", &title) != 1) // note crucial & { fprintf(stderr, "oops: format error\n"); exit(1); } this way, if fscanf() succeeds in entirety, function allocate memory title. if fails, memory have been released (or never assigned).
note changed %s %m[^>]. necessary because original conversions never match >. if there > in input, incorporated result string because reads white space, , > not white space. further, won't able tell whether trailing context ever matched — that's > in original format, , it's still problem (or not) in revised code i'm suggesting.
i added space @ start of string match optional white space. without that, < @ start of string must on same line > after second number, assuming > present @ all. should check return first fscanf():
if (fscanf(fp, "<%d>\n<%d>", &m, &b) != 2) { fprintf(stderr, "oops: format error\n"); exit(1); } note embedded newline looks white space between > , < — that's 0 or more blanks, tabs or newlines. note you'll never know whether second > matched or not.
you use exit(exit_failure); in place of exit(1); — or, since code in main(), use either return 1; or return(exit_failure); parentheses optional in either case presence evokes unwarranted ire in people.
you improve error messages. , should consider using fgets() or posix's getline() followed sscanf() because makes easier (by far) error reporting, plus can rescan data if first attempt @ converting fails.
Comments
Post a Comment