#c #xv6
#c #xv6
Вопрос:
Я изучаю C в ограниченной ОС (xv6), которая имеет только подмножество C. Я пытаюсь разделить одну строку на массив строк.
Для этого я создал массив указателей на строки lines
. Я ожидаю, что строки в конечном итоге будут выглядеть так: lines = { "abc", "def", "ghi" }
Когда я пытаюсь получить доступ к строкам по индексу (например, строки [0]) Я получаю null
. Я в тупике, почему я получаю null, и попробовал несколько вещей. Я почти уверен, что упускаю что-то очень очевидное.
Примечание: не ищу рабочий код, так как я хотел бы продолжить его создание самостоятельно, но был бы признателен за некоторые указания о том, почему я получаю этот результат.
#define STDIN 0
#define STDOUT 1
static void readline(){
char buff[] = "abcndefnghi";
int i,j;
char current[20];
char *lines[20];
int counter = -1;
int lines_counter = -1;
for(i = 0; i < 14; i ) {
if(buff[i] == 'n' || buff[i] == ''){
lines_counter ;
for(j = 0; j < 4; j ) {
lines[lines_counter][j] = current[j];
}
counter = -1;
} else {
current[ counter] = buff[i];
}
}
printf(STDOUT, "%s", lines[0]); // expected "aaa", instead output is(null)
}
int main(int argc, char *argv[]) {
readline();
exit();
}
Комментарии:
1.
lines[lines_counter][j]
также неинициализированный доступ к памяти.2. Другими словами
lines
, это массив из 20 указателей, каждый из которых указывает в никуда и в настоящее время неинициализирован. Вы должны назначить указателю допустимое хранилище, прежде чем сможете начать хранить в нем символы. Хранилище назначается либо путем динамического выделения хранилища для каждого указателя с помощьюmalloc
,calloc
, илиrealloc
, или путем назначения каждому указателю начального адреса для существующего массива. ( примечание: каждый указатель в строках может указывать на другой существующий символ внутриbuf
, а затем заменять'n'
s в buf на''
и использоватьbuf
в качестве существующего хранилища)3. К вашему сведению,
counter
lines_counter
не нужно ни инициализировать значение -1, ни сбрасывать значение -то же самое, если вы структурировали свои циклы с большей степенью разумности. На самом деле, это упростит написание и чтение кода, если вы выясните, как следует начинать с нуля и когда увеличивать каждый / любой. Несмотря на это, этот код был предназначен для запуска в отладчике, одношагового и просмотра переменных / памяти, чтобы понять, что вы написали, и, следовательно, чем это отличается от того, что вы намеревались.4. Для использования спецификатора формата %s строка должна заканчиваться нулем. Поэтому вам нужно добавить символ ‘ 0’.
5. @DavidC.Rankin Это была именно проблема. Спасибо за совет, я пришел с языка более высокого уровня, который не требует явного выделения памяти. Я потратил время, чтобы узнать больше о malloc, calloc и realloc.
Ответ №1:
Я бы посоветовал просто посмотреть исходный код strtok
и попробовать расширить любые стандартные вызовы библиотеки. strchr
это просто поиск символа в строке и strcspn
просто подсчитывает количество символов перед strchr
возвратом.