Segmentation fault (core dumped) in programme in c? - c

I'm a student and I m learning c (programming in ANSI c -> fifth edition) and facing the below error:
I'm implementing one program with typedef
In below c program give an error:
main.c:8:6: warning: ‘gets’ is deprecated [-Wdeprecated-declarations]
/usr/include/stdio.h:638:14: note: declared here
main.c:(.text+0x1f): warning: the `gets' function is dangerous and should not be used.
enter name:cara
Segmentation fault (core dumped)
program:
#include <stdio.h>
char * read(void); //here I m writing prototype but I don't know what is the prototype and why here write the prototype?
char * read(void)
{
char * name;
printf("enter name:");
gets(name); //get string input using gets(..) function
return name;
}
void main()
{
char * name;
name = read();
printf("welcome,%s\n",name);
}
above program is a complexity that is why I m using typedef in the below program:
this below program continuously run why?
#include <stdio.h>
typedef char * string;
string read(void);
string read(void)
{
string name;
printf("enter name:");
gets(name);
return name;
}
void main()
{
string name;
name = read();
printf("welcome,%s\n",name);
}
What I'm doing wrong?

There are a couple of things wrong with this. When you do char * name, you define name as a char pointer, but you don't actually allocate any space for the string to be stored. Hence, when you try to write values into that string, you're writing values in a random place that may not be writable or may contain crucial data that cannot be overwritten. Instead, try declaring name as char name[256]; to allocate enough space for it. Also, don't use gets, as it can lead to very, very, nasty things. Instead, use fgets to read input, and provide an upper limit on the number of characters equal to the amount of data you allocated. So, if you declared name as char name[256];, call fgets with fgets(name, 256, stdin);

The program has undefined behavior because you are using an uninitialized pointer that has an indeterminate value
char * name;
printf("enter name:");
gets(name);
You need to allocate memory where you are going to read a string.
As for the function gets then it is indeed an unsafe function and is not supported by the C Standard anymore. Use instead the standard C function fgets.
Pay attention to that according to the C Standard the function main without parameters shall be declared like
int main( void )
And using a typedef like this
typedef char * string;
is a bad idea. For example using this typedef name you are unable to declare a pointer to constant data like
const char *p;
because this declaration
const string p;
is not equivalent to the above declaration but means the following declaration
char * const p;
The program can look for example the following way
#include <stdio.h>
char * read( char *s, size_t n )
{
s[0] = '\0';
printf( "Enter name: " );
fgets( s, n, stdin );
return s;
}
int main( void )
{
enum { N = 100 };
char name[N];
printf( "%s", read( name, N ) );
}
Its output might look like
Enter name: rahul_
rahul_
Pay attention to that the function fgets can append the entered string with the new line character '\n'. To remove it you can use the following trick
#include <string.h>
//...
name[ strcspn( name, "\n" ) ] = '\0';

Related

Arrays and Functions in c

I am just starting to work with functions and wish to read an entire array of user input and convert all entries to uppercase. I am still a little confused how to change things in functions and have the changes occur in the array in the main program.
The code I attached is not working:
Any help and/or explanation would be appreciated.
Thank you
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <ctype.h>
// function to turn all user input to uppercase
turnUpCase(char *in,200)
{
char *p;
for (p=in; *p='\0'; ++p)
{
*p = toupper(*p);
}
}
int main(void)
{
char input[200];
int i = 0;
printf("Welcome to the Morse translator.\n");
printf("Enter input: ");
fgets(input, sizeof(input), stdin);
// call to function to turn all input into uppercase
turnUpCase(&input);
return 0;
}
For your turnUpCase function:
1- You are not mentioning any return type.
2- what is 200 ?? write it as retyrn_type turnUpCase(char *p, int size)
in for loop write it as
for (p=in; *p!='\0'; ++p) //to compare with anything use '=='
Name of array is always a pointer. You don't need to mention like turnUpCase(&input). let it go like turnUpCase(input,200)
modify:
turnUpCase(&input); //turnUpCase(input)
turnUpCase(char *in,200) //turnUpCase(char *in)
*p='\0' // *p!='\0'
To make your code work, first you need to change the declaration for turnUpCase() to something like:
void turnUpCase(char *in){}
Since your function does not return a value, it should be declared to be of type void. Next, in the for-loop of the function itself, you have an assignment instead of a comparison. Try this:
for (p = in; *p != '\0'; ++p){}
Finally, when you pass an array to a c function, you are really passing a pointer to the first element of the array, so in your case turnUpCase(input) passes a pointer to the first character of the input string to your function. The way you wrote it, you are passing the address of a pointer to the first character.
Incidentally, I might have written your function like this:
void to_upper(char *str)
{
while(*str) {
*str = toupper(*str);
++str;
}
}
change turnUpCase(&input); to turnUpCase(input); ( an array if passed to a function, "decays" to a pointer to its 1st element, so you don't need to use &) and
also:turnUpCase(char *in,200) to void turnUpCase(char *in) and *p='\0' to *p!='\0'.`
I didn't check if there are the proper libraries for this code to run, but the corrected code seems to be:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <ctype.h>
First, we need to declare the method. C needs it inside the header or before the function. Be aware of that this declaration has no body, and ends with ;. After that, we can define the function.
// function to turn all user input to uppercase
void turnUpCase(char *in);
every function needs a return type defined before the definition. Here's the definition and body of the function:
void turnUpCase(char *in) {
char *p;
for (p=in; *p; p++) *p = toupper(*p);
}
Note: As #DavidBowling suggested, this code can be rewritten as (I prefer keeping the original pointer as it was) :
void turnUpCase(char *in) {
char *p = in;
while(*p){
*p = toupper(*p);
p++;
}
}
Both methods check the chars until it reaches a zero char/string end char/null char. Every string in C ends with an \0 (0x00) character, so the function tells that until our string ends, loop the chars and make every char uppercase.
Now the magic begins:
int main(void) {
char input[200];
int i = 0;
printf("Welcome to the Morse translator.\n");
printf("Enter input: ");
fgets(input, sizeof(input), stdin);
Here, you don't need the addressing & operator, because in C, char arrays are already a pointer to it's contents. But, you might give the first char's address to the method too. So there are two options.
First:
// call to function to turn all input into uppercase
turnUpCase(input);
Second:
// call to function to turn all input into uppercase
turnUpCase(&input[0]);
Then, you can print the result to user.
printf("The uppercase version is: %s", input);
return 0;
}
i compile your code with c++ 4.2.1, and it seems has some compilation error.
when you claim a string, input variable is the pointer of first char in string, so it should be turnUpCase(input) when you call the function.
if want to change variable in function, you need to pass pointer or reference into it. in this case, pass input is just fine.
the reason your code not work may be:
for (p=in; *p='\0'; ++p)
should be:
for (p=in; *p=='\0'; ++p)

