Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
61 / 28 / 24
Регистрация: 28.09.2017
Сообщений: 399

Неправильная запись const char* в std::string

17.01.2019, 16:47. Показов 1312. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Привет, делаю Web-Парсер на плюсах и Python (на Питоне только Web пока что). В данный момент занимаюсь запросами. Решил пойти по-простому пути:
Code
1
2
3
4
5
6
7
1) С помощью библиотек Питона, я создаю скрипт внутри C++
2) Этот скрипт совершает запрос, с помощью моей библиотеки для запросов на Питоне
3) Далее этот же скрипт создает временный файл, в который помещает ответ сервера
4) Завершаем работу интерпретатора, далее извлекаем данные файла в строку C++ таким образом:
    1. while (!temp_file.eof()) (знаю, что eof не самый лучший выбор, но в данном контексте все стабильно работает), порциями заносим в строку новые данные
    2. конкатенируем со строкой
5) Удаляем временный файл
На 4 пункте застопорился, а именно не могу понять, почему строка не может нормально записываться.
Отлаживал, смотрел, считывание верное, но именно запись ведется неверно.

Описал проблему, описал работу алгоритма, вот код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#define PART_SIZE     256
#define TEMP_FILENAME "temp.request"
 
//...
 
void  WebRequests::completeRequest() {
    if (!response.empty())  //std::string response
        response.clear();
 
    Py_Initialize();
 
    std::ostringstream python_code;
    python_code <<
        "from Parser.Python.Web.WebRequests import WebRequest as wr\n" <<
        "request = wr(('" << hostname << "', " << port << "))\n" <<
        "request.set_request('''" << request.str().c_str() << "'''.encode())\n" <<
        "response = request.get_response()\n" <<
        "temp_file = open('" << TEMP_FILENAME << "', 'tw')\n" <<
        "temp_file.write(response)\n" <<
        "temp_file.close()\n";
 
    PyRun_SimpleString(python_code.str().c_str());
 
    Py_Finalize();
 
    std::ifstream temp_file(TEMP_FILENAME, std::ios::binary);
    char* response_part;                                       //data processed on parts
 
    while (!temp_file.eof()) {
        response_part = new char[PART_SIZE];
 
        temp_file.getline(response_part, PART_SIZE);
        response += response_part;
 
        delete response_part;
    }
 
    temp_file.close();
    remove(TEMP_FILENAME);
}
Пробовал с std::ostringstream, точно такая же ерунда.

Добавлено через 2 минуты
Строка на выходе получается примерно такой:
Code
1
    response = "</html>nter>nginx/1.12.1</center>/center>d>ed, 01 Jan 2020 00:00:00 GMT"
Добавлено через 23 секунды
Как можно видеть, все шиворот-навыворот
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
17.01.2019, 16:47
Ответы с готовыми решениями:

