C: 将字符串转换为 unsigned long long 错误
C: Convert string to unsigned long long Error
我只是想将 String
(从文件中的一行读取)转换为 long long
变量。我的问题是出现分段错误,我不知道为什么...这是代码:(我对“3°调用”函数的错误发表了评论)
#define CAPACITY (unsigned long long) 11
#define INTEGERS_PATH // the path to the file I wish to read
typedef struct {
void** array;
unsigned long long el_num;
unsigned long long array_capacity;
int (*compare)(void*,void*);
} GenericArray;
// used for compare elements
struct record{
char* string_field; // used in case the GenericArray is made of strings items
long long integer_field; // used in case the GenericArray is made of long long items
};
// END OF STRUCTS ---------------------------------------------------------------------------------
// BEGIN OF FUNCTIONS -----------------------------------------------------------------------------
int main(int argc, char const *argv[]) {
test_with_comparison_function(compare_record_int_field);
return (EXIT_SUCCESS);
}
// Compare function passed to generic_array_create() for create the GenericArray
static int compare_record_int_field(void* r1_p,void* r2_p){
if(r1_p == NULL){
fprintf(stderr,"compare_record_int_field: the first parameter is a null pointer");
exit(EXIT_FAILURE);
}
if(r2_p == NULL){
fprintf(stderr,"compare_record_int_field: the second parameter is a null pointer");
exit(EXIT_FAILURE);
}
struct record *rec1_p = (struct record*)r1_p;
struct record *rec2_p = (struct record*)r2_p;
if(rec1_p->integer_field < rec2_p->integer_field){
return(1);
}
return(0);
}
// 1° Call
static void test_with_comparison_function(int (*compare)(void*, void*)) {
GenericArray* array = generic_array_create(compare);
load_array(array);
print_array(array); // it prints the array
free_array(array); // it frees the memory alocated by the array
}
// 2° Call
GenericArray *generic_array_create(int (*compare)(void*,void*)){
GenericArray *array = malloc(sizeof(GenericArray));
if(array == NULL){
fprintf(stderr, "generic_array_create: unable to allocate memory for the generic array");
exit(EXIT_FAILURE);
}
array->array = malloc(CAPACITY * sizeof(void*));
array->el_num = 0;
array->array_capacity = CAPACITY;
array->compare = compare;
return(array);
}
// 3° Call
static void load_array(GenericArray* array){
clock_t start = clock(); // for timing
printf("\nLoading data from file...\n");
FILE * dataset_p = fopen(INTEGERS_PATH, "r");
if(dataset_p == NULL){
fprintf(stderr,"main: unable to open the file");
exit(EXIT_FAILURE);
}
char *read_line_p;
char buffer[1024];
int buf_size = 1024;
while(fgets(buffer, buf_size, dataset_p) != NULL){
read_line_p = malloc((strlen(buffer) + 1) * sizeof(char));
strcpy(read_line_p, buffer);
char *string_field_in_read_line_p = strtok(read_line_p, "\n");
char *integer_field_in_read_line_p = strtok(NULL, "\n");
char *string_field_1 = malloc((strlen(string_field_in_read_line_p) + 1) * sizeof(char));
char *string_field_2 = malloc((strlen(string_field_in_read_line_p) + 1) * sizeof(char));
strcpy(string_field_1,string_field_in_read_line_p);
strcpy(string_field_2,string_field_in_read_line_p);
/* Here begins errors (SEGMENTATION FAULT) */
int integer_field = atoi(integer_field_in_read_line_p);
long long integer_field = strtoll(integer_field_in_read_line_p, (char **) NULL, 10);
struct record *record_p = malloc(sizeof(struct record));
record_p->string_field = string_field_1;
record_p->integer_field = integer_field;
generic_array_add(array, (void*) record_p);
free(read_line_p);
}
fclose(dataset_p);
printf("\nData loaded\n");
}
这是我要读取的文件,它是一个简单的 .txt
文件:
9
8
7
6
5
4
3
2
2
1
10
问题出在这三行:
while(fgets(buffer, buf_size, dataset_p) != NULL){
// ...
char *string_field_in_read_line_p = strtok(read_line_p, "\n");
char *integer_field_in_read_line_p = strtok(NULL, "\n");
fgets
函数读取 一个 行,并在末尾留下换行符 '\n'
。这意味着您尝试标记化的字符串中只有 one '\n'
。所以第二次调用 strtok
应该 return NULL
.
您不检查它,因此对该 NULL
指针的任何取消引用(发生在转换函数中)将导致 undefined behavior 和可能的崩溃。
我只是想将 String
(从文件中的一行读取)转换为 long long
变量。我的问题是出现分段错误,我不知道为什么...这是代码:(我对“3°调用”函数的错误发表了评论)
#define CAPACITY (unsigned long long) 11
#define INTEGERS_PATH // the path to the file I wish to read
typedef struct {
void** array;
unsigned long long el_num;
unsigned long long array_capacity;
int (*compare)(void*,void*);
} GenericArray;
// used for compare elements
struct record{
char* string_field; // used in case the GenericArray is made of strings items
long long integer_field; // used in case the GenericArray is made of long long items
};
// END OF STRUCTS ---------------------------------------------------------------------------------
// BEGIN OF FUNCTIONS -----------------------------------------------------------------------------
int main(int argc, char const *argv[]) {
test_with_comparison_function(compare_record_int_field);
return (EXIT_SUCCESS);
}
// Compare function passed to generic_array_create() for create the GenericArray
static int compare_record_int_field(void* r1_p,void* r2_p){
if(r1_p == NULL){
fprintf(stderr,"compare_record_int_field: the first parameter is a null pointer");
exit(EXIT_FAILURE);
}
if(r2_p == NULL){
fprintf(stderr,"compare_record_int_field: the second parameter is a null pointer");
exit(EXIT_FAILURE);
}
struct record *rec1_p = (struct record*)r1_p;
struct record *rec2_p = (struct record*)r2_p;
if(rec1_p->integer_field < rec2_p->integer_field){
return(1);
}
return(0);
}
// 1° Call
static void test_with_comparison_function(int (*compare)(void*, void*)) {
GenericArray* array = generic_array_create(compare);
load_array(array);
print_array(array); // it prints the array
free_array(array); // it frees the memory alocated by the array
}
// 2° Call
GenericArray *generic_array_create(int (*compare)(void*,void*)){
GenericArray *array = malloc(sizeof(GenericArray));
if(array == NULL){
fprintf(stderr, "generic_array_create: unable to allocate memory for the generic array");
exit(EXIT_FAILURE);
}
array->array = malloc(CAPACITY * sizeof(void*));
array->el_num = 0;
array->array_capacity = CAPACITY;
array->compare = compare;
return(array);
}
// 3° Call
static void load_array(GenericArray* array){
clock_t start = clock(); // for timing
printf("\nLoading data from file...\n");
FILE * dataset_p = fopen(INTEGERS_PATH, "r");
if(dataset_p == NULL){
fprintf(stderr,"main: unable to open the file");
exit(EXIT_FAILURE);
}
char *read_line_p;
char buffer[1024];
int buf_size = 1024;
while(fgets(buffer, buf_size, dataset_p) != NULL){
read_line_p = malloc((strlen(buffer) + 1) * sizeof(char));
strcpy(read_line_p, buffer);
char *string_field_in_read_line_p = strtok(read_line_p, "\n");
char *integer_field_in_read_line_p = strtok(NULL, "\n");
char *string_field_1 = malloc((strlen(string_field_in_read_line_p) + 1) * sizeof(char));
char *string_field_2 = malloc((strlen(string_field_in_read_line_p) + 1) * sizeof(char));
strcpy(string_field_1,string_field_in_read_line_p);
strcpy(string_field_2,string_field_in_read_line_p);
/* Here begins errors (SEGMENTATION FAULT) */
int integer_field = atoi(integer_field_in_read_line_p);
long long integer_field = strtoll(integer_field_in_read_line_p, (char **) NULL, 10);
struct record *record_p = malloc(sizeof(struct record));
record_p->string_field = string_field_1;
record_p->integer_field = integer_field;
generic_array_add(array, (void*) record_p);
free(read_line_p);
}
fclose(dataset_p);
printf("\nData loaded\n");
}
这是我要读取的文件,它是一个简单的 .txt
文件:
9
8
7
6
5
4
3
2
2
1
10
问题出在这三行:
while(fgets(buffer, buf_size, dataset_p) != NULL){
// ...
char *string_field_in_read_line_p = strtok(read_line_p, "\n");
char *integer_field_in_read_line_p = strtok(NULL, "\n");
fgets
函数读取 一个 行,并在末尾留下换行符 '\n'
。这意味着您尝试标记化的字符串中只有 one '\n'
。所以第二次调用 strtok
应该 return NULL
.
您不检查它,因此对该 NULL
指针的任何取消引用(发生在转换函数中)将导致 undefined behavior 和可能的崩溃。