Segmentation fault: 11 in basic single source C program

I am an absolute beginner is C, so bear with me.
I am getting a segmentation fault: 11 directly after I put my Name in When I run my code. When I compile it never has any errors so I am really not sure what I am doing wrong. I am on mac also if that affects anything.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char * name;
char * pass;
} user;
void prompt(user u) {
char passw;
char name;
printf("Enter your name:\n");
scanf("%s", &name);
if (strncmp(u.name, &name, strlen(u.name)) == 1) {
printf("Correct! Please input password:\n");
scanf("%s", &passw);
if (strncmp(u.pass, &passw, strlen(u.pass)) == 0) {
printf("Congrats! you got in.\n");
}
}
}
int main() {
user me;
me.name = "Me";
me.pass = "1234";
prompt(me);
return 0;
}
The problem here is with the variable type name and the corresponding format specifier. You defined it to be a char, but you use %s to scan the value. It causes a bound-overflow that creates undefined behavior.
You need to make name an array, like
char name[64] = {0}; //size is for demo
and the, use scanf() like
scanf("%63s", name);
same goes for passw, also.
FWIW, %s is used to scan a string, whereas, to intake a single char, you need to use %c format specifier.
Also, you can consider having a look at the man page for fgets() as this is considered a safer alternative.

Try using strlen but get error: Conflicting types for 'strlen'