ошибка в программе (cannot convert 'std::string {aka std::basic_string<char>}' to 'const char*')
int main() { string fileName, currWord, currMax = &quot;&quot;; cin&gt;&gt;fileName; freopen(fileName, &quot;r&quot;, stdin); while...

Std::string в const char*
можно ли std::string превратить в const char* и как это сделать?

Сравнение std::string с const char *
В структуре определено неявное преобразование в std::string и const char * и наоборот: public struct three_values { public: const...

14
24 / 22 / 5
Регистрация: 13.11.2012
Сообщений: 49
17.01.2019, 17:15
Экранировать спецсимволы?
Цитата Сообщение от pavel2210057 Посмотреть сообщение
"request = wr((\'"
0
61 / 28 / 24
Регистрация: 28.09.2017
Сообщений: 399
17.01.2019, 17:20  [ТС]
Pavell, повторяю, запрос проходит успешно, именно где-то в строках [26:39] затаилась проблема.

Добавлено через 58 секунд
Хотя ничего не отрицаю, возможно где-то еще накосячил, но точно не в кавычках. (насколько я знаю в Питоне одинарные и двойные различий не имеют, в отличии от PHP)
0
зомбяк
 Аватар для TRam_
1585 / 1219 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
17.01.2019, 17:30
Цитата Сообщение от pavel2210057 Посмотреть сообщение
где-то еще накосячил, но точно не в кавычках
Пишешь строку в коде С++, а не из файла считываешь, так что тут кавычки как раз влияют, их все надо экранировать:

C++
1
2
3
4
5
6
7
        "from Parser.Python.Web.WebRequests import WebRequest as wr\n" <<
        "request = wr((\'" << hostname << "\', " << port << "))\n" <<
        "request.set_request(\'\'\'" << request.str().c_str() << "\'\'\'.encode())\n" <<
        "response = request.get_response()\n" <<
        "temp_file = open(\'" << TEMP_FILENAME << "\', \'tw\')\n" <<
        "temp_file.write(response)\n" <<
        "temp_file.close()\n";
0
61 / 28 / 24
Регистрация: 28.09.2017
Сообщений: 399
17.01.2019, 17:33  [ТС]
TRam_, вы можете быть бесконечно правы, но скрипт работает идеально! У меня ответ пишется в файл, я приостанавливал выполнение программы и проверял, что в файле. Там все красиво, как полагается. Полный ответ сервера.
0
 Аватар для igorrr37
2869 / 2016 / 991
Регистрация: 21.12.2010
Сообщений: 3,721
Записей в блоге: 15
17.01.2019, 17:37
неправильно удаляете delete[] response_part;
0
61 / 28 / 24
Регистрация: 28.09.2017
Сообщений: 399
17.01.2019, 17:48  [ТС]
igorrr37, прокол нашел, но проблема не исчезла. Отладчиком прогнал по циклу: response_part принимает правильные значения на каждой итерации. Именно что-то с стринговой переменной...
0
techpriest
 Аватар для Mirmik
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
17.01.2019, 18:19
В строковом литерале " ' " не обрабатывается как спецсимвол. Коментировать его надо, если '\''.

Хотя формально применение delete вместо delete[] является UB, на деле для POD типов для них в текущих реализациях компиляторов разницы нет. Так что это тоже не приводило к ошибке.

Добавлено через 24 минуты
Тут еще есть проблема, которая выплывет, если строка будет больше 255-ти символов, но в целом код выглядит валидно. Предлагаю просмотреть эволюцию переменной response между итерациями.
0
61 / 28 / 24
Регистрация: 28.09.2017
Сообщений: 399
17.01.2019, 21:21  [ТС]
Цитата Сообщение от Mirmik Посмотреть сообщение
Тут еще есть проблема, которая выплывет, если строка будет больше 255-ти символов
Пока что не встречал ответы, в которых было бы больше символов в строке. Если конечно не найдется умник, который решит написать HTML-код страницы в одну строку.
Цитата Сообщение от Mirmik Посмотреть сообщение
Предлагаю просмотреть эволюцию переменной response между итерациями.
Смотрел еще до публикации поста. На каждой итерации, начиная со второй, она принимает неверное значение. Я потому и решил спросить на форуме, потому что это очень странное поведение, на мой взгляд.
Буквально пара итерации:
Code
1
2
3
4
5
6
7
    1 итерация:
        response_part = "HTTP/1.0 400 Bad Request"
        response =      "HTTP/1.0 400 Bad Request";
 
    2 итерация:
        response_part = "Server: ngjit"
        response =      "Server: ngjitBad Request"
(Специально отправил на сервер (cyberforum, кстати) пустой запрос, поэтому не смотрите на "Bad Request")
Как видите, 1 итерация проходит нормально, пустая строка + response_part стала равна response_part.
Но во 2 уже начинается беспредел: почему "HTTP/1.0 400 Bad Request" + "Server: ngjit" стало вдруг равно "Server: ngjitBad Request"?

Единственное, где я вижу возможную проблему, так это распределение в памяти. Хотя это было бы странно, но может барахлит итератор класса std::string. Это ну ооочень вряд ли (это все-таки std), но я уже не представляю просто.

Добавлено через 1 час 38 минут
Правда ни у кого нет идей?
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
17.01.2019, 21:23
pavel2210057, Прикрепите полученный скриптом файл сюда без изменений, будет проще.
0
61 / 28 / 24
Регистрация: 28.09.2017
Сообщений: 399
17.01.2019, 21:36  [ТС]
DrOffset, обычный такой ответ с ошибкой запроса. Но ладно.
Вложения
Тип файла: txt temp.txt (405 байт, 8 просмотров)
0
Параллельный Кот
 Аватар для valen10
1905 / 827 / 350
Регистрация: 25.03.2016
Сообщений: 2,045
17.01.2019, 22:16
Уважаемый pavel2210057, научитесь пользоваться отладчиком. Если бы вы им воспользовались, то увидели бы, что строка формируется без проблем.


А вы похоже сделали отладочную печать. Что пошло не так? А то, что строка содержит символы \r, или по другому - возврат каретки. При выводе в окно консоли этот символ выполняет возврат курсора в начало строки, и следующие символы начинают заменять ранее напечатанные. Вот пример демонстрации этого эффекта:

C++
1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include <string>
using namespace std;
 
int main() {
    string s = "Hello \rGoodbye, Vasya!";
    cout << s << endl;
 
    return 0;
}
Проверьте, что напечатает эта программа. Но это будет точно не то, что вы видите в тексте программы.
1
techpriest
 Аватар для Mirmik
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
17.01.2019, 22:55
Дополню. Наблюдаемый эффект связан с тем, что функция getlineизымает символы переноса строки. Поэтому в responce от \r\n остается только \r.
1
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
17.01.2019, 23:44
Цитата Сообщение от Mirmik Посмотреть сообщение
Наблюдаемый эффект связан с тем, что функция getlineизымает символы переноса строки. Поэтому в responce от \r\n остается только \r.
Дополню тоже. Я специально попросил файл, т.к. это показалось мне странным. getline - это текстовая функция и не должна оставлять \r в строке. Про виндовые переносы строк она знает и обрабатывает их корректно \r\n интерпретируются как \n. Но если посмотреть на файл в шестнадцатеричном редакторе, то будет видно, что переносы строк там кодируются не как \r\n, а как \r\r\n и именно поэтому в строку попадает "лишний" \r, который обеспечивает такой наблюдаемый эффект.
Чтобы исправить код, нужно сделать так:
C++
1
temp_file.getline(response_part, PART_SIZE, '\r');
1
61 / 28 / 24
Регистрация: 28.09.2017
Сообщений: 399
18.01.2019, 07:11  [ТС]
Цитата Сообщение от valen10 Посмотреть сообщение
научитесь пользоваться отладчиком. Если бы вы им воспользовались, то увидели бы, что строка формируется без проблем.
Я то как раз-таки умею им пользоваться, я выше показывал значение переменной на различных итерациях, так что не надо так говорить.
А вот все остальное, что писали вы и еще два добрых человека - верно. И правда надо было проверить файл в 16-ричном формате.
Теперь на всю жизнь запомню, спасибо огромное!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
18.01.2019, 07:11
Помогаю со студенческими работами здесь

(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&
astxx::manager::connection::connection(std::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const&amp;, unsigned short); ...

Преобразовать const unsigned char* в std::string (или _bstr_t )
Здравствуйте старшие товарищи! Есть функция, которая возвращает результат типа const unsigned char*. а мне нужно получить ...

Запрошено преобразование от ‘const std::string*’ к нескалярному типу ‘std::string’
private: std::string firstName; }; std::string ClientData::getFirstName() const{ return firstName; } Дает в итоге...

ошибка error: cannot convert 'std::string {aka std::basic_string<char>}' to 'std::string* {aka std::basic_stri
на вод поступают 2 строки типа string. определить количество вхождений строки 2 в строку 1 ошибка error: cannot convert 'std::string {aka...

Ошибка при компиляции "Cannot convert `std::string' to `const char*"
Подскажите пожалуйста.Компилятор указывает на 13-ой позиции на ошибку типа: cannot convert `std::string' to `const char* for argument `1'...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru