This is a simple code to store a person's name and number in a file.the problem occurs when i also want to include the person's contact number.the error occurs after the contact number is scanned.
#include <stdio.h>
#include <stdlib.h>
main()
{
FILE *fp;//file pointer
char *name,*number;
char filename[]="testfile.txt";//file to be created
fp=fopen(filename,"w");
if(fp==NULL)
{
printf("\nerror\n");
exit(1);
}
fprintf(stdout,"Please enter a name:\t");
fscanf(stdin,"%s",name);
fprintf(fp,"%s",name);
fprintf(stdout,"Enter contact number:\t");
fscanf(stdin,"%s",number);
fprintf(fp,"%s",number);
fclose(fp);
}
you did not malloc() the memory for name and number!
Here is an extract of your code:
char *name;
fscanf(stdin,"%s",name);
name is a pointer to a char (or the first char of a string) but you didn't initialized it's value so it points anywhere.
The second line with fscanf read a word and write it in memory at the address pointed by name. So, basically, fscanf will try to write somewhere it will probably won't be able to write.
There are 2 solutions:
either you change char *name to char name[MAXNAME] (where MAXNAME is a constant value)
either you do a malloc: char *name = malloc(MAXNAME)
The same for number.
Allocate memory for pointers name and number
name = malloc(sizeof(char) * num_elements);
number = malloc(sizeof(char) * num_elements);
Related
I need to put the names separated by commas from the text into struct that expands dynamically, but I am prohibited from using realloc ().I'm getting a core dumped error in this code. What is the error in this code?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct movie{
double budget;
int genre;
char* name;
double score;
int year;
};
void recorder_function(struct movie *movies){
FILE*fp;
fp=fopen("Movies.txt","r");
struct movie *p;
int i,n=0;
char line[1000];
char temp_budget[50];
char temp_name[50];
char temp_genre[50];
while (!feof(fp)) {
fgets(line,1000,fp);
sscanf(line,"%50[^,],%50[^,],%50[^,]",temp_budget,temp_genre,temp_name);
//I open the fields in this section
movies=(struct movie *)calloc(n+1,sizeof(struct movie));
p=(struct movie *)calloc(n+1,sizeof(struct movie));
p[n].name=(char*)malloc(sizeof(char)*(strlen(temp_name)+1));
movies[n].name=(char*)malloc(sizeof(char)*(strlen(temp_name)+1));
for(i=0;i<n;i++)
movies[i]=p[i];
strcpy(movies[n].name,temp_name);
free(p);
p=movies;
n++;
}
for(i=0;i<n;i++)
printf("%s\n",movies[i].name);
}
int main(){
int choice;
struct movie *movies;
recorder_function(movies);
}
It is a bad idea to overwrite the pointer movie by newly allocated clean buffer.
Instead of that, you should
Allocate new buffer only for p.
Put the new element to p[n]
Put existing elements movie[0], ... , movie[n-1] to p[0], ... , p[n-1]
Free the old buffer movie
Assign the new buffer p to movie
Don't forget to initialize movie not to cause troubles at the first freeing.
Also while (!feof(fp)) is wrong and you should check if readings are successful after trying to read and before using what are read.
One more important point is that you should make sure that fopen() succeeded. Passing NULL, which fopen() returns on failure`, to other file manipulation functions may cause troubles.
Another point is that your arrays used for sscanf() outputs should have one more elements for the terminating null-character.
Yet another point is that casting results of malloc() family is considered as a bad practice.
Try this:
void recorder_function(struct movie *movies){
FILE*fp;
fp=fopen("Movies.txt","r");
if(fp==NULL){
fputs("file open error\n", stderr);
return;
}
struct movie *p;
int i,n=0;
char line[1000];
char temp_budget[51];
char temp_name[51];
char temp_genre[51];
movies=NULL;
while (fgets(line,1000,fp)) {
sscanf(line,"%50[^,],%50[^,],%50[^,]",temp_budget,temp_genre,temp_name);
//I open the fields in this section
p=calloc(n+1,sizeof(struct movie));
p[n].name=malloc(sizeof(char)*(strlen(temp_name)+1));
strcpy(p[n].name,temp_name);
for(i=0;i<n;i++){
p[i]=movies[i];
}
free(movies);
movies=p;
n++;
}
for(i=0;i<n;i++){
printf("%s\n",movies[i].name);
}
}
The next stage will be fixing the weird usage of the argument movie. Arguments in C are copies of what are passed, and modifications of arguments in callee functions won't affect what are passed in caller. Your choice is:
Remove the argument movies and convert that to a local variable.
Have recorder_function take a pointer to struct movie* (struct movie**) and have it use the pointer to modify what caller specifies. (You also have to change the statement to call the function to pass a pointer in this case)
I relatively new to the C language and StackOverflow. I'm trying to write a simple C code that will prompt user for their name and then display it.
#include <stdio.h>
int main (void)
{
char name;
printf("Let's do this, please enter your name:");
scanf("%s", &name);
printf("Your name is %s", name);
return 0;
}
The code complies but after inputting the name, it displays Segmentation fault (core dumped).
Thank you for any help.
A very small mistake #Jackie_Legs. In the declaration of the variable name, You have declared it as a char. so it holds just one character.
The solution: choose an arbitrary size for your name, say 10 or 15 characters. and declare it as an array of the size.
char name[15];
No changes in any other part of the program. Also, you should omit the & symbol in the scanf for strings.
So just one change and your code should work.
Here is the updated code which would work:
#include <stdio.h>
int main (void)
{
char name[15];
printf("Let's do this, please enter your name:");
scanf("%s", name);
printf("Your name is %s\n", name);
return 0;
}
It is because your name variable can only store single character and you are trying to store more than one character which will lead to unpredictable behaviour of program (e.g. segmentation fault).
If you know max length of name, declare variable name as array of character such as
char name[20];
Here you can store name with max length of 19 character. You can decide length of array as per your requirement.
You need to declare a string as because a single letter is stored in char and multiple characters along with a null character at the end forms an String which can be anything like names, etc.
In your code you have taken char which stores only a single character but in order to store your name (which is a string) you will have to take char array along with the size of the array.
Replace char with char[size] where size is the size for the string that you need.
Here are the changes I made to your code:
#include <stdio.h>
int main (void)
{
char name[30];
printf("Let's do this, please enter your name:");
scanf("%s", name);
printf("Your name is %s", name);
return 0;
}
name is declared as char, which means it can contain only one character. It is not sufficient to contain a string of characters (which a name usually consists of). You need to declare a char array (an array of characters).
The size of the array should be at least 1 more than the largest name you want to read in.
The extra byte is to contain the null terminating character '\0'.
char name[SizeOfLargestName + 1];
And when you use scanf, you need not use & because now name points to the first byte of the array.
scanf("%s", name);
It is throwing error because of char name; char data type in C contain 1 character only in a variable. But your input is a string.
You need to change the declaration of the variable from char to char array.
char name[50];
printf("Let's do this, please enter your name:");
scanf("%s", name);
printf("Your name is %s", name);
I need to read some data from text file and store it in 2D-array.
This code works good:
#include <string.h>
#include <stdio.h>
int main() {
FILE *f = fopen("Read.txt", "r");
char buff[100][100];
char str[100];
int i = 0;
while(fgets(str, 100, f)) {
strcpy(buff[i], str);
i++;
}
return 0;
}
But why doesn't it work when I try to change buff definition in line 5 to:
char (*buff)[100];
I expected this definition to work too.
The error I get:
Run-Time Check Failure #3 - The variable 'buff' is being used without being defined
char (*buff)[100];
Here buff is a pointer to an array of 100 characters. So first you should make the pointer point to valid memory location before storing some value in it.
Presuming you want to go for dynamic memory allocation then you can have
char *buff[100];
Now in the fgets() loop allocate memory to each pointer individually like
buff[i] = malloc(100);
Note here buff is an array of 100 char pointers.
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.
I want to allow users to type the name of any .txt file to be read/written.
This is my code :
printf("Enter .txt file name\n");
scanf("%s",&fname);
FILE *inputf;
inputf=fopen(&fname,"w");
Problem is this method does not work (having &fname) as a parameter.
I can imagine its because C needs "filename.txt" for it work ... even if I enter for example : "custom.txt", the program returns an error of "Storage block not big enough for this operation"
What is the correct method to accomplish this ?
Im using C and im pretty much using basic commands .. (not too advanced)
Thanks alot !!!
The scanf statement will try to store the filename entered as input into the memory, starting from the address passed as its 2nd argument. So you have to allocate/reserve some memory and pass its address to scanf.
As you have not mentioned the type of fname, let me list the possibilities and then answer you.
char fname;
The 2nd argument of scanf and the 1st argument of fopen, both need to be char *. So, passing address of fname or &fname is valid. But it has a problem.
When you declare 'char fname' you are reserving memory for only 1 char. When scanf tries to store the input filename, it will have to write more than 1 char. So eventually you end up overwriting some other memory.
char *fname;
In this case pass fname to both scanf and fopen, instead of '&fname'.
But you have to allocate some memory (e.g. using malloc), before using fname. Otherwise fname will contain some garbage address and scanf will try to overwrite some random memory.
So either declare fname as char fname[N] or char *fname = malloc(N+1); (where N is the maximum possible length of filename you would be entering).
And then, pass fname to both scanf and fopen as follows:
scanf("%s",fname);
inputf = fopen(fname,"w");
Defining fname as a char array, and assuming you expect the filename (without extension) as input (which means you need to append the extension to it):
char fname[128];
printf("Enter .txt file name\n");
scanf("%123s",fname);
strcat(fname,".txt");
FILE *inputf;
inputf=fopen(fname,"w");
Note that an input length check is added to avoid buffer overflow errors in scanf.
I think this can help
#include <stdio.h>
void read_name(char *);
int main(void)
{
char name[BUFSIZ];
char line[BUFSIZ];
FILE *f;
printf("Name ");
read_name(name);
if ( (f=fopen(name,"r"))==NULL)
return -1;
else
return 0;
fclose(f);
}
void read_name(char *s)
{
int i;
fgets(s,BUFSIZ,stdin);
for (i=0; s[i]!='\n'; i++);
s[i]='\0';
return;
}
Try inputf = fopen(fname,"w");.
Also if you want to just read a filename, you can just do sscanf(file,"%s",t) and it will store the filename into t !