这个问题与this topic非常接近,但我更喜欢这个解决方案提供的可行性和指针说明。
我有一个数据文件,我从它得到一个很长的字符数组,我想把这个字符串分成一个数组,每个数组中,都有一个字符串,对应于这个文件中的一行。
我看到了解决方案,但它们都使用了有限的数组,因为我不知道每行的长度,我真的需要动态分配所有的数组,但我找不到行的长度,因为strtok
没有在每个字符串的末尾放一个空字符\0
。
我现在有两个解决方案,但都不起作用:
int get_lines(char *file, char **lines) {
int nb_lines = 0;
char *token = strtok(file, "\n");
for(int i = 0; token != NULL; i++) {
token = strtok(NULL, "\n");
nb_lines = i;
}
nb_lines++;
lines = malloc((nb_lines + 1) * sizeof(char*));
lines[nb_lines] = '\0';
token = strtok(file, "\n");
for(int i = 0; token != NULL; i++) {
token = strtok(NULL, "\n");
int nb_char = 0;
for(int j = 0; token[j] != '\n'; j++) //This will cause SIGSEGV because strtok don't keep the '\n' at the end
nb_char = j;
nb_char++;
token[nb_char] = '\0'; //This cause SIGSEGV because token's allocation finish at [nb_char-1]
lines[i] = malloc(strlen(token) * sizeof(char)); //strlen cause SIGSEGV because I cannot place the '\0' at the end of token
printf("%s", token); //SIGSEGV because printf don't find the '\0'
lines[i] = token;
}
for(int i = 0; i < nb_lines; i++) {
printf("%s", lines[i]); //SIGSEGV
}
return nb_lines;
}
字符串
所以你可以看到上面的想法,我想做什么,为什么它不工作。
下面你会看到我做的另一个尝试,但我被困在同一点:
int count_subtrings(char* string, char* separator) {
int nb_lines = 0;
char *token = strtok(string, separator);
for(int i = 0; token != NULL; i++) {
token = strtok(NULL, separator);
nb_lines = i;
}
return nb_lines + 1;
}
char** split_string(char* string, char* separator) {
char **sub_strings = malloc((count_subtrings(string, separator) + 1) * sizeof(char*));
for(int i = 0; string[i] != EOF; i++) {
//How to get the string[i] length to malloc them ?
}
}
型
我的文件很大,行太多,所以我不想malloc另一个大小为(strlen(file) + 1) * sizeof(char)
的表,以确保每行不会SIGSEGV,我也发现这个解决方案很脏,如果你们有其他想法,我会很高兴。
(英语:I'm not really good)
2条答案
按热度按时间avkwfej41#
使用
strtok
的方法有两个缺点:第一,strtok
修改字符串,因此您只能传递一次原始字符串;第二,它跳过空行,因为它将nlines的延伸视为单个标记分隔符..(我不知道您是否关心这一点)。你可以通过一次遍历字符串来计算新行的数量。为你的行数组分配内存,然后进行第二次遍历,在那里你在新行处分割字符串:
字符串
我已经分配了两个比换行符计数多的行指针:一个用于最后一行没有以换行符结束的情况,另一个用于在末尾放置
NULL
标记,这样你就知道你的数组在哪里结束(当然,你可以通过指向size_t
的指针返回实际的行数)。px9o7tmv2#
下列拟议守则:
1.干净地编译
1.(在堆大小的限制内)不关心输入文件的大小
printf()
替换puts()
现在代码
字符串
假设上面的代码在一个名为:
untitled1.c
的文件中,则输出如下。型