I have code which is giving me a segmentation fault. I debugged it and and the error occurred when the strcpy executed. The code is attempting to extract data from a text file and store it into an array of structs. I plan to use strcpy to store the store the text file's data into the structs. Any idea why this is occurring?
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int input( char *s, int length);
void main(){
char *tok;
char *buffer;
size_t bufsize = 32;
size_t characters;
FILE *f;
char *file_name;
char line[255];
int currentRoom;
int count = 0;
typedef struct {
char room_n;
char description[100];
char room_north;
char room_south;
char room_west;
char room_east;
} room;
//Creating an array of structs
room record[1000];
while(1){
buffer = (char *)malloc(bufsize * sizeof(char));
if(buffer == NULL){
perror("Unable to allocate buffer");
exit(1);
}
printf("Enter a command: ");
characters = getline(&buffer, &bufsize, stdin);
if(strcmp(buffer,"exit\n") == 0){
printf("Exiting...\n");
exit(1);
}
tok = strtok(buffer, " \n"); // Tokenize input
printf("%s is the token \n", tok);
if (strcmp(tok,"loaddungeon") == 0){
file_name = strtok(NULL, "\n");
printf("file name : %s \n", file_name);
f = fopen(file_name,"r");
while (fgets(line, sizeof(line), f) != NULL)
{
char val1[128];
char val2[128];
char val3[128];
char val4[128];
char val5[128];
char val6[128];
strcpy(val1, strtok(line, "$"));
strcpy(val2, strtok(NULL, "$"));
strcpy(val3, strtok(NULL, " "));
strcpy(val4, strtok(NULL, " "));
strcpy(val5, strtok(NULL, " "));
strcpy(val6, strtok(NULL, " "));
//Segmentation fault error occurs here
strcpy(record[count].room_n, val1);
Definition of strcpy() is:
char *strcpy(char *dest, const char *src)
where-
dest -- This is the pointer to the destination array where the
content is to be copied.
src -- This is the string to be copied.
In your code arguments passed to strcpy() is char and char * :
strcpy(record[count].room_n, val1);
As defined in the structure:
typedef struct {
char room_n; //room_n declared as 'char'
char description[100];
char room_north;
char room_south;
char room_west;
char room_east;
} room;
Suggestion:
Allocate memory for room_n to point to. Change the declaration to
char room_n[128];
Related
We added print statements to check where the segmentation fault was happening. It fails at strcpy(command, token);
How can we store that part into command? Also is there a way to check for the null character at the end of token? Does strtok() have a null character at the end when used?
int main(int argc, char **argv)
{
char *command, *flag, *pathname, *linkname;
struct stat st = {0};
char cmd[200];
char *token; //Pointer
int counter = 1; //Counter variable
FILE *fp;
char mode2[] = "0750"; //To set the permission of a file/path
long j;
char mode[] = "0640"; //To set the permission of a file/path
long i;
fgets(cmd, 200, stdin);
printf("print for cmd: %s\n", cmd);
//User input is tokenized to determine the proper commands are entered and executed
token = strtok(cmd, " "); //Input is tokenized by white spaces.
printf("token: %s\n", token);
strcpy(command, token);
printf("print for command: %s\n", command);
if(token == NULL)
{
printf("Error with command input.\n");
exit(EXIT_FAILURE);
}
You never assign a value to command, much less allocate space for it to point to.
You need to initialize you *command variable before assigning a value to it with strcpy(). The segmentation fault will happen if you try to assign a value to a NULL pointer.
A correct use of strcpy() would be like this:
char *str = malloc(3 * sizeof(char));
char sentence[3] = "Hi\0";
strcpy(str, sentence);
printf("%s\n", str);
I am writing a program where I must define my own versions of the following functions:
int AtoI ( const char * str );
int StrCmp ( const char * str1, const char * str2 );
char * StrCpy ( char * destination, const char * source );
char * StrCat ( char * destination, const char * source );
char * StrChr ( char * str, int character );
Inside the main function, I am required to declare an array called wordlist of type myWord of size 20. Then, using the strtok() library function, extract each word from the string MyString and store it in wordlist. However, I keep getting the error message:
incompatible type for argument 1 of ‘strcpy’
for the line:
strcpy(wordlist[i], token);
How do I fix this problem? So far, this is what I have:
#include <stdio.h>
#include <string.h>
struct myWord{
char word[21];
int length;
};
int main(void){
typedef struct myWord myword;
int i = 0;
myword wordlist[20];
char *myString = "the cat in the hat jumped over the lazy fox";
char *token;
token = strtok(myString, " ");
while(myString != NULL){
strcpy(wordlist[i], token);
token = strtok(NULL, " ");
printf("%s\n", wordlist[i]);
i++;
}
}
The corrected code is
#include <stdio.h>
#include <string.h>
typedef struct myWord{
char word[21];
int length;
}myword;
int main(void){
int i = 0;
myword wordlist[20];
char myString[] = "the cat in the hat jumped over the lazy fox";
char *token;
token = strtok(myString, " ");
while(token != NULL){
strcpy(wordlist[i].word, token);
token = strtok(NULL, " ");
printf("%s\n", wordlist[i].word);
i++;
}
}
C-string member of your struct is word, so you must pass that member to strcpy and printf
Your loop must check token returned by strtok to check if the end of string was reached
strtok modify your string to do the job, so the string must be modifiable, you cannot use a pointer to a string literal.
I have to put the data from a csv file (name, address, telephone...) to a structure of my C program. It's been unsuccessful, unfortunately. I tried using strtok function to break into tokens every time it finds a ";" (because we're dealing with a Comma Separated File).
Here's what I've done:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define MAX_STR_LEN 256
#define MAX_BOOKS 256
struct estrutura
{
int id;
char nome[40];
char endereco[40];
char cidade[40];
char pais[20];
char cep[10];
char nasc[12];
char telefone[14];
char total[20];
};
struct estrutura cliente[200];
FILE *pFile;
//allocate buffer in each line
char *buf = malloc(MAX_STR_LEN);
char *tmp;
void abrir();
/* Functions to be coded
int menu();
int menu2(); //manutencao de clientes
void adicionar();
void alterar();
void excluir();
void exibir();
void pesquisar(); */
main()
{
system("cls");
abrir();
//menu();
}
void abrir() //open the csv file and copy it to
{
/* FileStream for the Library File */
FILE *pFile;
/* allocation of the buffer for every line in the File */
char *buf = malloc(MAX_STR_LEN);
char *tmp;
/* if the space could not be allocated, return an error */
if (buf == NULL) {
printf ("No memory\n");
}
if ( ( pFile = fopen( "control.csv", "r" ) ) == NULL ) //Reading a file
{
printf( "File could not be opened.\n" );
}
int i = 0;
while (fgets(buf, 255, pFile) != NULL)
{
if ((strlen(buf)>0) && (buf[strlen (buf) - 1] == '\n')) //checa leitura
buf[strlen (buf) - 1] = '\0';
tmp = strtok(buf, ";");
cliente[i].id = atoi(tmp); //atoi for int
tmp = strtok(NULL, ";"); //use strcpy for char
strcpy(cliente[i].nome,tmp);
tmp = strtok(NULL, ";");
strcpy(cliente[i].endereco, tmp);
tmp = strtok(NULL, ";");
strcpy(cliente[i].cidade, tmp);
tmp = strtok(NULL, ";");
strcpy(cliente[i].pais, tmp);
tmp = strtok(NULL, ";");
strcpy(cliente[i].cep, tmp);
tmp = strtok(NULL, ";");
strcpy(cliente[i].nasc, tmp);
tmp = strtok(NULL, ";");
strcpy(cliente[i].telefone, tmp);
tmp = strtok(NULL, ";");
strcpy(cliente[i].total, tmp);
//tempBook.ID = atoi(buf); fix below
printf("%i, %s, %s, %s, %s, %s, %s, %s, %s \n",i, cliente[i].id , cliente[i].nome, cliente[i].endereco, cliente[i].cidade, cliente[i].pais, cliente[i].cep, cliente[i].nasc, cliente[i].telefone, cliente[i].total);
i++;
}
//free(buf);
fclose(pFile);
}
How can I solve this problem? I can't successfully copy the data from 100 clients in the csv to a structure.
Thank you since now!
There are three main problems here:
The format string in printf("%i, %s, %s, %s, ...) doesn't match the parameters, you need one more %i: printf("%i, %i, %s, %s, %s, ...).
In your code you never call abrir() but you call menu(), which doesn't exist, therefore your code doesn't even compile.
If you are on Windows (and only then) you need fopen(..., "rt")) instead of fopen(..., "r"))
Furthermore (not causing actual problems in your code):
char *buf = malloc(MAX_STR_LEN); can be replaced by char buf[MAX_STR_LEN];. It's pointless to allocate memory dynamically if the amount of memory is known at compile time. In that case you must of course not call free(buf) (which is commented out anyway).
Following declarations just after struct estrutura cliente[200]; are useless, you can remove them.
FILE *pFile;
//allocate buffer in each line
char *buf = (char*)malloc(MAX_STR_LEN);
char *tmp;
Otherwise the program should work fine unless your input file has fields that are larger than the field in your struct estrutura.
I realize this question has been asked often but I still dont really understand how it works. I want to try and read my file into my structures, inside a function and pass the structures through pointers to the function. I am unsure about how to even write the function prototype.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 90
#define STR 200
#define MAXLEN 40
struct human {
char name[MAXLEN];
char surname[MAXLEN];
int age;
float weight;
};
int main(int argc, char *argv[]) {
char *dlim= " ", *end = "\n";
char *string;
string = (char *)malloc(sizeof(char) * STR);
int i = 0, j = 0;
struct human *man = malloc(sizeof(struct human) * MAX);
FILE *fin = fopen("data.txt", "r");
if (fin == NULL) {
printf("Cannot open file\n");
exit(0);
}
while (fgets (string, STR, fin)){
read (string, &man[i], dlim, end);
i++;
}
fclose(fin);
free(string);
free(man);
return 0;
}
struct human *man read(char *fstring, struct *man, char *div, char *end){
int i=0;
char *tok;
tok = strtok(string, dlim);
strcpy(man[i].name, tok);
tok = strtok(NULL, dlim);
strcpy(man[i].surname,tok);
tok = strtok(NULL, dlim);
man[i].age = atoi(tok);
tok = strtok(NULL, end);
man[i].weight = atof(tok);
return man[i];
}
Whats the function meant to look like? And am i correct in assuming that through the use of pointers, the struct will be automatically be updated in main, without needing to return something in the function?
Can the function also return nothing (void), because the use of pointers will automatically pass onto main?
Thank you!
Your code is close but the pointer logic in the subroutine that fills in the human structure is incorrect. See if the following rework, and slight simplification, helps you understand how to pass the structure:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXIMUM_HUMANS 90
#define MAXIMUM_INPUT_STRING_LENGTH 200
#define MAXIMUM_STRING_LENGTH 40
struct human {
char name[MAXIMUM_STRING_LENGTH];
char surname[MAXIMUM_STRING_LENGTH];
int age;
float weight;
};
void initialize_human(char *string, struct human *man, char *delimiter, char *end) {
char *token;
token = strtok(string, delimiter);
strcpy(man->name, token);
token = strtok(NULL, delimiter);
strcpy(man->surname, token);
token = strtok(NULL, delimiter);
man->age = atoi(token);
token = strtok(NULL, end);
man->weight = atof(token);
}
int main(int argc, char *argv[]) {
char *dlim= " ", *end = "\n";
char string[MAXIMUM_INPUT_STRING_LENGTH];
struct human humans[MAXIMUM_HUMANS];
FILE *fin = fopen("data.txt", "r");
if (fin == NULL) {
fprintf(stderr, "Cannot open file\n");
exit(1);
}
int population; // after loop, this contains total body count
for (population = 0; fgets(string, MAXIMUM_INPUT_STRING_LENGTH, fin); population ++) {
initialize_human(string, &humans[population], dlim, end);
}
printf("population: %d\n", population);
printf("last added: %s who weighs %f\n", humans[population - 1].surname, humans[population - 1].weight); // test if we loaded it up correctly
fclose(fin);
return 0;
}
This question already has answers here:
Reading and parsing lines from a file with fgets and strtok
(2 answers)
Closed 7 years ago.
I am trying to put textfile to the struct
have issues with assigning values form text file to the struct, it keeps printing me the last value being printed incompletely.
Can you kindly help me out with the issue?
Thank you in advance.
#include <stdio.h>
#include <stdlib.h>
#define MAX_LEN 422498
#define MAX_KEY 128
struct record
{
char* a;
char* b;
};
int main(int argc, char **argv){
char* input=argv[1];
char* output=argv[2];
char* buff[MAX_LEN];
char *delimiter = ";";
//printf("%s\n",input);
//printf("%s\n",output);
FILE *fp;
fp = fopen(input, "r"); //opening file*/
if( fp == NULL )
{
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
int rowsNum=0;
struct record* recArr = malloc(3 * sizeof (struct record));
//struct record recArr[4];
//recArr=malloc(1 * 2*sizeof(char*));
/*recArr[0].a="aa";
recArr[0].b="bb";
recArr[1].a="cc";
recArr[1].b="dd";
recArr[2].a="ee";
recArr[2].b="ff";
printf("%s\n", recArr[0].a);
printf("%s\n\n", recArr[0].b);
printf("%s\n", recArr[1].a);
printf("%s\n\n", recArr[1].b);
printf("%s\n", recArr[2].a);
printf("%s\n\n", recArr[2].b);*/
while (fgets(buff, MAX_LEN, (FILE*)fp)!=NULL)
{
//recArr=realloc(recArr, (rowsNum+1) * 2*sizeof(char*));
//char* Key = strtok(buff, delimiter);
//char* Value = strtok(NULL, delimiter);
recArr[rowsNum].a=strtok(buff, delimiter);
recArr[rowsNum].b=strtok(NULL, delimiter);
printf("%s\n", recArr[rowsNum].a);
printf("%s\n\n", recArr[rowsNum].b);
/*Key=NULL;
Value=NULL;*/
rowsNum++;
printf("%d\n", rowsNum);
}
fclose(fp);
int i;
for (i=0;i<3;i++)
{
printf("%s\n", recArr[i].a);
printf("%s\n\n", recArr[i].b);
}
//printf("%d\n", rowsNum);
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h> // this is needed to use strtok function (and strlen, strcpy)
#define MAX_LEN 422498
#define MAX_KEY 128
struct record
{
char* a;
char* b;
};
int main(int argc, char **argv){
char* input=argv[1];
char* output=argv[2];
char buff[MAX_LEN]; // buff should be char[MAX_LEN], not char*[MAX_LEN]
char *delimiter = ";";
//printf("%s\n",input);
//printf("%s\n",output);
FILE *fp;
fp = fopen(input, "r"); //opening file*/
if( fp == NULL )
{
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
int rowsNum=0;
struct record* recArr = malloc(3 * sizeof (struct record));
//struct record recArr[4];
//recArr=malloc(1 * 2*sizeof(char*));
/*recArr[0].a="aa";
recArr[0].b="bb";
recArr[1].a="cc";
recArr[1].b="dd";
recArr[2].a="ee";
recArr[2].b="ff";
printf("%s\n", recArr[0].a);
printf("%s\n\n", recArr[0].b);
printf("%s\n", recArr[1].a);
printf("%s\n\n", recArr[1].b);
printf("%s\n", recArr[2].a);
printf("%s\n\n", recArr[2].b);*/
while (fgets(buff, MAX_LEN, (FILE*)fp)!=NULL)
{
//recArr=realloc(recArr, (rowsNum+1) * 2*sizeof(char*));
//char* Key = strtok(buff, delimiter);
//char* Value = strtok(NULL, delimiter);
//recArr[rowsNum].a=strtok(buff, delimiter);
//recArr[rowsNum].b=strtok(NULL, delimiter);
// you have to COPY the string
char* a=strtok(buff, delimiter);
char* b=strtok(NULL, delimiter);
recArr[rowsNum].a = malloc(sizeof(char) * (strlen(a) + 1)); // +1 for terminating '\0'
recArr[rowsNum].b = malloc(sizeof(char) * (strlen(b) + 1));
strcpy(recArr[rowsNum].a, a);
strcpy(recArr[rowsNum].b, b);
printf("%s\n", recArr[rowsNum].a);
printf("%s\n\n", recArr[rowsNum].b);
/*Key=NULL;
Value=NULL;*/
rowsNum++;
printf("%d\n", rowsNum);
}
fclose(fp);
int i;
for (i=0;i<3;i++)
{
printf("%s\n", recArr[i].a);
printf("%s\n\n", recArr[i].b);
}
//printf("%d\n", rowsNum);
// you should free the allocated buffer
for (i=0;i<3;i++)
{
free(recArr[i].a);
free(recArr[i].b);
}
free(recArr);
}
string.h should be included to use strtok : GCC made some warnings about it.
the type of buff was not proper: it should be char buff[MAX_LEN], not char* buff[MAX_LEN](an extra asterisk is there)
the function strtok modifies the buffer given and returns the pointer that is pointing somewhere in the buffer. When reading the next line, the buffer is overwritten and the text previously read is lost unless it is copied to somewhere. For that reason, I added some code that copies the strings read and save pointers that points where the strings are copied instead of somewhere in buff.