954,480 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

help on 'Segmentation Fault'

i just would like to ask for help regarding my code... my problem is this... the user must enter an 80-digit number...if he enters more than 80 digits, the error "\007Input number must not exceed a total of %d digits\n" will appear setting the iserror flag to 1 and breaking the for loop. then if iserror==1, it will execute the line "continue" so that the user may enter a new number... the previous number he entered is no longer valid...

the problem is, after the program prints "Enter number 1: " to take a NEW input from user, the getchar function gets the number immediately after the 80th number which the user previously entered... i wonder how can i be cleared of the previous number the user entered so that when asked again to enter number 1, the getchar will get the char starting from the first digit of the NEW input number.

while(isvalid==0){
        iserror=0;
        printf("Enter number 1: ");
        ch=getchar();
        /*check if no input for number 1*/
        if(ch=='\n'){
            printf("\007Please input an integer up to 80 digits\n");
            continue;
        }
        /*check if input for number 1 exceeds maximum digit count*/
        if(ch=='-'){/*signed input number 1*/
            signednum1=1;
            for(n=0;n<=MAXDIGITCOUNT,ch!='\n';n++){
                ch=getchar();
                if(n==MAXDIGITCOUNT && ch!='\n'){
                    printf("\007Input number must not exceed a total of %d digits\n",MAXDIGITCOUNT);
                    iserror=1;
                    break;
                }
                if(n<MAXDIGITCOUNT && ch!='\n'){
                    num1[n]=ch;
                    len1=n+1;
                }
            }
            if(iserror==1){
                continue;
            }
        }
        if(iserror==1){
            isvalid=0;
        }
        else
            isvalid=1;
    }
zeek
Newbie Poster
9 posts since Jul 2005
Reputation Points: 10
Solved Threads: 0
 

Just clear the stream of extra characters. You can use this function:

void discard ( FILE *in )
{
  int c;

  while ( ( c = fgetc ( in ) ) != EOF && c != '\n' )
    ;
}
Narue
Bad Cop
Administrator
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
 

Couldn't you flow control (with an if statement) the entry? Once you have 80 digits, you switch over to the second number so any overage is automatically put into the second number.

Would that work, or am I not understanding the problem correctly?

Drowzee
Posting Whiz in Training
245 posts since Jul 2005
Reputation Points: 22
Solved Threads: 5
 

actually, i am creating a program to add 2 large-digit numbers up to 80... first you input number 1 (which can be up to 80 digits) next you input number 2 (also can be up to 80 digits)...
when the user enters greater than 80 digits for number 1, the remaining numbers beyond the limit of 80 must be discarded...

i have to prompt the user that he enters more than 80 digits and i have to prompt him again to enter "input number 1:"... wherein in my program it continues on running (getting the remaining digits previously entered because of getchar) and executing "input number 2:" without giving the user the chance to input a new number for number 1... (NOTE: i did not place the code for "input number 2:" in the question)

mr. narue... i am still new in c programming... can you pls explain the code (and where i should to place it) because as i understand it, i have to open a file... i'm sorry sir but i still have little knowledge in C. hope you understand thanks

zeek
Newbie Poster
9 posts since Jul 2005
Reputation Points: 10
Solved Threads: 0
 

Just clear the stream of extra characters. You can use this function:

void discard ( FILE *in )
{
  int c;

  while ( ( c = fgetc ( in ) ) != EOF && c != '\n' )
    ;
}


DID YOU KNOW THAT:
The c-defined 'stdin' that takes the input directly from the keyboard is compatible with (if not a direct type of) FILE* ?

AND NOW YOU KNOW!

What's going on here? I'll walk you through it.

void discard ( FILE *in ) //1
{
  int c;//2

  while ( ( c = fgetc ( in ) ) != EOF)  && c != '\n' )  //3
    ;
}


Okay, here goes:
1. The function name and accepted parameters. In this case, you'll want to call:

discard(stdin);

when you want to clear the input stream of excess characters.
You'd call it after you get 80 digits.

2. This is the digit you want to get in for your input.

3. This while loop does everything in the declaration of the while loop.
Its first argument, ((c = fgetc(in)) != EOF), does two things:
First, it calls the fgetc function and returns an integer value, which is stored in the variable 'c'. The parenthesis around

(c=fgetc(in))

are to help both you and the compiler realize that the fgetc function and assignment should be called first.
Second, it compares the value of 'c' to the defined value of the end of file character (abbreviated as EOF). If 'c' has the value of EOF, the while loop exits.
That's what the !=EOF does.

