이 질문은 이 주제에 정말 가깝지만 이 솔루션에서 제공해야하는 책임과 포인터 설명을 선호합니다.
그래서 나는 데이터 파일을 가지고 있고 그것으로부터 매우 긴 char 배열을 얻습니다. 이 문자열을 각 경우에이 파일의 한 줄에 해당하는 문자열을 사용하여 배열로 나누고 싶습니다.
해결책을 보았지만 모두 제한된 배열을 사용합니다. 각 줄의 길이를 모르기 때문에 모든 줄을 동적으로 할당해야하지만 strtok
null 문자를 넣지 않기 때문에 줄의 길이를 찾을 수 없습니다. \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] lenght to malloc them ?
}
}
내 파일이 상당히 크고 줄이 너무 클 (strlen(file) + 1) * sizeof(char)
수 있으므로 각 줄이 SIGSEGV가 아닌지 확인하기 위해 크기가 다른 다른 테이블을 malloc하고 싶지 않으며 다른 사람이 있다면이 솔루션이 매우 더럽습니다. 생각하면 정말 행복 할 것입니다.
(영어 실수로 미안 해요, 정말 잘 못해요)
접근 방식 strtok
에는 두 가지 단점이 있습니다. 첫째, strtok
문자열을 수정하므로 원래 문자열을 한 번만 전달할 수 있습니다. 둘째, 그것은 하나의 토큰 분리 자로 nelines의 뻗어나 가기 때문에 빈 줄을 건너 뜁니다 .. (나는 그것이 당신에게 관심사인지 모르겠습니다.)
문자열을 한 번 통과하여 줄 바꿈을 계산할 수 있습니다. 라인 배열에 메모리를 할당하고 두 번째 패스를 만듭니다. 여기서 문자열을 줄 바꿈으로 분할합니다.
char **splitlines(char *msg)
{
char **line;
char *prev = msg;
char *p = msg;
size_t count = 0;
size_t n;
while (*p) {
if (*p== '\n') count++;
p++;
}
line = malloc((count + 2) * sizeof(*line));
if (line == NULL) return NULL;
p = msg;
n = 0;
while (*p) {
if (*p == '\n') {
line[n++] = prev;
*p = '\0';
prev = p + 1;
}
p++;
}
if (*prev) line[n++] = prev;
line[n++] = NULL;
return line;
}
줄 바꿈 개수보다 두 개의 줄 포인터를 더 할당했습니다. 하나는 마지막 줄이 줄 바꿈으로 끝나지 않는 경우를위한 것이고 다른 하나 NULL
는 끝에 센티넬 을 배치하여 배열이 끝나는 위치를 알 수 있습니다. (물론에 대한 포인터를 통해 실제 줄 수를 반환 할 수 size_t
있습니다.)
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다