2013-04-21 10 views
1

У меня этот странный вопрос с strcspn() в Visual Studio 2012.Странная проблема с strcspn в Visual Studio 2012

Когда я компилирую следующий код как 32 битного Win32 приложение консоли я получаю ожидаемый результат 6.

#include <string> 
#include <iostream> 
#include <cstring> 

int main(int argc, char **argv) 
{ 
    char delimiter_ = ','; 
    std::string css_ = "ESCAPE,,0,0"; 

    printf("%s\n", css_.c_str()); 
    printf("%d\n", strcspn(css_.c_str(), &delimiter_)); 

    size_t lengthOfField = strcspn(css_.c_str(), &delimiter_); 
    printf("%d\n", lengthOfField); 

    std::cin.get(); 

    return 0; 
} 

Однако, если я скомпилирую этот же код для x64, я получаю неожиданный результат 4. Есть ли что-то, что я должен был бы или это ошибка в VS2012? Эта проблема существует при использовании либо cstring, либо string.h для метода strcspn().

В отдельном проекте в какой-то момент проблема существует, но вместо того, чтобы показывать результат 4 в x64, она отображается для Win32, но показывает 6 для x64. В другом файле в этом же проекте проблема такая же, как и выше. Казалось бы, это какой-то UB, но ясно, что данный код может воспроизвести эту проблему, и, насколько я знаю, я не представил здесь UB.

EDIT: После некоторого дальнейшего тестирования, используя cout вместо printf возвращаемых значений также было 0 и 1.

ответ

3

strcspn нужны указатели на строки с нулевым завершением как оба параметра, вам нужно исправить код следующим образом.

char delimiter_[] = ","; 
printf("%d\n", strcspn(css_.c_str(), delimiter_)); 
3

Второго аргумент strcspn, как предполагается, оканчивающимся нуль строки-си. Вы просто передаете ему адрес одного символа. Он будет рассматривать этот единственный символ как начало c-строки, сканируя вперед, пока не найдет нулевой ограничитель. Но так как это не c-строка, и у вас нет прав на любой из символов после первого, это неопределенное поведение.

1

Параметры strcspn должны быть C-стиль строка не один символ.

size_t strcspn(const char *dest, const char *src); 

Затем используйте ниже

std::string delimiter_ = ","; 

strcspn(css_.c_str(), delimiter.c_str()); 
         ^^^^^^^^^^^^^^^^^ 
+1

+1 для начала справа * и * привязка документа к 'strcspn()', который, хотя и хорошо объяснен, другие ответы, казалось бы, были пропущены. – WhozCraig

0

css_.find(delimiter) гораздо проще писать.