{Note: "in" is the reference the function uses instead of stdin, the keyboard input. It's the same thing, just renamed for the discard function.}

The second argument in the while loop,

c != '\n'

Compares the value of c (taken in the first argument) to the value of the "newline" character. When using stdin, this translates to a press of the enter key.

The two arguments for the while loop are joined by the logical AND operator, &&. That means that as long as both conditions(c can't be the end of file and c can't be a new line) are met, any key press is discarded. Only pressing enter can break the loop.

So, once you've got your 80 digit entries, you call the discard function with stdin as the argument, and anything that's not an enter will be assigned and overwritten without getting into the numbers you want to preserve. Once enter is pressed, the discard function exits, and you can start entering the second 80 digit number.

Drowzee
Posting Whiz in Training
245 posts since Jul 2005
Reputation Points: 22
Solved Threads: 5
 

Various pieces have been presented and discussed already. Here's how I might piece some things together.

#include <stdio.h>

char *getline(char *dst, size_t size)
{
   size_t i = 0;
   for ( ;; )
   {
      int ch = getchar();
      if ( ch == '\n' || ch == EOF )
      {
         break;
      }
      dst[i] = ch;
      if ( ++i >= size - 1 )
      {
         printf("input may not exceed %lu digits\n", (long unsigned)(size - 1));
         break;
      }
   }
   dst[i] = '\0';
   return dst;
}

void input(char *number, size_t size)
{
   printf("enter a %lu-digit number: ", (long unsigned)(size - 1));
   fflush(stdout);
   getline(number, size);
   printf("number = \"%s\"\n", number);
}

int main(void)
{
   char number[10];
   input(number, sizeof number);
   return 0;
}

/* my output
enter a 9-digit number: 1234567890
number = "123456789"

enter a 9-digit number: 1234567890123
input may not exceed 9 digits
number = "123456789"
*/


As an aside,'\007' can be expressed as '\a' to be more standard.

Dave Sinkula
long time no c
Team Colleague
5,058 posts since Apr 2004
Reputation Points: 2,780
Solved Threads: 314
 

thanks to you guys but i have a new problem:

the user is prompt to enter number 1 and then number 2.
i declared two arrays to handle each digit...

char num1[ MAXDIGITCOUNT ];
	char num2[ MAXDIGITCOUNT ];

in my program, i will passed the contents of these arrays to a function called 'addition' but before i do that i decided to convert first each content of the arrays into integer. I first declare two arrays to handle the converted numbers:

int inum1[ MAXDIGITCOUNT ]; 
	int inum2[ MAXDIGITCOUNT ];

then i do this:

for( n = 0; n < len2; n++ ) {
        inum2[ n ] = atoi( num2[ n ] );
   }

and i received this message:
[Warning] passing arg 1 of 'atoi' makes pointer from integer without a cast

then i write the function 'addition' as:

void addition(int _num1, int _num2,...){
                s1 = _num1[ _len1]; 
     }

and i received this error message:
- subscripted value is neither array nor pointer

zeek
Newbie Poster
9 posts since Jul 2005
Reputation Points: 10
Solved Threads: 0
 

the user is prompt to enter number 1 and then number 2.
i declared two arrays to handle each digit...

char num1[ MAXDIGITCOUNT ];
	char num2[ MAXDIGITCOUNT ];

in my program, i will passed the contents of these arrays to a function called 'addition' but before i do that i decided to convert first each content of the arrays into integer. I first declare two arrays to handle the converted numbers:

int inum1[ MAXDIGITCOUNT ]; 
	int inum2[ MAXDIGITCOUNT ];

then i do this:

for( n = 0; n < len2; n++ ) {
        inum2[ n ] = atoi( num2[ n ] );
   }

and i received this message:
[Warning] passing arg 1 of 'atoi' makes pointer from integer without a cast

then i write the function 'addition' as:

void addition(int _num1, int _num2,...){
                s1 = _num1[ _len1]; 
     }

and i received this error message:
- subscripted value is neither array nor pointer

and when i tried to run the program, it shows Segmentation Fault while performing
the line containing the 'atoi'

zeek
Newbie Poster
9 posts since Jul 2005
Reputation Points: 10
Solved Threads: 0
 

atoi expects a pointer to a nul-terminated array of characters, that is, a "c-style string".

You're passing it a character, not a pointer to an array of characters. When a character gets interpreted as a pointer, it ends up refering to some arbitrary address of memory that the program has no right to access. Accessing memory it's not allowed to access gives your program the segmentation fault.

If you want to convert a character such as '1' to an integer value of 1, all you need to do is subtract '0'. I.e. char x = '5'; int y = x - '0'; /* y == 5 now */

Rashakil Fol
Super Senior Demiposter
Team Colleague
2,658 posts since Jun 2005
Reputation Points: 1,135
Solved Threads: 177
 

atoi expects a null-terminated string, not a single character. Try something like this (untested).

inum2[ n ] = num2[ n ] - '0';


<< Threads merged -- don't post duplicates . >>Do not flood the forum
Do not flood the forum posting the same question in multiple forums, or multiple ways. All that happens is it gets confusing. It's a lot easier for everyone to get the answers they need if everything is kept in one place.

Dave Sinkula
long time no c
Team Colleague
5,058 posts since Apr 2004
Reputation Points: 2,780
Solved Threads: 314
 

thanks guys... you're really a great help

zeek
Newbie Poster
9 posts since Jul 2005
Reputation Points: 10
Solved Threads: 0
 

look into cin.clear()

winbatch
Posting Pro in Training
466 posts since Feb 2005
Reputation Points: 68
Solved Threads: 18
 

>look into cin.clear()
The question was concerning C, not C++. You also didn't mention why to use cin.clear(), which is a bad thing because you might trick someone into thinking that it discards characters when all it does is clears the error state for the stream.

Narue
Bad Cop
Administrator
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
 

This article has been dead for over three months

Post: Markdown Syntax: Formatting Help
You