I'm trying to use strsep to remove extra characters in an CSV file. The problem is that when I run it, it gives me Segmentation Fault and I can't figure out why. Here's the code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <ctype.h>
typedef struct {
int id, followers, following, public_gists;
int public_repos;
char *login;
char *type;
char *created_at;
int *follower_list;
int *following_list;
} *User;
void checkUsersFile();
FILE *createCSV();
void corrigirFicheiro();
User criarUser();
int count = 0;
void checkUsersFile() {
//Ficheiro "users.csv"
FILE *file = fopen("ficheirosG1/users-set2.csv", "r");
//Verifica se o ficheiro "users.csv" existe
if(!file) {
printf("Ficheiro não encontrado");
return;
}
//Cria ficheiro "users-ok.csv"
FILE *newFile = createCSV("users-ok.csv");
corrigirFicheiro(file, newFile);
printf("%d\n", count);
}
//Cria e retorna ficheiro "users-ok.csv"
FILE *createCSV(char *nome) {
FILE *file = fopen(nome, "w");
return file;
}
//Função responsável por intrepretar o ficheiro "users.csv" e colocar os dados corretos no ficheiro "users-ok.csv"
void corrigirFicheiro(FILE *file, FILE *newFile) {
//imprimirPrimeiraLinha(file, newFile);
char string[200000];
//Uma linha do ficheiro com, no máximo, 200.000 caracteres
while ((fgets(string, 200000, file))) {
if (string[0] != '\0') {
//1. Criar user
//2. Print user
User user = criarUser(&string);
if (user != NULL) {
printf("ok\n");
}
free(user);
}
}
//free(string);
}
//Cria um User a partir de uma linha do ficheiro
User criarUser(char *str) {
User novoUser;
novoUser = (User) malloc(sizeof(User));
for(int i = 0; i<10; i++) {
//char *a = strdup(strsep(&str, ";"));
//char *b = strdup(strsep(&a, "\n"));
char *p = strsep(&str, ";\n\r");
if (strlen(p) == 0) {
count++;
free(novoUser);
return NULL;
}
}
return novoUser;
}
int main(){
checkUsersFile();
return 0;
}
Using gdb to debug the code, it says that it occurs in the line if(strlen(p) == 0 {
So it doesn't even enter the switch case.
I don't know why this is happening.
Thank you
I see no reason to think that the
strsep()call is responsible for the error you encounter.This is wrong, however:
and it very likely is responsible for your error.
Useris a pointer type, sosizeof(User)is the size of a pointer, which is not large enough for a structure of the kind that aUserpoints to. When you later try to assign to the members of the structure to which it points (omitted) or to access them inprintUser()(also omitted), you will overrun the bounds of the allocated object. That's exactly the kind of thing that might cause a segfault.An excellent idiom for expressing an allocation such as that uses the receiving variable to establish the amount of space to allocate:
Note that I have also removed the unneeded cast.
As I expressed in comments, however, it is poor style to hide pointer nature behind a
typedef, as yourUserdoes, and personally, I don't much care even for mosttypedefs that avoid that pitfall.Here is how you could do it with a better typedef:
But this is how I would do it, without a typedef: