Новый и лучший ответ
, Конечно, ColorConverter является способом пойти. Звоните ColorConverter. ConvertFromString и бросок результат. По общему признанию это включит упаковку. Если Вы не хотите упаковывать, создайте словарь, чтобы запуститься с для стандартных имен (все еще использующий ColorConverter) и затем использовать словарь для последующих поисков.
Исходный ответ
Вы могли довольно легко выбрать имена свойства и значения от Система. Windows. Медиа. Цвета однажды в карту:
private static readonly Dictionary KnownColors = FetchColors();
public static Color FromName(string name)
{
return KnownColors[name];
}
private static Dictionary FetchColors()
{
// This could be simplified with LINQ.
Dictionary ret = new Dictionary();
foreach (PropertyInfo property in typeof(Colors).GetProperties())
{
ret[property.Name] = (Color) property.GetValue(null);
}
return ret;
}
Это немного ужасно, но это - одноразовый хит.
sizeof (str)
возвращает размер указателя типа char *
. Что вам нужно сделать, так это указать malloc
размер самой строки:
char * copy = malloc(strlen(str) + 1);
Кроме того, эти строки:
while(*str != '\0'){
*copy = *str;
str++;
copy++;
}
copy = '\0';
Можно легко переписать на C следующим образом:
while(*copy++ = *str++);
Сначала вы должны понять, что sizeof (xxx), где xxx - любое выражение левого значения (переменная), всегда эквивалентно do sizeof ( тип xxx ). Следовательно, на самом деле ваш sizeof (str) возвращает размер char *, то есть размер любого другого указателя. В 32-битной архитектуре вы получите 4, в 64-битной архитектуре - 8 и т. Д.
Итак, как также объяснили другие, вам нужно знать длину строки, которую вы хотите выделить, а затем добавить 1 для хранения терминала \ 0, C неявно используется для помещения в конец строки.
Но для того, чтобы делать то, что вы хотите (скопировать строку и выделить необходимое пространство), будет проще и эффективнее использовать strdup , который делает именно это: malloc и strcopy .
Вы также не должны забывать освободить место, которое вы выделили сами (используя malloc, calloc, strdup или любую другую функцию распределения). В C это не исчезнет, когда выделенная переменная выйдет за пределы области видимости. Он будет использоваться до конца программы. Это то, что вы называете утечкой памяти.
#include <string.h> /* for strdup, strlen */
#include <stdio.h> /* for printf */
int main()
{
char * str = "string";
char * copy = strdup(str);
printf("bytes at least allocated for copy: %d\n", strlen(copy)+1);
printf("%s\n", copy);
free(copy);
}
И последнее: я изменил сообщение на байт, по крайней мере, выделенное , потому что вы действительно не знаете размер, выделенный при вызове malloc. Часто он выделяет немного больше места, чем вы просили. Одна из причин заключается в том, что во многих диспетчерах памяти свободные блоки связаны между собой с использованием некоторой скрытой структуры данных, и любой выделенный блок должен содержать хотя бы такую структуру,
Вы получаете размер указателя str (4 байта), а не то, на что он указывает?
sizeof (str)
возвращает пространство, необходимое для хранения указателя на строку, а не саму строку. Вы можете увидеть размер строки, например, с помощью strlen (str)
.
Затем вы измените свой указатель copy
на целое число, которое имеет значение 0 (символ '\ 0'
). Это то же самое, что copy = NULL
, что показывает вам функция printf ().
Чтобы ответить на второй вопрос, выполнив оператор copy ++
, вы изменили значение copy
(то есть адрес в памяти, содержащий массив char
), так что к тому времени, когда вы его распечатаете, он указывает на конец массива, а не на начало (значение, возвращаемое функцией malloc ()
). Вам понадобится дополнительная переменная, чтобы обновить строку и иметь доступ к началу строки:
Отредактируйте , чтобы исправить проблему malloc / sizeof
- спасибо CL.
char * str = "string";
/* char * copy = malloc(sizeof(str) + 1); Oops */
char * copy = malloc(strlen(str) + 1);
char * original_copy = copy;
printf("bytes allocated for copy: %d\n", sizeof(copy));
while(*str != '\0'){
*copy = *str;
str++;
copy++;
}
copy = '\0';
printf("%s\n", original_copy);
sizeof () возвращает размер фактического типа переменной. Итак, когда вы определяете свой тип как char *, он возвращает размер указателя.
Но если вы сделали свою переменную массивом, sizeof вернет размер самого массива, который будет делать то, что вы хотите:
char *ptr = "moo to you";
char arr[] = "moo to you";
assert(sizeof(ptr) == 4); // assuming 32 bit
assert(sizeof(arr) == 11); // sizeof array includes terminating NUL
assert(strlen(arr) == 10); // strlen does not include terminating NUL
NULL
. copy = '\ 0'
; сбрасывает указатель и делает его NULL
.