开发者

File I/O difficulties in C

I'm writing a version of the Unix expand utility that replaces tabs with spaces in a file. To do this, I'm reading in each character and testing if it is a tab character. If it is, it replaces the tab with the given amount of spaces, otherwise the character gets printed.

My main method goes like

int main(int argc, char *argv[]){
 FILE *fp;

 char *help1="-help";
 char *help2开发者_开发百科= "--help";

 //int spaces; //number of spaces to replace tabs

 fp= fopen(argv[1], "rw");
 parse_file(fp, 4);
 fclose(fp);

 return 0;
}

the parse_file method goes like

void parse_file(FILE *fp, int spaces)
{
  int i; //loop counter
  char c; //current character
  while (c!= EOF)
{
    c= getchar(); //get char from stream

    if (c=='\t') //if char is a tab
    {
        for (i=0; i< spaces; i++)
            putchar(" "); //replace with spaces

    } 
    else 
        putchar(c); //otherwise, print the character

}

}

When compiling, I get an integer from pointer without cast warning for putchar(" "); and the program hits a segfault when executing.

So, my questions:

1- What is the warning "makes integer from pointer without cast" all about? What can I do to resolve it?

2- The code generates a segfault on execution with a text file passed in as an argument. Is there anything in this code that would cause that?


you must use

putchar(' ')

instead

putchar(" ")


  1. You're calling putchar on a string (" "), but it wants a char argument (' '). (Actually an int, but only passing a char is safe.)

  2. The segfault is probably due to the fclose on fp, which may be NULL. You should check the return value from fopen. The reason you only notice after parse_file is that it doesn't touch fp at all (it reads from stdin and writes to stdout). To use the stream fp, you should use getc(fp) and putc(fp) instead. (That still won't work because you'd overwrite the stream with more data than you're reading from it, so you'll get garbage out.)

In fact, the program is sure to segfault when no command line argument is given. Either fopen segfaults because it is handed the null pointer argv[1], or it returns a null pointer itself.

When writing these kinds of programs, please adhere to the Unix philosophy and write them as filters: read from stdin, write to stdout. Don't modify a file in-place if you don't have to.


In C string literals are of type char *, a pointer to some area containing string characters. " " is a string literal, not a character. Use ' ' when you need a single character


As everyone else says, re. The use of char vs. string. As for the logic behind the actual error message you see, the string is a pointer to a const array of characters. Hence the error is saying it is converting the pointer to an int. Most of the char functions work with ints.


To summarise the issues (I'm repeating stuff other people have said, but issues 5 and 6 havehas not been mentioned so far):

  1. putchar() does not take a string pointer as an argument but an int - the constant ' ' is an acceptable parameter
  2. you don't check that argc > 1 before using argv[1]
  3. you don't check that fopen() successfully opens the file
  4. c should be defined as an int since in some character sets (char) -1 (0xFF) is a legitimate character and also the comparison c == EOF may fail if c is not sign extended
  5. The first time through the loop c is used uninitialised and in the loop you also treat EOF as a normal character. The normal idiom in C programs is

    int c;
    while ((c = fgetc(fp)) != EOF)
    { 
        // do stuff with c
    }
    
  6. You are getting your characters from stdin and not fp hence use fgetc() not getchar()

I think that covers everything.

To answer your explicit question, you get the warning "makes integer from pointer without cast" when an int is expected but you use a pointer (in this case the type of " " is const char*).


In addition to what has already been said, getchar() returns int not char. EOF is an int constant. You will need to read the result from getchar() into an int, check for EOF, and if not found, cast the int into a char.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