Thread: Segmentation fault( counts number of words program )

  1. #1
    Registered User
    Join Date
    Apr 2011
    Posts
    48

    Segmentation fault( counts number of words program )

    Hi,
    I solved question but somehow it gives Segmentation fault...
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <ctype.h>
    int main(void)
    {
    	char ch, *string[10];
    	int i = 0,j, words = 0, one = 0, two = 0,three = 0, four = 0, five = 0,\
    six = 0,seven = 0, eight = 0;
    	FILE *inp;
    	inp = fopen("text.dat", "r");
    	if(inp == NULL)
    		printf("text.dat cannot be opened");
    	while(fscanf(inp,"%c",&ch) == 1){
    		//fscanf(inp,"%c",&ch);
    		if(isspace(ch) == 0){
    			fscanf(inp, "%s", string[i]);
    			i++;
    			words++;
    		}
    	}
    	for(j = 0;j <= words;++j){
    		if( strlen(string[j]) == 1)
    			one++;
    		else if( strlen(string[j]) == 2)
    			two++;
    		else if( strlen(string[j]) == 3)
    			three++;
    		else if( strlen(string[j]) == 4)
    			four++;
    		else if ( strlen(string[j]) == 5)
    			five++;
    		else if ( strlen(string[j]) == 6)
    			six++;
    		else if ( strlen(string[j]) == 7)
    			seven++;
    		else if ( strlen(string[j]) == 8)
    			eight++;
    	}
    	printf("%d words, one letter = %d, two letter = %d, three letter = %d,\
    four letter = %d, five letter = %d, six letter = %d, seven letter = %d,\
    eight letter = %d", words, one, two, three, four, five, six, seven, eight);
    	fclose(inp);
    	return(0);
    	}
    text.dat
    Even though she stands only 3 feet 9 inches tall, Judy Lohden has a big voice. And we're not just talking about her singing, which fills the school auditorium and wows audiences. What we love is her wry, funny narrative voice, which grabs readers and guides them through the intricate social hierarchies of cafeteria and classroom as only an outcast truly can. From the author of the hilarious memoir, Foreign Babes in Beijing, this is a novel that's filled with wit, yearning, and unforgettable character.
    and gdb says(I don't know how to use gdb)
    (gdb) run
    Starting program: /home/mustafa/Documents/My_C_Programs/Programming_Projects/CHAPTER9/3

    Program received signal SIGSEGV, Segmentation fault.
    __isoc99_fscanf (stream=0x0, format=0x80488b8 "%c") at isoc99_fscanf.c:31
    31 isoc99_fscanf.c: No such file or directory.
    in isoc99_fscanf.c

  2. #2
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Code:
    	inp = fopen("text.dat", "r");
    	if(inp == NULL)
    		printf("text.dat cannot be opened");
    	while(fscanf(inp,"%c",&ch) == 1){
    It looks like the file failed to open. You do check to see if the open failed by checking inp against NULL (which is good!), but you don't abort the process when it fails, so it just falls through to start your while() loop even when the file open failed. Try:
    Code:
    if(inp == NULL)
    {
      printf("text.dat cannot be opened");
      return 1;
    }
    That should stop that segmentation fault anyway. To fix your actual problem, make sure text.dat is in your current working directory (i.e. If you type 'ls', text.dat should be listed there.)
    If you understand what you're doing, you're not learning anything.

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > fscanf(inp, "%s", string[i]);
    Where do these point?

    > char ch, *string[10];
    They're not pointing anywhere.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Problems:
    1. You check if inp is NULL, but if it is, you still try to read from the file. You need to exit if that happens.
    2. You try to read into string[i], but string[i] is only a char *, there's no memory there to hold what you read.
    3. You only declared string to have 10 elements, but there are way more than 10 words in your text.dat file. You don't even need this array, just make a single char array, word[100], and fscanf into that. Then, do a strlen and record how many letters.
    4. You can simplify your read loop. fscanf with a "%s" will read a word, stopping at the white space. The next such call will skip all the white space and give you the next word. No need for your isspace() business.
    5. You should combine one, two, three, etc into an array, and do something like count_array[strlen(s)]++. Just make sure strlen(s) wont go out of bounds of your array first.

  5. #5
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    int i = 0,j, words = 0, one = 0, two = 0,three = 0, four = 0, five = 0,\
    six = 0,seven = 0, eight = 0;
    You're kidding right? These are like the worst variable names *everrrrrr*.

    Seriously you need to either A) using meaningful variable names or B) make groups of variables into an array with a meaningful name.

    Plus there's a much simpler way to count words... just scan the file and count spaces... Look up isspace() in your library documentation.

  6. #6
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by CommonTater View Post
    Plus there's a much simpler way to count words... just scan the file and count spaces... Look up isspace() in your library documentation.
    He's counting word lengths, not words, if I understand the code correctly...

  7. #7
    Registered User
    Join Date
    Apr 2011
    Posts
    48
    Quote Originally Posted by itsme86 View Post
    Code:
    	inp = fopen("text.dat", "r");
    	if(inp == NULL)
    		printf("text.dat cannot be opened");
    	while(fscanf(inp,"%c",&ch) == 1){
    It looks like the file failed to open. You do check to see if the open failed by checking inp against NULL (which is good!), but you don't abort the process when it fails, so it just falls through to start your while() loop even when the file open failed. Try:
    Code:
    if(inp == NULL)
    {
      printf("text.dat cannot be opened");
      return 1;
    }
    That should stop that segmentation fault anyway. To fix your actual problem, make sure text.dat is in your current working directory (i.e. If you type 'ls', text.dat should be listed there.)
    ls --all
    . .. 1 1.c 2 2.c 3 3.c text.dat
    text.dat is in same directory.But somehow it can't be read.
    And also I added this to my code.
    Code:
    if(inp == NULL)
    {
      printf("text.dat cannot be opened");
      return 1;
    and it says just like you said
    Starting program: /home/mustafa/Documents/My_C_Programs/Programming_Projects/CHAPTER9/3
    text.dat cannot be opened
    How can I solve this problem.Because everything is right.

  8. #8
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Look into the perror function for getting a message that tells why the file can't be opened. Try a 'ls -l' to see each file with it's ownership and permissions.

  9. #9
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Then either:
    A) The current working directory is not /home/mustafa/Documents/My_C_Programs/Programming_Projects/CHAPTER9/3.
    B) You have some sort of file permissions issue.

    The current working directory is not necessarily going to be the same as the the directory in which the executable resides. For instance, the ls command is in /bin, but I can execute it if I'm currently in the /home/mustafa directory. So if I'm in /home/mustafa, and I type "ls text.dat", it's not going to find it if text.dat is in /bin with the ls executable.

    Quote Originally Posted by paranoidgnu
    How can I solve this problem.Because everything is right.
    You're going to have to abandon that idea, because obviously, if everything was right, you wouldn't be having a problem.
    Last edited by itsme86; 05-12-2011 at 10:55 AM.
    If you understand what you're doing, you're not learning anything.

  10. #10
    Registered User
    Join Date
    Apr 2011
    Posts
    48
    Quote Originally Posted by anduril462 View Post
    Look into the perror function for getting a message that tells why the file can't be opened. Try a 'ls -l' to see each file with it's ownership and permissions.
    -rw-rw-rw- 1 mustafa mustafa 507 2011-05-12 18:55 text.dat
    @Commontater
    You are right I have to be more rigorous, but it's just a question from a book.And I'm a beginner

  11. #11
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Okay...instead of using printf to get an error messages, use perror, like so:
    Code:
    perror("Couldn't open file text.dat: ");
    It will print out the text you provided followed by a more descriptive error message. I'm guessing, like itsme86 said, it's a working directory thing, since your ownership and permissions look fine. Make that change, then give us the output of the following commands:
    Code:
    $ pwd
    $ gcc -Wall 3.c
    $ ls -l
    $ ./a.out

  12. #12
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by paranoidgnu View Post
    @Commontater
    You are right I have to be more rigorous, but it's just a question from a book.And I'm a beginner
    There is no excuse for poor craftsmanship...
    Really... start good habits now, so you don't spend half your time fixing the bad ones later on.

  13. #13
    Registered User
    Join Date
    Apr 2011
    Posts
    48
    Quote Originally Posted by CommonTater View Post
    There is no excuse for poor craftsmanship...
    Really... start good habits now, so you don't spend half your time fixing the bad ones later on.
    Thanks for your advices CommonTater.I will be more rigorous and careful.Anyway I have to be what you have said.You are right.

    Now, gdb says;

    Program received signal SIGSEGV, Segmentation fault.
    0xb7eb1b05 in _IO_vfscanf_internal (s=Cannot access memory at address 0xffffffff
    ) at vfscanf.c:1053
    1053 vfscanf.c: No such file or directory.
    in vfscanf.c
    I changed file name.But nothing changed..

  14. #14
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    OK, so which of the other uninitialised variables pointed out to you are still uninitialised?

    Post your latest code.

    The next useful command in gdb is 'bt', to show you how it got to the segfault, and which call from YOUR code is responsible.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  15. #15
    Registered User
    Join Date
    Apr 2011
    Posts
    48
    @Salem,
    Latest code, nearly same as previous.
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <ctype.h>
    int main(void)
    {
    	char ch, *string[100];
    	int i = 0,j, words = 0, one_word = 0, two_word = 0, three_word = 0,\
    four_word = 0, five_word = 0, six_word = 0, seven_word = 0, eight_word = 0;
    	FILE *inp;
    	inp = fopen("metin.text", "r");
    	if(inp == NULL)	{
    		printf("metin.text cannot be opened");
    		return 1;
    	}	
    	while(fscanf(inp,"%c",&ch) == 1){
    		//fscanf(inp,"%c",&ch);
    		if(isspace(ch) == 0){
    			fscanf(inp, "%s", string[i]);
    			i++;
    			words++;
    		}
    	}
    	for(j = 0;j <= words;++j){
    		if( strlen(string[j]) == 1)
    			one_word++;
    		else if( strlen(string[j]) == 2)
    			two_word++;
    		else if( strlen(string[j]) == 3)
    			three_word++;
    		else if( strlen(string[j]) == 4)
    			four_word++;
    		else if ( strlen(string[j]) == 5)
    			five_word++;
    		else if ( strlen(string[j]) == 6)
    			six_word++;
    		else if ( strlen(string[j]) == 7)
    			seven_word++;
    		else if ( strlen(string[j]) == 8)
    			eight_word++;
    	}
    	printf("%d words, one letter = %d, two letter = %d, three letter = %d,\
    four letter = %d, five letter = %d, six letter = %d, seven letter = %d,\
    eight letter = %d", words, one_word, two_word, three_word, four_word,\
    five_word, six_word, seven_word, eight_word);
    	fclose(inp);
    	return(0);
    	}

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. C Program that counts total prime number?
    By exe101 in forum C Programming
    Replies: 2
    Last Post: 04-07-2009, 01:18 AM
  2. words counts
    By lingz82 in forum C++ Programming
    Replies: 3
    Last Post: 08-31-2006, 05:16 AM
  3. Segmentation fault on my program
    By blackswan in forum C Programming
    Replies: 2
    Last Post: 05-11-2005, 04:47 PM
  4. Segmentation fault in beginning or program
    By tameeyore in forum C Programming
    Replies: 1
    Last Post: 02-26-2005, 08:16 PM
  5. Segmentation fault !, program works:S
    By jspri in forum C Programming
    Replies: 8
    Last Post: 09-28-2004, 05:25 PM