Using struct and strcpy, program crashes - c

Hello this is my first time posting on this site and also I am not very familiar with structures or with strcpy() I was wondering why my program below is crashing.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
struct Employee{
char name[30];
char email[30];
};
void main(){
struct Employee x;
char employee_name[30];
char employee_email[30];
printf("enter the employees's name\n");
fgets(employee_name,30,stdin);
strcpy(x.name, employee_name);
printf("enter the employee's email\n");
fgets(employee_email,30,stdin);
strcpy(x.email,employee_email);
printf('%s',x.name);
printf('%s',x.email);
}
The purpose of the program is basically to accept a name and email as input and put it in the name and email of the structure and than print them using the structure. Now the program compiles and allows me to take the input but after that it crashes and I do not know why. Does anyone know why the crash is occurring?

The issue is with
printf('%s',x.name);
printf('%s',x.email);
as per the printf() format,
int printf(const char *format, ...);
the fisrt argument is a const char *. So, you need to write
printf("%s",x.name);
printf("%s",x.email);
That said,
void main() should be int main(void), at least to conform to the standards.
fgets() scans and stores the trailing newline (if any) to the input buffer as a part of the input. You may want to strip it off before copying the buffer.

Related

Segmentation fault (core dumped) in programme in 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';

How to properly use fscanf and fgets to read from file

