Segmentation fault at writing the telephone number program - c

I am writing a C program that prompts the user to enter a telephone number in the form (xxx)xxx-xxxx and then displays the number in the format xxx.xxx.xxxx. Here is an example:
Enter a phone number [(xxx) xxx-xxxx]: (404)817-6200
You entered the data 404.817.6200
I created two strings, one for storing the phone number with parenthesis and '-' signs and the other, empty. I want to add each character to the empty string, changing the ')' and '-' to '.'. Here is my code:
#include <stdio.h>
int main(void){
char num[15];
char phone[13];
int i = 1;
int j = 0;
printf("Please, enter your phone number in the format (xxx)xxx-xxxx:");
scanf("\n%s", num);
while(num != '\0'){
if(num[i] == ')' || num[i] == '-'){
phone[j] = '.';
}else{
phone[j] = num[i];
}
i++;
j++;
}
printf("\n%s",phone);
}
When I run the program, it gives me the error message that says:
Segmentation fault
Can somebody explain why it is happening and how to prevent it in the future?

I see three issues in your program:
(1) while(num != '\0') should be while(num[i] != '\0'. num is an array (and will never compare equal '\0', so you get an endless loop and exceed array bounds.
(2) you need at least 14 bytes for phone (just one less than num, not two less)
(3) you need to write a string termination character into phone; othwerwise printf("\n%s",phone); will again exceed the bounds of phone; e.g:
}
phone[j] = '\0';
printf("\n%s",phone);`

When you reference the name of an array variable in C, without appending the [] (index) operator, you are (effectively) referring to the address of that array's first element. This will never be zero (or NULL) for an array declared as a local variable, so the comparison of num to zero ('\0') in your while loop will never be true, and the loop will run on unstopped, until you try to read or write to an invalid address, at which point the program will crash.
With compiler warnings enabled, you should see something like the following (generated by clang-cl):
warning : comparing a pointer to a null character constant; did you
mean to compare to NULL? [-Wpointer-compare] warning : comparison
of array 'num' not equal to a null pointer is always true
[-Wtautological-pointer-compare]
What you should do, instead, is to compare the 'current' element (at index i) to the nul character ('\0') to check for the end of the string:
while (num[i] != '\0') {// Check character at position "i"
// rest of your loop ...
You should also ensure that your phone string is properly nul-terminated (although some compilers will initialize the array to zero, don't rely on this). You can do this either by adding an initializer to the declaration of phone:
char phone[13] = { 0 }; // Will set all elements to zero
or by adding the nul terminator immediately after the end of your while loop:
// body of while loop
// ...
}
phone[j] = '\0'; // Append the terminator

Related

C program that reads five strings and only prints strings that begin with the letter 'a'

I'm new to programming and cant figure out what I'm doing wrong.
From the 5 given strings I'm trying to print only strings that begin with the character 'a'.
This is what i have done so far
#include <stdio.h>
int main()
{
char str[5][100];
int i;
//For loop asks user to input 5 strings
for(i=0;i<5;i++)
{
printf("\nEnter line > ");
scanf("%s", str[i]);
}
for(i=0;i<5;i++)
{
//To check if the first character in a string is 'a'
if(!str[0]=='a')
{
printf("\n%s", str[i]);
}
}
return 0;
}
This part is not working. In my mind its supposed to check the first letter of every string but its not doing that. Instead the program doesn't print out anything when this if statement is there.
if(!str[0]=='a')
In your if statement, you need to remove the ! character and access the first element of the string i like this:
if(str[i][0]=='a')
Your are accessing the pointer to the first string which will be a random memory address. If you access the first value, you will need to access two array elements: First the correct character array (string) by using [i] and then the character you want to test [0]
The ! in front of the first value will turn any non-zero value to zero and a zero into a one (logical negation). Therefore you are always testing
if(0 == 'a')
which is always false

Scanning and printing strings using pointers

I wrote a code for scanning a string from user using pointers and storing it in another string array and printing that string array. The output is coming quite strange. The first three characters are printed but next characters are coming as random garbage values. Please tell me the error in the code. Following is the code:
#include<stdio.h>
int main(void)
{
char str1[8];
char *p1=str1;
char str2[8];
char *p2=str2;
printf("Enter a string\n");
while(*p1)
scanf("%c",p1++);
*p1='\0';
p1=&str1[0];
while(*p1)
*p2++=*p1++;
*p2='\0';
printf("The copied string is :");
p2=&str2[0];
while(*p2)
printf("%c",*p2++);
}
You are not placing the terminating null character('\0') at the end of your strings str1[] and str2[]. And you are trying to dereference and check the value which is not initialized in your first while loop condition: while(*p1)
printf("Enter a string\n");
do{
scanf("%c",p1++);
}while(*(p1 - 1) != '\n'); //try the do while loop
*(p1 - 1) = '\0'; //placing terminating null character
p1 = &str1[0];
while(*p1){
*p2++ = *p1++;
}
*p2 = '\0'; //placing terminating null character
here's the demo code: https://ideone.com/dF2QsJ
Why have you checked the condition for the new line in the do while condition? And why p1-1?
This is because you end the input by entering a '\n' which gets stored at p1 and then p1 moves to p1 + 1 at the end of each iteration. So, I check whether a '\n' is present at p1 - 1.
okay,
Why arent you using %s and get the input directly. you can get the entire string rather than looping over each character.
This loop
while(*p1)
scanf("%c",p1++);
checks the contents of str1 (pointed at by p1) before ever storing anything there. That uninitialized memory might contain anything, so this loop might never execute (if the first char happens to be NUL), or might run off the end of the array (corrupting memory).

Why am I getting a debug assertion failed error on running the code

When I enter a password in my program below and press enter I get a debug
assertion error, specifically isctype.c line 56
Expression:(unsigned)(c+1) <= 256
Could someone help me get around this please?
Code:
int main()
{
int j=0;
char pass[100];
int upper=0, lower=0, digit=0, sc=0;
printf("Enter your password:\n");
scanf("%s",&pass);
while(j!=' '){
if(isalpha(pass[j])){
if(isupper(pass[j])){
upper++;
}
else{
lower++;
}
}
else if(isdigit(pass[j])){
digit++;
}
else{
sc++;
}
j++;
}
if(upper==0||lower==0||digit==0||sc==0){
printf("Password must contain atleast one upper case, one lower case, one digit and a special character");
}
else{
printf("Good to go");
}
return 0;
_getch();
}
Replace
while (j!=' ')
by
while (pass[j] != 0)
You want to loop as long as pass[j] is different from zero. Remember, strings are terminated by a zero.
It looks like the problem in your code is
while(j!=' ')
which is checking j against space (' ') which is having ASCII value of 32 (decimal).
Essentially, you're unconditionally using pass array elements having index 0 to 31.
Then, pass is an automatic local variable and you did not initialize it. It contains indeterminate value.
If, your input is less than 31 characters, the remaining element of pass will remain uninitialized, and using them further (as the argument to is....() family, here) may lead to undefined behaviour.
Solution: You don't need to check for a space, (as %s does not accept one). Instead you should check for the null terminator \0. Change your code to
scanf("%s",&pass); to scanf("%99s",pass); to avoid possible buffer overflow.
while(j!=' ') to while(pass[j]) to loop until the string terminator null.
That said,
using _getch() after unconditional return statement does not make any sense. You can straight-away remove that _getch().
The recommended signature of main() is int main(void).

Array point 0 doesn't reset content

I've made use of an array, and want to delete the content by placing null in array[0] but it doesn't work. Example... If I type Jesper, then the serial.print(nameBuffer[1]) returns e.
A temporary solution I use is a for-loop to place null in all it's spaces.
char name1[9] = "Jesper";
char nameBuffer[9];
void setup()
{
Serial.begin(9600);
}
void loop()
{
int i = 0;
nameBuffer[0] = 0;
Serial.print(nameBuffer[1]);
Serial.println(" All reset\n");
while(Serial.available() == 0)
{
// wait for data to be send
}
while(Serial.available() > 0)
{
int inByte = Serial.read();
delay(50);
nameBuffer[i] = char(inByte);
i++;
Serial.print("Recieved bytes: ");
Serial.println(inByte,DEC);
}
Serial.print("Searching for: ");
Serial.println(nameBuffer);
}
nameBuffer is an array of 9 char elements. Each of those elements has a value of type char.
Setting a char object to 0 doesn't remove it from the array (0 or '\0', the null character, is as valid a char value as any other), nor does it affect the elements that follow it.
Now if you're treating the contents of nameBuffer as a string (defined by the C standard as "a contiguous sequence of characters terminated by and including the first null
character"), then storing '\0' in nameBuffer[0] will cause it to contain an empty string. It has a length of 0, but there are still 9 char values stored in the array. So this:
printf("%s", nameBuffer);
won't print anything, but namebuffer[1] is still a valid char object holding whatever value was last stored in it.
Don't assume that printing a null character, or sending it over a serial port, will do nothing. If you don't want to print each character in your array, you'll need some logic to avoid printing the characters you don't want.
Incidentally, your code appears to be C++, not C. You have overloaded versions of Serial.print, one taking a char argument and one taking a char*; C doesn't support overloading. And char(inByte) is C++; it's a syntax error in C. (BTW, a cast isn't necessary there; the value will be converted implicitly.)

Converting Character Array to Integer Array in C for ISBN Validation

I really hope someone can give a well explained example. I've been searching everywhere but can't find a proper solution.
I am taking an introduction to C Programming class, and our last assignment is to write a program which validates a 10 digit ISBN with dashes... The ISBN is inputted as a string in a CHAR array. From there I need to separate each digit and convert them into an integer, so I can calculated the validity of the ISBN. On top of that, the dashes need to be ignored..
My thought process was to create an INT array and then use a loop to store each character into the array, and pass it through the atoi() function. I also tried using an IF statement to check each part of the CHAR array to see if it found a dash. If it did find one, it would skip to the next spot in the array. It looked something like this:
int num[12], i = 0, j = 0, count = 0;
char isbn[12];
printf ("Enter an ISBN to validate: ");
scanf ("%13[0-9Xx-]%*c", &isbn);
do {
if (isbn[i] == '-') {
i++;
j++;
}
else {
num[i]= atoi(isbn[j]);
i++;
j++;
}
count++;
} while (count != 10);
But that creates a segmentation fault, so I can't even tell if my IF statement has actually filtered the dashes....
If someone could try and solve this I'd really appreciate that. The Assignment was due Dec 4th, however I got an extension until Dec 7th, so I'm pressed for time.
Please write out the code in your explanation. I'm a visual learner, and need to see step by step.
There's obviously a lot more that needs to be coded, but I can't move ahead until I get over this obstacle.
Thanks in advance!
First of all, your definition of isbn is not sufficient to hold 13 characters; it should therefore be 14 chars long (to also store the terminating '\0').
Second, your loop is overly complicated; three loop variables that maintain the same value is redundant.
Third, the loop is not safe, because a string might be as short as one character, but your code happily loops 10 times.
Lastly, converting a char that holds the ascii value of a digit can be converted by simply subtracting '0' from it.
This is the code after above improvements have been made.
#include <stdio.h>
int main(void)
{
int num[14], i;
char isbn[14], *p;
printf("Enter an ISBN to validate: ");
scanf("%13[0-9Xx-]%*c", &isbn);
// p iterates over each character of isbn
// *p evaluates the value of each character
// the loop stops when the end-of-string is reached, i.e. '\0'
for (p = isbn, i = 0; *p; ++p) {
if (*p == '-' || *p == 'X' || *p == 'x') {
continue;
}
// it's definitely a digit now
num[i++] = *p - '0';
}
// post: i holds number of digits in num
// post: num[x] is the digit value, for 0 <= x < i
return 0;
}

Resources