Segmentation Fault (core dumped) Character Arrays - c

I am attempting to read in a sentence from the user and make it into an array, where each letter holds a character value. Each time I run the program, I am able to type in the sentence, but after that "Segmentation Fault (core dumped)" appears. All of this is happening within a function that is called from the main.
int words(char sentence[]){
int i=0;
printf("Please enter your favorite sentence(max 100 characters).\n");
scanf("%c", &sentence);
while(sentence != "." && sentence != "!"){
i++;
scanf("%c", &sentence[i]);
}
printf("%d", i);
return i;
}

What does your compiler say when you compile with -Wall -Wextra. You can't expect to write C code correctly without compiling with warnings on. Everyone says how badly you can mess up with C code, it lets you do anything. That's true but the warnings are there to help you.
I'm not sure why people are asking you to go to gdb or valgrind. For me, this code should never be executed and expect to be right. My compiler spits out these warnings:
words.c: In function ‘words’:
words.c:6: warning: format ‘%c’ expects type ‘char *’, but argument 2 has type ‘char **’
words.c:7: warning: comparison with string literal results in unspecified behavior
words.c:7: warning: comparison with string literal results in unspecified behavior
Fix those warnings and then come back if you are still having problems. Or if you don't understand what those warnings mean then ask a specific question about it.

Change your code to this and it will work:
char sentence[30];
int i=0;
printf("Enter phrase: \n");
scanf("%c", sentence);
while(sentence[i]!='.' && sentence[i]!='!')
{
i++;
scanf("%c",&sentence[i]);
}
printf("%d\n", i);
return i;
You just had to remove the '&' from the scanf in the fourth line since sentence alone without the array index indication is a memory adress itself. Note that this works if the sentences always end with a '.' or a '!'. Although i believe there is a better way to do this than reading the sentence one char at a time.

Related

Formatted string in scanf() in C

Just like printf(), I was trying to use optional specifiers in scanf() format string. I tried to use the width and precision specifier. Now in printf() it simply reserves the columns and print according to these specifiers but what happens with scanf()? Like what is meaning of %3d and %3.3f here? Is this even relevant in case of scanf()? I have a little idea that width in this case represents the number of characters that are to be read for some particular format but not sure. Below code explains this further:
#include<stdio.h>
int main()
{
int a;
float b;
printf("Enter Numbers:\n");
scanf("%3d %3.3f",&a,&b);
printf("Entered Numbers are\n");
printf("%d %f",a,b);
return 0;
}
Since you specified in the comments that what you really want to know is 'what if i forcefully try to do it' ... Here are the results (with Clang)
warning: invalid conversion specifier '.'
and
warning: data argument not used by format string
The program compiles , however, since these are just warnings.
Upon executing the binary, and entering the variables asked for:
The "%d" for a gets stored properly.
Regardless of what value is entered, the " %3.3f " for b always stores 0.000000
In short, the it does what almost any other code that compiles with warnings does - not behave as intended. This is neither undefined, nor unspecified behaviour, but it is wrong.
Suggestion : Refrain from asking questions that are of the nature ' what happens if I try to compile this '. Just try and see for yourself !

Why my computer crashes when I execute this code in c?

