2013-02-12 3 views
0

Я хочу дать пользователю возможность указать один файл (здесь ground_truth_filename). Если он не укажет этот параметр, я хочу сделать предположения о имени файла по умолчанию.условия проверки на char * filename

Однако, я не могу проверить, ground_truth_filenameNULL или ноль, хотя я инициализировал его как 0 в основной программе. Если аргумент передается пользователем, я присваиваю этому аргументу ground_truth_filename. Но проверка ground_truth_filename == 0 дает мне ошибку утверждения.

Любая помощь будет оценена по достоинству.

int processFile(const char *filename, 
       YAML::Emitter &out_yaml, 
       char *ground_truth_filename) 
{ 
    std::cout << "Here" << std::endl; 

    if (ground_truth_filename == 0) 
     sprintf(ground_truth_filename,"%s.yaml",filename);   

    std::ifstream imgstrm(filename, std::ios::binary | std::ios::in); 

    if (imgstrm.bad() || !imgstrm.is_open()) 
    { 
     fprintf(stderr, "Failed to open file: %s\n", filename); 
     return FILE_ERROR; 
    } 

    // get ground truth 
    std::ifstream ground_truth_stream(ground_truth_filename); 

    if (!ground_truth_stream.is_open()) 
    { 
     fprintf(stderr, "Failed to open file: %s\n", ground_truth_filename); 
     return FILE_ERROR; 
    } 
} 

Вот как называется функция. Возможно, я должен инициализировать ground_truth_filename = '\ 0'?

char *ground_truth_filename = 0; 
for (int i = 1; i + 1 < argc; i += 2) { 
      if (!strcmp(argv[i], "--snapshot-markup")) { 
       ground_truth_filename = argv[i + 1]; 
       markupFlag = true; 
      } 
     } 
processFile(filename, out_yaml, ground_truth_filename) 
+3

'if (pointer == NULL) {sprintf (указатель," foo "); } ', безусловно, неверно. – 2013-02-12 18:04:08

+0

'if (NULL! = Ground_truth_filename && '\ 0' == * ground_truth_filename)' – SparKot

+0

Какова логика для NULL! = Ground_truth_filename && '\ 0' == * ground_truth_filename? – vkaul11

ответ

0

Перед тем, как скопировать в него символы, вам необходимо выделить ground_truth_filename.

if (ground_truth_filename == 0) 
    { 
    int length = strlen(filename) + strlen(".yaml") + 1; 
    ground_truth_filename = new char[length]; 
    sprintf(ground_truth_filename,"%s.yaml",filename); 
    } 
+0

Не зная, какие 'filename' и' ground_truth_filename' передаются в качестве и как они должны быть возвращены (оба очень неясны из исходного сообщения), трудно сказать, поможет ли этот код. –

+0

Nik, я также добавил свой звонок выше. – vkaul11

+0

Ответ на dspeyer ниже поможет решить вашу проблему. В основном вы пытаетесь «sprintf» что-то в буфер NULL. Этот ответ тоже, но он требует, чтобы вы помнили, называли ли вы 'new []', и если это так, вызывается 'delete []' перед возвратом, чтобы избежать утечки памяти. Есть ли причина, по которой вы не используете 'std :: string'? –

1

Первый аргумент sprintf должен быть указателем на буфер, достаточно большой, чтобы провести выходные. Указатель NULL или указатель на меньший буфер символов (например, строковый литерал "") вызовет сбой.

код, который будет работать в:

char buf[256]; 

if (ground_truth_filename == NULL) { 
    int charsneeded = snprintf(buf,sizeof(buf),"%s.yaml",filename); 
    if (charsneeded >= sizeof(buf)) { 
    return FILE_ERROR; // filename too long 
    } 
    ground_truth_filename = buf; 
} 

Дело в том, что buf дает новый filename место в памяти, чтобы жить. Строки нуждаются в этом.

Редактировать: добавлена ​​вещь, предназначенная для защиты от слишком длинных имен файлов в качестве меры безопасности. Если вы на самом деле этого хотите, динамически выделяйте buf вместо этого.

+0

И если 'ground_truth_filename' используется вне этой функции, после его возврата ваш код будет гарантировать, что он укажет, кто-что знает. Наступает веселье. –

+0

@NikBougalis Нет, это не так, поскольку параметры функции являются локальными переменными.Прикосновение к тому, что оно указывает *, является опасным, но изменения самого указателя перестают иметь значение, как только указатель исчезнет из сокращающегося стека. – dspeyer

+0

D'oh. Я читал это как 'char ** ground_truth_filename'. Виноват. –

Смежные вопросы