strdup () функция

У вас есть синтаксическая ошибка, замените на:

UPDATE library_students.book SET CopiesInBorrow= ?, AvailableCopies=? WHERE BookID=?

Не используйте AND между столбцами, которые вы хотите обновить. Вы можете использовать AND в части WHERE, чтобы применить необходимые условия.

Если вы хотите что-то вроде этого:

UPDATE library_students.book SET CopiesInBorrow= ? WHERE AvailableCopies=? AND BookID=?

, тогда использование AND будет допустимым.

Из вашего кода я вижу, что вы просто хотите увеличить значение столбца и уменьшить еще один. Вам не нужно сначала находить эти значения в таблице, а затем вносить изменения.

Вы можете выполнить это утверждение:

UPDATE library_students.book SET CopiesInBorrow = CopiesInBorrow + 1, AvailableCopies = AvailableCopies - 1 WHERE BookID = ?

Так что измените на это:

public void updateFields(BorrowedBook borrowedBook) throws SQLException {
    PreparedStatement pstmt;
    try {
        Statement stmt = con.createStatement();
        pstmt = con.prepareStatement("UPDATE library_students.book SET CopiesInBorrow = CopiesInBorrow + 1, AvailableCopies = AvailableCopies - 1 WHERE BookID = ?");
        pstmt.setString(1, getBookID(borrowedBook));
        pstmt.executeUpdate();
        rs.close();
    }catch (SQLException ex) {
        ex.printStackTrace();
    }
} 
15
задан kiamlaluno 13 July 2010 в 11:18
поделиться

7 ответов

Обычно, Вы просто используете #if для определения функции, которую Вы хотите когда в соответствии с определенным компилятором. Если встроенная библиотека не определяет strdup, нет никакой проблемы в определении его самостоятельно (кроме того, если они действительно определяют его в будущем, необходимо будет вынуть его.)

// Only define strdup for platforms that are missing it..
#if COMPILER_XYZ || COMPILER_ABC
char *strdup(const char *)
{
   // ....
}
#endif
20
ответ дан 1 December 2019 в 01:06
поделиться

Вы могли просто использовать макрос как это, этот способ, которым можно использовать старое название, но компоновщик будет видеть другое имя;

char *my_strdup(const char *s) {
    char *p = malloc(strlen(s) + 1);
    if(p) { strcpy(p, s); }
    return p;
}

/* this goes in whatever header defines my_strdup */
char *my_strdup(const char *s);
#define strdup(x) my_strdup(x)
6
ответ дан 1 December 2019 в 01:06
поделиться

К вашему сведению: я лично никогда не видел среду, которая не определила strdup ().

2
ответ дан 1 December 2019 в 01:06
поделиться

Необходимо также рассмотреть предотвращение создания любого идентификатора (включая функцию), который начинается с ул. [a-z]. В то время как это не резервируется, стандартный раздел (ISO/IEC 9899:1999) C 7.26.11 (будущие направления библиотеки) состояния "Имена функций, которые начинаются с ул., мадам, или wcs и строчная буква могут быть добавлены к объявлениям в заголовке".

3
ответ дан 1 December 2019 в 01:06
поделиться

a), Что происходит, когда я пишу свою собственную функцию с тем же именем как встроенная функция?

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

b), Что я могу сделать для предотвращения плохих вещей, происходящих со мной на платформах, которые не имеют strdup (), не переписывая весь мой код для не использования strdup (), который просто немного утомителен?

я рекомендовал бы создать Ваше собственное функция обертки к strdup и заменить все Ваши вызовы для использования новой функции обертки. Например:

char *StringDuplicate(const char *s1)
{
#ifdef POSIX
    return strdup(s1);
#else
    /* Insert your own code here */
#endif
}

Изменение всех Ваших вызовов от strdup до StringDuplicate () должно быть простым, находят и заменяют операцию, делая это выполнимым подходом. Определенная для платформы логика будет затем сохранена в единственном месте вместо того, чтобы быть рассеянной всюду по Вашей кодовой базе.

4
ответ дан 1 December 2019 в 01:06
поделиться

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

Затем Вы просто помещаете в своем заголовочном файле:


#ifndef HAVE_STRDUP
# ifdef HAVE__STRDUP
#  define strdup _strdup
# else
#  define strdup my_strdup
# endif
#endif

, Если strdup уже существует на целевой платформе, libc версия используется, если не Ваша пользовательская функция my_strdup будет использоваться.

РЕДАКТИРОВАНИЕ: Я должен был добавить explination, почему это лучше.

Сначала компилятор не связан с существованием функции в libc. Например, возьмите функцию strlcpy. Это присутствует на FreeBSD, но не на Linux (glibc), хотя оба используют gcc по умолчанию. Или что происходит, если кто-то собирается скомпилировать Ваш код с лязгом?

117-секундный проверка платформы (я не знаю, существует ли стандартный путь) будет только работать, если Вы явно добавляете для каждой платформы, Вы хотите поддерживать корректное условное выражение препроцессора. Так принятие Вас освоило для компиляции приложения на OSX и Win32, и Вы хотите скомпилировать его теперь на Linux, необходимо будет пройти все условные выражения препроцессора, чтобы видеть, работают ли они на Linux. Возможно, Вы также хотите поддерживать FreeBSD, OpenBSD, и т.д.? Та же работа снова. С тестом в Ваших сценариях здания это может скомпилировать без любой дополнительной работы.

6
ответ дан 1 December 2019 в 01:06
поделиться

Если кто-то еще читает это: Не используйте strdup() платформы, даже если он доступен, и не тратьте время/усилия на autoconf/automake только для того, чтобы использовать его. Серьезно, насколько это сложно:

char* mystrdup(const char* str)
{
 return strcpy(malloc( strlen(str) + 1),str);
}

Действительно ли это требует #ifdefs? Проверки компилятора? K.I.S.S.

-2
ответ дан 1 December 2019 в 01:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: