Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!usc!snorkelwacker.mit.edu!bloom-picayune.mit.edu!athena.mit.edu!jik From: jik@athena.mit.edu (Jonathan I. Kamens) Newsgroups: comp.unix.programmer Subject: Re: sscanf always generates error condition Message-ID: <1991May1.050122.21795@athena.mit.edu> Date: 1 May 91 05:01:22 GMT References: <1991Apr30.233554.1321@agate.berkeley.edu> Sender: news@athena.mit.edu (News system) Distribution: usa Organization: Massachusetts Institute of Technology Lines: 41 In article <1991Apr30.233554.1321@agate.berkeley.edu>, ilan343@violet.berkeley.edu (Geraldo Veiga) writes: |> #include |> extern int errno; |> char s[] = "10000"; |> main () |> { |> int tmp; |> sscanf(s,"%d",&tmp); |> perror("System error"); |> } You are violating two rules of Unix programming here. First of all, system calls are allowed to set errno to whatever they want, even if they return successfully. The only time you are supposed to check errno is if a library function has signaled to you that it is returning abnormally. Therefore, the body of your program should be replaced by: int tmp, retval; retval = sscanf(s, "%d", &tmp); if (retval == EOF) { fprintf(stderr, "Short string.\n"); else if (retval != 1) { perror("System error"); Remember that sscanf returns the number of variables assigned, or EOF on end of file (or, in the case of sscanf, a short string) or file error. Second, technically speaking, the only time errno is relevant is when a system call fails. This means that, in the strictest sense, it is not valid to use errno to find out what error occurred after a library function fails. However, in cases where you know that the library function failed because of a failed system call, it's a good bet that errno will still contain the error return value from the system call, so it's usually OK to use it to determine what happened. -- Jonathan Kamens USnail: MIT Project Athena 11 Ashford Terrace jik@Athena.MIT.EDU Allston, MA 02134 Office: 617-253-8085 Home: 617-782-0710