I can't figure out what causes this problem... appreciate any help!
I've tried a lot of codes for strlen but this one was the only one that I could implement with only 1 error. With this code, I'm trying to read a string from a file, break it in words separated by space, determinate the length and then print the word and the length to the user.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
FILE*arquivo;
char nuks[80];
char frase[80];
typedef struct node {
char palavra;
struct node* esquerda;
struct node* direita;
int altura;
} No;
size_t strlen(char *nstr)
{
int total=0;
char str[80];
strcpy(str, nstr);
total = strlen(str);
printf("|%s| is |%d|", str, total);
}
int main()
{
No* raiz = NULL;
arquivo=fopen("README.txt","r");
fgets(nuks, 79, arquivo);
printf("%s\n",nuks);
char *parte;
// Get the first word
parte = (char*)strtok(nuks, " ");
// Get the other words
while(parte != NULL){
strlen(parte);
printf("%s\n", parte);
parte = (char*)strtok(NULL, " ");
}
printf("\n\n");
system("pause");
return 0;
}
You are calling a function named strlen() into a function also named strlen(), which makes it recursive and, what is worse, infinitely recursive!
Besides that, you don't need to have a local copy of nstr into str just for determining its length.
Finally, is there any reason for not using the standard strlen() function declared in string.h?
size_t strlen(const char *) is already defined in <string.h>, therefore the conflict. You should choose another function name for your function.
1> The standard strlen is conflicting with local strlen. (Probably the conflict error is here )
2> The fuction is not properly coded, calling recursively itself without any exit point.
The first one can be ignored as local definition will overload the one in string.h
But the problem is in the function.
Note that in your code, you've included the C string library
#include <string.h>
which has the function
size_t strlen(const char *str)
that returns the length of the string passed into the function.
However, in your code, you try to overwrite the function
size_t strlen(char *nstr)
which causes confusion when C tries to compile your file. Try to use a different name for your function instead. For example:
/* This function prints the length of string */
void print_strlen(char *nstr) {
int total=0;
total = strlen(nstr);
printf("|%s| is |%d|", nstr, total);
}
Also, note that in your code, you defined
char str[80];
which then copies the input nstr to str.
This is ok so long as the length of the string doesn't exceed 79 (note that there is a null terminator '\0' for string). But as soon as the length of your string exceed that limit, your output will be a bit funny!

