Хорошей идеей является использование «объектно-реляционного картографа», подобного Idiorm :
$user = ORM::for_table('user')
->where_equal('username', 'j4mie')
->find_one();
$user->first_name = 'Jamie';
$user->save();
$tweets = ORM::for_table('tweet')
->select('tweet.*')
->join('user', array(
'user.id', '=', 'tweet.user_id'
))
->where_equal('user.username', 'j4mie')
->find_many();
foreach ($tweets as $tweet) {
echo $tweet->text;
}
Он не только избавляет вас от SQL-инъекций, но и от синтаксических ошибок! Также поддерживает коллекции моделей с цепочкой методов для фильтрации или применения действий к нескольким результатам сразу и нескольких подключений.
В C "строки" просто char
массивы. Поэтому Вы не можете непосредственно связать их с другими "строками".
можно использовать эти strcat
функция, которая добавляет строку, на которую указывают src
до конца строки, на которую указывают dest
:
char *strcat(char *dest, const char *src);
Вот пример с cplusplus.com :
char str[80];
strcpy(str, "these ");
strcat(str, "strings ");
strcat(str, "are ");
strcat(str, "concatenated.");
Для первого параметра, необходимо обеспечить сам целевой буфер. Целевой буфер должен быть буфером массива символов. Например: char buffer[1024];
Удостоверяются , что первый параметр имеет достаточно пространства для хранения то, что Вы пытаетесь скопировать в него. При наличии Вам, более безопасно использовать функции как: strcpy_s
и strcat_s
, где явно необходимо определить размер целевого буфера.
Примечание : строковый литерал не может использоваться в качестве буфера, так как это - константа. Таким образом всегда необходимо выделять массив символов для буфера.
возвращаемое значение [1 111] может просто быть проигнорировано, оно просто возвращает тот же указатель, как был передан в как первый аргумент. Это там для удобства и позволяет Вам объединять вызовы в цепочку в одну строку кода:
strcat(strcat(str, foo), bar);
, Таким образом, Ваша проблема могла быть решена следующим образом:
char *foo = "foo";
char *bar = "bar";
char str[80];
strcpy(str, "TEXT ");
strcat(str, foo);
strcat(str, bar);
Если у Вас будет опыт в C, то Вы заметите, что строки являются только массивами символов, где последний знак является нулевым символом.
Теперь, когда довольно неудобно, поскольку необходимо найти последний знак для добавления чего-то. strcat
сделает это для Вас.
, Таким образом, strcat перерывает первый аргумент в пользу нулевого символа. Тогда это заменит это содержанием второго аргумента (пока это не закончится в пустом указателе).
Теперь позволяют нам пройти Ваш код:
message = strcat("TEXT " + var);
Вот, пожалуйста добавление чего-то к указателю на текст "ТЕКСТ" (тип "ТЕКСТА" является константой char*. Указатель.).
, Который не будет обычно работать. Также изменение "ТЕКСТОВОГО" массива не будет работать, поскольку это обычно помещается в постоянный сегмент.
message2 = strcat(strcat("TEXT ", foo), strcat(" TEXT ", bar));
, Который мог бы работать лучше, за исключением того, что Вы снова пытаетесь изменить статические тексты. strcat не выделяет новую память для результата.
я предложил бы сделать что-то вроде этого вместо этого:
sprintf(message2, "TEXT %s TEXT %s", foo, bar);
Read документация sprintf
для проверки, поскольку это - опции.
И теперь важный момент:
Гарантируют, что буфер имеет достаточно пространства для содержания текста И нулевого символа. Существует несколько функций, которые могут помочь Вам, например, strncat и специальные версии printf, которые выделяют буфер для Вас. Не обеспечение размера буфера приведет к повреждению памяти и удаленно годным для использования ошибкам.
Это - неопределенное поведение попытаться изменить строковые литералы, который является что что-то как:
strcat ("Hello, ", name);
попытается сделать. Это попытается лавировать на эти name
строка до конца строкового литерала "Hello, "
, который не четко определен.
Попытка что-то это. Это достигает того, что Вы, кажется, пытаетесь сделать:
char message[1000];
strcpy (message, "TEXT ");
strcat (message, var);
Это создает буферную область, которая является , позволил быть измененным и затем копирует и строковый литерал и другой текст к нему. Просто будьте осторожны с переполнением буфера. Если Вы управляете входными данными (или проверяете его заранее), хорошо использовать буферы фиксированной длины как, я имею.
Иначе, необходимо использовать стратегии смягчения, такие как выделение достаточной памяти от "кучи", чтобы гарантировать, что можно обработать его. Другими словами, что-то как:
const static char TEXT[] = "TEXT ";
// Make *sure* you have enough space.
char *message = malloc (sizeof(TEXT) + strlen(var) + 1);
if (message == NULL)
handleOutOfMemoryIntelligently();
strcpy (message, TEXT);
strcat (message, var);
// Need to free message at some point after you're done with it.
Вы пытаетесь скопировать строку в адрес, который статически выделяется. Вам нужно кошке в буфер.
Конкретно:
... надрез...
место назначения
Pointer to the destination array, which should contain a C string, and be large enough to contain the concatenated resulting string.
... надрез...
http://www.cplusplus.com/reference/clibrary/cstring/strcat.html
существует пример здесь также.
Первый аргумент strcat () должен быть в состоянии содержать достаточно пространства для сцепленной строки. Поэтому выделите буфер с достаточным количеством пространства для получения результата.
char bigEnough[64] = "";
strcat(bigEnough, "TEXT");
strcat(bigEnough, foo);
/* and so on */
strcat () свяжет второй спор с первым аргументом и сохранит результат в первом аргументе, возвращенный символ* является просто этим первым аргументом, и только для Вашего удобства.
Вы не получаете недавно выделенную строку с первым и вторым связанным аргументом, который я предположил бы, что Вы ожидали на основе своего кода.
Не забывайте инициализировать буфер вывода. Первым аргументом strcat должна быть завершенная строка пустого указателя с достаточным дополнительным местом, выделенным для получившей строки:
char out[1024] = ""; // must be initialized
strcat( out, null_terminated_string );
// null_terminated_string has less than 1023 chars
Также malloc и перевыделение полезны, если Вы не знаете заранее, сколько строк связывается.
#include <stdio.h>
#include <string.h>
void example(const char *header, const char **words, size_t num_words)
{
size_t message_len = strlen(header) + 1; /* + 1 for terminating NULL */
char *message = (char*) malloc(message_len);
strncat(message, header, message_len);
for(int i = 0; i < num_words; ++i)
{
message_len += 1 + strlen(words[i]); /* 1 + for separator ';' */
message = (char*) realloc(message, message_len);
strncat(strncat(message, ";", message_len), words[i], message_len);
}
puts(message);
free(message);
}
Люди, используйте strncpy (), кошка str n (), или snprintf ().
Превышение Вашего пространства буфера повредит то, что следует в памяти!
(И не забывают предоставлять пространство для запаздывающих пустых '\0' символов!)
Избегайте использования strcat
в коде C. Самое чистое и, самое главное, самый безопасный путь состоит в том, чтобы использовать snprintf
:
char buf[256];
snprintf(buf, sizeof buf, "%s%s%s%s", str1, str2, str3, str4);
Некоторые комментаторы подняли вопрос, что количество аргументов не может соответствовать строке формата, и код все еще скомпилирует, но большинство компиляторов уже выпускает предупреждение, если это верно.