开发者

Strange segfault in C

开发者 https://www.devze.com 2023-04-09 10:05 出处:网络
Ok, so I\'m not really sure what is going on here.I have a simple function, int foo(char *filename), that takes filename and counts the words in a file.

Ok, so I'm not really sure what is going on here. I have a simple function, int foo(char *filename), that takes filename and counts the words in a file.

int foo(char *filename){

  FILE *inFile;
  int wordCount = 0;    

  printf("foo\n"); // test printf() statement (currently prints)

  char word[50];
  inFile = (&filename, "r");

  printf("infile\n");  // test printf() statement (currently prints)

  while (1){
    printf("while");   // test printf() statement (doesn't print)
    fscanf(inFile, "%s", word);
    if (feof(inFile))
        break;
    printf("%d", wordCount); //test printf() statement
    wordCount++;
  }
  f开发者_运维技巧close(inFile);
  return wordCount;

}

As you can see, I print "infile", but not "while". I get a segmentation fault. Does anyone have any idea why this doesn't work Also, is my inFile = (&filename, "r"); statement correct? I'm not that great with pointers.


I'm surprised this line actually compiles:

inFile = (&filename, "r");

If you're trying to open a file:

inFile = fopen(filename, "r");

EDIT:

And as mentioned, you need to end your printfs with \n or call fflush(stdout) or it will get buffered and not print.


What are you expecting this line to do?

inFile = (&filename, "r");

Because it looks like you're missing a functional call. I suspect you wanted something like this:

inFile = fopen(filename, "r");

That is, the fopen function expects a character pointer, and you have this:

int foo(char *filename){

So you don't need to use the & operator. The & operator returns the address of a variable, so by entering &filename you're ending up with (a pointer to (a pointer to (char)). You'll rarely use the & operator with strings; you'll usually see it used when a function needs to return multiple values (like the Unix wait() function).

There are a number of tutorials out there that talk about C pointers in more detail; a Google search for "c pointers" yields some likely results. And of course, read your K&R :).


The reason you don't see the "while" print is because it's not terminated with \n, thus is kept in the buffer and not printed out, by the time the seg fault occurs.

The seg fault occurs at fscanf, because you missed the fopen, and messed up your pointers. @Mystical explained how to fix it.


ALWAYS check the return value from fopen(), the call to which seems to be missing.

FILE *inFile = fopen(filename, "r");
if (inFile == 0)
    ...diagnose error...do not use inFile...

Note the absence of the & from filename in the call to fopen(); you simply don't need it.

The printf() before the fscanf() does not produce anything because the output string does not end with a newline; it is held over until you do print a newline, and the crash occurs before you do that.

The crash occurs because the string "r" is not a valid file stream; if you'd actually called fopen(), it would probably be because the open failed and you did not check it.

If your compiler did not give you warnings about the code, get a better compiler. If it did give you warnings, learn to heed them (and fix them) before posting to StackOverflow.


While you're at it, you might want to consider what happens if the word you get to read is 50 characters or longer. Happiness does not ensue. You should consider using:

while (fscanf("%49s", word) == 1)
    wordCount++;

If a word is longer than 49 characters, it will at least now be split up into some number of 49-byte units (each counted as a word) without giving you buffer overflow problems (another source of crashes). If you need a diagnostic print in the loop, so be it; add the braces and print.

I have very, very seldom had cause to use feof() in my (25+ year) programming career. Code using it is generally suspect; I wonder if the person learned Pascal and hasn't unlearned it when learning C.

0

精彩评论

暂无评论...
验证码 换一张
取 消