Can't declare two character pointers [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
why does c allow initialization of string without declaration?
I am trying this rather simple code:
#include<stdio.h>
void copy(char *,char *);
main() {
char *name;
char *surname;
printf("Enter name: ");
scanf("%s",name);
printf("%s",name);
}
But for some reason, after I enter a name and press Enter, the program hangs and gives a message like Program has stopped working. However when I remove the 2nd character pointer declaration, that is the char *surname;, it works just as expected. What is the problem here?
You have not allocated memory for the pointers, so the scanf accesses arbitrary unspecified memory, which is undefined behaviour.
You need to pass pointers to sufficiently large memory blocks to scanf, either declare
char s1[100], s2[100];
(if 100 is large enough), or malloc memory
char *s1 = malloc(100);
char *s2 = malloc(100);
if (!s1 || !s2) {
// malloc failure
exit(EXIT_FAILURE);
}
You are writting into unallocated memory. That is undefined behavior,
You can do 2 things here:
declare your arrays of chars as having a fixed size at compile-time like this: char name[100]; (which means you can't change their size at runtime)
allocate room for char *name using malloc() or calloc() functions in stdlib.h
In any case you absolutely have to make sure you only allow the user to input the amount of bytes you allocated, otherwise bad things can and will happen!
A small study on what an evil person can (and will ;) do if you fail to define said boundaries can be found here: http://www.cultdeadcow.com/cDc_files/cDc-351/
Because you didn't allocate memory for it, and the string you put in it screws the code of the program. Try to use sscanf and getline:
#include <stdio.h>
int main()
{
int nbytes = 100;
char *my_string;
int int1, int2, int3;
int args_assigned;
args_assigned = 0;
while (args_assigned != 3)
{
puts ("Please enter three integers separated by whitespace.");
my_string = (char *) malloc (nbytes + 1);
getline (&my_string, &nbytes, stdin);
args_assigned = sscanf (my_string, "%d %d %d", &int1, &int2, &int3);
if (args_assigned != 3)
puts ("\nInput invalid!");
}
printf ("\nThanks!\n%d\n%d\n%d\n", int1, int2, int3);
return 0;
}
check out this:
Reading in a variable length string user input in C
and this :
http://en.wikipedia.org/wiki/Buffer_overflow
You declare a pointer and do not give it a valid memory address, it points to a random addrss. You cannot read or write with this pointer. Pointers should be used like this:
char s1[100],s2[100];
char * name=s1;
char * surname=s2;

strncmp/strcpy corrupting source

today i was trying to get friendly with char * string... but it seems im failing :)
Every time i call strcmp/strncmp/strcpy function my source gets corrupted...
here is the snippet
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct student
{
int UID;
char name[20];
char surname[20];
};
char * getString(int minChars, int maxChars);
struct student * myStud;
int main(int argc, char** argv) {
myStud = (struct student*)malloc(sizeof(struct student));
while(1)
{
printf("\nEnter new name: ");
strcpy(myStud->name,getString(1,19));
printf("\n The values is now %s",myStud->name);
}
return (EXIT_SUCCESS);
}
char * getString(int minChars, int maxChars)
{
char string[maxChars+1];
scanAgain:
scanf("%s",&string);
if(strlen(string)<minChars)
{
printf("\nToo few symbols, try again: ");
goto scanAgain;
}
if(strlen(string)>maxChars)
{
printf("\nToo many symbols, try again: ");
goto scanAgain;
}
string[maxChars]='\0';
return(string);
}
Output:
Enter new name: Alekasdasd
The values is now Alekasda�#
Enter new name:
im just a beginner so it might be something very simple... might be not.
oh and by the way, using linux and netbeans as SDK, gcc as compiler.
You're returning a pointer to a stack variable.
char * getString(int minChars, int maxChars)
{
char string[maxChars+1];
When getString returns, string is invalid. Your return value points to this invalid string.
Use:
char * getString(int minChars, int maxChars, char * string) {
return string;
}
...
char string[100];
getString(1, 2, string);
Also, goto? Stop that please - use for, while do, do while but not goto
char * getString(int minChars, int maxChars)
{
char string[maxChars+1];
...
return(string);
}
The "string" array here is only allocated for the scope of the getString() function. Once it returns (goes out of scope), it ceases to exist and will be overwritten by the rest of your program. The "return(string)" statement returns the pointer of this data that's not allocated anymore -- not the data itself. This happens due to the implicit array-to-pointer conversion in C.
Instead of doing this, your getString() function should take a char* as an argument, which is allocated in the calling function.
I see two problems with your getString() function:
The string variable must be declared static so that the memory used for it is not released (stack, popped) when the function returns.
The parameter to scanf() you do not want the & token, but simply the pointer to the buffer, string.
That is, change the lines:
char string[maxChars+1];
scanf("%s",&string);
to read
static char string[maxChars+1];
scanf("%s",string);
The reason you do not want the ampersand in the scanf() call is the following from the man page, man 3 scanf:
s Matches a sequence of non-white-space characters; the next
pointer must be a **pointer to character array** that is long enough
to hold the input sequence and the terminating null character
('\0'), which is added automatically. The input string stops at
white space or at the maximum field width, whichever occurs
first.
240 lines is not a "snippet".
As James suggested in his comment, reduce the code to the minimum number of lines needed to reproduce the problem. At that stage the cause of the problem should become obvious to you -- if not try posting again.

Resources