I was practicing about structs in C, so I've tried to execute 2 times this code and twice the computer crashes. I've had turn off the computer twice since my computer crashes.
Compiler is GCC (About MinGW on windows platform). The code is following :
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct person {
char name[50];
int age;
int document;
};
int main(void){
struct person p1;
printf("Data of the first person\n\n");
printf("age: ");
fflush (stdin);
scanf("%i",p1.age );
printf("Document: ");
fflush(stdin);
scanf("%i",p1.document);
printf("Age is: %i and document is: %i ",p1.age,p1.document);
return 0;
}
Sincerely,
NIN.
UPDATE....
Bad news. Now Avast says I`ve created a virus. Therefore Avast delete my exe:
Should I report as false positive or not ?
scanf("%i",p1.age );
When you call scanf, p1.age is an integer with no particular value. So you are asking scanf to store the value you input in no particular place. It's not surprising this causes a crash. You want:
scanf("%i", &p1.age );
This tells scanf to read in an integer and store it at the address of p1.age.
It's surprising your compiler didn't give you a warning. Are you sure you have all of its warnings enabled?
When I try to compile this, I get appropriate warnings:
warning: format ‘%i’ expects argument of type ‘int *’, but argument 2 has type ‘int’ [-Wformat=]
Update: Your anti-virus has heuristics that block software that has suspicious behavior. Your code has bugs, and your anti-virus doesn't know that they're just mistakes and not attempts to do something nefarious. It sounds like you don't have a very good environment set up for experimentation. Let me guess -- you're doing all this from a Windows administrator account.

Cannot get the correct input in C programming

I am writing a simple C program to accept an input number from user and display it just because earlier i was writing some C program and this stupid error is bugging me it wasn't there before until yesterday
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int a;
printf("Enter a number");
scanf("%d",&a);
printf("Display number%d",&a);
}
Every time i run a program that accept an input it displays a seemingly random value and not the one I entered not just in this program in any other too, here
is the O/p:
Enter a number: 12
Display number : 2752300
Process returned 7(0X7) execution time : 1.880s
Press any key to continue
I don't know whether is the Compiler error or some memory error that is causing this problem but for the record i have tried using different IDE like DEV C/C++, Turbo C/C++ and Code Blocks but the error remains to be same in all of it except in Turbo C/C++ it display a signed number of i enter for eg : if input is 12 it displays: -12.
The problem is in your print statement. You are printing the address of a, not the value. Use print("%d",a);
The %d format specifier for printf expects an int, not an int *:
printf("%d",a);
It's not attempting to write to a, so it doesn't need its address.
If you compile with the warning level turned up (-Wall -Wextra for gcc), it will tell you this:
format ‘%d’ expects type ‘int’, but argument 2 has type ‘int *’
scanf needs a pointer to the variable if it is going to change the variable itself, so we use the address-of operator to get the pointer.
scanf() received "%d", as a parameter and then knows it needs to read an integer and store it in the next variable in the argument list.
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int a = 0;
printf("Enter a number: ");
scanf ("%d" ,&a);
printf ("%d \n ",a);
return 0;
}

What does the ^ scanf modifier actually do?

I have searched and read that the ^ modifier states to ignore whatever you put inside of the [ ] in scanf. For example:
int val;
scanf("%[^abc] %d, &val);
printf("val is %d", val);
Now, if I input abc42, I thought the abc would be ignored and 42 would get stored into val. But, this doesn't happen.
I also tried to suppress the scanf by making it:
scanf("%*[^abc] %d, &val);
but this did not work either. So I am confused on what ^ actually does.
When you say you want scanf to ignore certain characters, I think you mean you want scanf to read those characters and then ignore them. In order to do that, you use the %*[] format specifier:
scanf("%*[abc] %d", &val);
The [abc] tells scanf to read any number of the characters between the brackets (i.e. a, b, or c). The * tells scanf to ignore those characters, then the %d reads the value into val.
The ^ specifier tells scanf to read any number of characters other than those in between the brackets, which is the opposite of what you want to do, I think.
You need to carefully read the documentation of scanf(3) and to enable all warnings when compiling (e.g. gcc -Wall -Wextra -g if using GCC...); you'll probably have been warned with such a compilation. You should also use the result of scanf and run your program in a debugger (gdb)
scanf("%[^abc] %d", &val);
is reading two items, the first being a string of characters outside of the set {a,b,c} (and the second being an integer going "nowhere").
So your program has undefined behavior (UB) because you call scanf with one argument less than it should, and because the first argument should be the location of a wide enough char buffer. UB can be really bad, so you need to always avoid it.
You might try:
int val= 0;
char buf[32]; // 30+1 could be enough....
memset (buf, 0, sizeof(buf));
if (scanf("%30[^abc] %d", buf, &val) == 2) {
printf("got string %s and int %d\n", buf, val);
}
else { // handle scanf failure
}
It gives the following warning message when I am compiling the code.
test.c:5:2: warning: format ‘%[^abc’ expects argument of type ‘char *’,but argument 2 has type 'int *’ [-Wformat]
test.c:5:2: warning: format ‘%d’ expects a matching ‘int *’ argument [-Wformat]
You have to pass the character array to the scanf function, when you are using this.
So, modify the scanf line to bellow, and check what happens.
char buf[100];
int val;
scanf("%[^[abc] %d",buf,&val);
The %[^abc] it reads the string, if any character in the bracket other than the ^ is occurs it will fill the address of the character array with the reading characters.
So, this is used only when we are reading the string input.

GCC compile error: format ‘%c’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat]

Ok, I'm a noob with C, but I think the code is basic and straightforward. This program is for a college assignment, and is supposed to have the 'isdigit()' function in it. Here is the code
//by Nyxm
#include <stdio.h>
#include <ctype.h>
main()
{
char userChar;
int userNum, randNum;
srand(clock());
printf("\nThis program will generate a random number between 0 and 9 for a user to guess.\n");
/*I changed it from '1 to 10' to '0 to 9' to be able to use the isdigit() function which
will only let me use a 1 digit character for an argument*/
printf("Please enter a digit from 0 to 9 as your guess: ");
scanf("%c", userChar);
if (isdigit(userChar))
{
userNum = userChar - '0';
randNum = (rand() % 10);
if (userNum == randNum)
{
printf("Good guess! It was the random number.\n");
}
else
{
printf("Sorry, the random number was %d.\n", randNum);
}
}
else
{
printf("Sorry, you did not enter a digit between 0 and 9. Please try to run the program again.\$
}
}
When I try to compile, I get the following error
week3work1.c: In function ‘main’:
week3work1.c:14:2: warning: format ‘%c’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat]
What on earth is going on? I am desperate for help. Any help at all. I am seriously about to just give up on this program. Why is it saying it expects argument of 'char *' when my textbook shows that "%c" is for regular ole 'char'? I am using nano, gcc, and Ubuntu if that makes any difference.
For scanf(), you need to pass a pointer to a char, otherwise it doesn't have any way to store the character, since said char would be passed in by value. So you need &userChar instead.
Let's say userChar is 0 before the call. With your current code, you're basically doing this (as far as utility goes):
scanf("%c", 0);
What you want is this:
scanf("%c", some-location-to-put-a-char);
Which is &userChar.
The man page for scanf mentions this:
c Matches a sequence of characters whose length is specified by
the maximum field width (default 1); the next pointer must be a
pointer to char, and there must be enough room for all the char‐
acters (no terminating null byte is added). The usual skip of
leading white space is suppressed. To skip white space first,
use an explicit space in the format.
replace scanf("%c", userChar); with scanf("%c", &userChar);.
You need to pass in a pointer instead of the value of the char.
scanf("%c",&userChar);

Resources