Strncpy дает нежелательные символы в конце строки - PullRequest
0 голосов
/ 24 июня 2019

По сути, моя программа использует связанные списки для подачи команд роботу. Я использую strcpy() для копирования команд в мою структуру узла связанного списка, но он добавляет ненужные символы в конец (то есть "right" превращается в "right\000-º\rd"). Я использовал strncpy() и пытался выделить память, но все безрезультатно. В моей структуре используемый cmd имеет размер 10, так как когда я инициализировал структуру, я сделал cmd[10] внутри, так как я знаю, что команда никогда не превысит этот размер.


Node *newNode(char cmd[10], int val) {

   Node *newnode = NULL;
   newnode = malloc(sizeof(Node));

   if(cmd == "handup" ||cmd == "handdown" ||cmd == "colour" ||cmd == "forward" ||cmd == "backward" ||cmd == "right" ||cmd == "left")
   {
     strcpy(newnode->cmd, cmd);
     newnode->val = val;
     newnode->next = NULL;
     return newnode;
   }

   else
   {
     printf("Invalid command.\n");
     return NULL;
   }

}

Мне нужно, чтобы он дал мне результат "вправо" или "вперед" и т. Д., Но он продолжает добавлять странные вещи в конец строки, и я не знаю, что делать

1 Ответ

3 голосов
/ 24 июня 2019

ВАЖНОЕ ПРИМЕЧАНИЕ Этот ответ охватывает только некоторые проблем с вашим кодом.Самая большая проблема в том, что вы не показали нам полную программу.Мы не знаем, как выглядит ваш тип Node, и мы не знаем, какую функцию вы используете, которая печатает "right\000-º\rd".

Пожалуйста, прочтите это: https://stackoverflow.com/help/minimal-reproducible-example и обновитеВаш вопрос.

Почему эти персонажи нежелательны?Почему это важно?

A string по определению является "непрерывной последовательностью символов, оканчивающихся на первый нулевой символ и включающий его".Если у вас есть массив массива char[10], содержащий

{ 'h', 'e', 'l', 'l', 'o', '\0', '?', '$', '\xff', '!' }

, тогда этот массив содержит строку длиной 5, "hello".

strcpy, копирует строки и просто игнорирует любыебайты после завершающего нулевого символа, которые не являются частью строки.strncpy похоже, но это не совсем строковая функция, и она может быть опасной, если вы не очень осторожны;см. эту мою статью для получения дополнительной информации.

Для большинства приложений вы можете просто игнорировать все, что находится за завершающим символом '\0'.Каждая строковая функция будет игнорировать эти данные, поскольку она не является частью строки.

Если у вас есть причина заботиться о том, что следует за символом '\0' (часть массива, но не часть строки)Вы можете установить его на '\0'.Самый простой способ - использовать memset для установки этих байтов на ноль.

Еще несколько замечаний о вашем коде:

Node *newNode(char cmd[10], int val) {

Ваш параметр cmd имеет тип char*,не char[10].Это параметр указателя, а не параметр массива (C не имеет параметров массива).

if(cmd == "handup" ...

Это сравнение указателей, а не сравнение строк (на что указывает комментарий Мэнса Рейдера).Указатели, вероятно, будут неравными.Используйте strcmp для сравнения строк.(При более внимательном рассмотрении, если cmd был передан как строковый литерал, и , если ваш компилятор разделил пространство для идентичных строковых литералов, тогда == может быть верным. Мы не видели всю вашу программу, поэтому трудно быть уверенным.)

Например, это:

if ("hello" == "hello") puts("equal"); else puts("unequal");

может печатать либо equal, либо unequal.

Ваш NodeТип, вероятно, является структурой, содержащей char* член cmd.Вы не выделяете память для строки, на которую будет указывать newnode->cmd.

Рекомендуемое чтение: разделы 6 и 8 comp.lang.c FAQ .(И все остальное.)

...