I'm new at programming in C (it's my first language) and I'm not so good at english, so sorry for the grammar... By the way, I was wondering if you could help me with this:
I have to read from file the components of the array, setting them as part of it and see them as output in the screen.
I created a file with this informations:
Rossi,Mario,M,mariorossi#gmail.com,3923333332,Portiere
Bianchi,Giuseppe,M,giuseppebianchi#gmail.com,3470000021,Attaccante
Ferrari,Anna,F,annaferrari#gmail.com,3466482645,Attaccante
Romano,Antonio,M,antonioromano#gmail.com,3450394672,Centrocampista
and trying to coding I ended up with this:
#include <stdio.h>
#include <stdlib.h>
struct dati_giocatori {
char cognome[20];
char nome[20];
char genere[20];
char email[20];
int telefono;
char ruolo[20];
};
typedef struct dati_giocatori GIOCATORE;
void lettura(FILE *file, GIOCATORE *vettore, int dim);
void stampa(GIOCATORE *vettore, int dim);
int main (){
FILE *file;
GIOCATORE *vettore;
int dim;
vettore=(GIOCATORE*)malloc(dim*sizeof(GIOCATORE));
printf("how many players do you want to see?");
scanf("%d",&dim);
file=fopen("Giocatori.txt","r");
lettura(file,vettore,dim);
stampa(vettore,dim);
system("pause");
return 0;
}
void lettura(FILE *file, GIOCATORE *vettore, int dim){
int i=0;
if(file){
while(!feof(file) && i<dim){
fscanf(file,"%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],[^\n]", vettore[i].cognome,vettore[i].nome,vettore[i].genere,vettore[i].email,&vettore[i].telefono,vettore[i].ruolo);
i++;
}
}
else{
printf("Error.");
}
}
void stampa(GIOCATORE *vettore, int dim){
int i=0;
while(i<dim){
printf("%s,%s,%s,%s,%d,%s\n", vettore[i].cognome,vettore[i].nome,vettore[i].genere,vettore[i].email,vettore[i].telefono,vettore[i].ruolo);
i++;
}
}
but it does not work very well. I know I have some problems with the fscanf (probabily), and I wanted to know if the malloc is used correctly... Could you help me? Where are the errors I make? How can I solve them? How should the code be using a fgets instead of fscanf? Am I using the delimitators in the right way?
Ok, thank you very much for replying, I'll treat the 10-digit phone number with a long variable, but I still don't get how I should correctly use the fscanf. It's the first time with delimitators, and this confuse me. My format specifiers are "%s,%s,%s,%s,%ld,%s", right? but how should I put them in the fscanf? What have I to write after the parameter "file" in the fscanf?
fscanf(file,"%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],[^\n]",...
Your format specifiers are not correct; if you tell fscanf that the data to read is comma-separated, which you do with the commas outside the brackets, you don't need to specify what you put inside ([^,]), and you're missing format specifiers. Try to provide fscanf the same format you gave to printf in the stampa function. Be careful: an integer variable would not hold correctly a 10-digit phone number, use a long variable or treat it like a string as well.
On the other hand, fgets would read the whole line into a string buffer as it does not accepts a format specifier, so you would end up having a one string only, containing the entire line, then you should parse it with something like sscanf in the same way you should use fscanf.

Char arrays and scanf function in C

I expected to get errors in following code, but I did not. I did not use & sign. Also I am editing array of chars.
#include <stdio.h>
int main()
{
char name[10] ="yasser";
printf("%s\n",name);
// there is no error ,
// trying to edit array of chars,
// also did not use & sign.
scanf("%s",name);
// did not use strcpy function also.
printf("%s\n",name);
return 0;
}
I expected to get errors in following code, but I did not.I did not use & sign.
scanf("%s",name);
That's totally ok as name is already the address of the character array.
It sounds like you have several questions:
calling scanf("%s", name) should have given an error, since %s expects a pointer and name is an array? But as others have explained, when you use an array in an expression like this, what you always get (automatically) is a pointer to the array's first element, just as if you had written scanf("%s", &name[0]).
Having scanf write into name should have given an error, since name was initialized with a string constant? Well, that's how it was initialized, but name really is an array, so you're free to write to it (as long as you don't write more than 10 characters into it, of course). See more on this below.
Characters got copied around, even though you didn't call strcpy? No real surprise, there. Again, scanf just wrote into your array.
Let's take a slightly closer look at what you did write, and what you didn't write.
When you declare and initialize an array of char, it's completely different than when you declare and initialize a pointer to char. When you wrote
char name[10] = "yasser";
what the compiler did for you was sort of as if you had written
char name[10];
strcpy(name, "yasser");
That is, the compiler arranges to initialize the contents of the array with the characters from the string constant, but what you get is an ordinary, writable array (not an unwritable, constant string constant).
If, on the other hand, you had written
char *namep = "yasser";
scanf("%s", namep);
you would have gotten the problems you expected. In this case, namep is a pointer, not an array. It's initialized to point to the string constant "yasser", which is not writable. When scanf tried to write to this memory, you probably would have gotten an error.
When you pass arrays to functions in C, they decay to pointers to the first item.
Therefore for:
char name[] ="yasser";
scanf("%s", name) is the same as scanf("%s", &name[0]) and either of those invocations should send shivers down your spine, because unless you control what's on your stdin (which you usually don't), you're reading a potentially very long string into a limited buffer, which is a segmentation fault waiting to happen (or worse, undefined behavior).
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv, char **envp) {
char *myName = (char *) calloc(10, sizeof(char));
*(myName)='K'; *(myName+1)='h'; *(myName+2)='a'; *(myName+3)='l'; *(myName+4)='i'; *(myName+5)='d';
printf("%s\n",myName);
scanf("%s",myName);
printf("%s\n",myName);
return (EXIT_SUCCESS);
}
#include <stdio.h>
#include <string.h>
int main()//fonction principale
{
char name[10] ="yasser";
int longeur=0;
printf("%s\n",name);
scanf("%s",name);
longeur = strlen(name);
for (int i=0;i<longeur;i++) {
printf("%c",*(name+i));
}
return 0;}

How can i use scanf to plug in names and receive sentences as outputs?

I cant figure out what is wrong with my code. I want to be able to type in any of those names as the scanf function and then the words should come up that i have in the printf functions (the error occurs when i try to type in a name):
#include <stdio.h>
#include <math.h>
int main()
{
char *Name;
char *Carson;
char *Kam;
char *David;
char *Avery;
char *Taylor;
char *Brian;
printf("Enter a name:\n");
scanf("%s",Name);
printf("%s Hello Carson\n", Carson);
printf("%s Whats up?\n?", Kam);
printf("%s What are you looking at me for, I dont have any gum!!\n", David);
printf("%s Good luck with volleyball this weekend!!\n", Avery);
printf("%s Unauthorized user. Please back away!\n", Taylor);
printf("%s Hello user.\n", Brian);
return(0);
}
You need to change
char *Name;
to
char Name[100];
or use malloc to allocate memory for char *Name first before reading data to it.
And it seems you didn't initialize Carson/Kam/... before print them out. Try to fix them too.

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