C++: старый исходник - в Studio
У новичков нередко возникает проблема миграции учебных (и не только) исходников на C++ (или на "простом" C), взятых из эпохи Borland C++ 3.1 и Turbo C, в современные среды вроде Visual Studio. Если с созданием консольного приложения они худо-бедно разбираются, то необходимость поменять пару слов в исходнике часто вызывает ступор :)
Да, без минимальных правок исходного текста программы обычно не обойтись. Но они почти всегда типовые. Кратко перечислю их в этом сообщении.
Во-первых, волшебная директива в начале файла.
1.
#include <alloc.h>
Ошибка. alloc.h
- борландовский, чаще всего был нужен для выделения памяти сишными функциями malloc
/calloc
. Просто подключите вместо него cstdlib
.
2. Также обычно нужно добавить к инклудам
#include <clocale> #include <windows.h>
В начале функции main
напишите
setlocale(LC_ALL,"Russian");
для русского текста в консоли, есть ещё setlocale(LC_CTYPE, ".1251")
, если кодировка исходника = Windows, и даже setlocale(LC_CTYPE, ".866")
должно работать :)
Если нужен ввод русских букв именно в Visual Studio C++, обычно достаточно добавить вместо setlocale
SetConsoleCP(1251); SetConsoleOutputCP(1251);
(в чём разница - тут)
3.
#include <conio.h>
Они разные у Микрософта и Борланда. Например, у Микрософта нет Борландовской очистки экрана clrscr()
:) Сойдёт на крайний случай
#include <cstdlib> //... system("cls");
но учтите :)
Если нужно переставить курсор в консоли на Visual C++ - подойдёт вот эта функция:
void gotoxy(int xpos, int ypos) { COORD screen; HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); screen.X = xpos; screen.Y = ypos; SetConsoleCursorPosition(handle,screen); }
Только она нумерует столбцы и строки с нуля, а не с единицы, как борландовская функция. Ну да сделать
xpos--; ypos--;первой строкой функции, чтоб не перебивать координат при множественных вызовах
gotoxy
- сообразите.
Имейте в виду, что в Unix/Linux conio.h
нет. Если очень нужно, как вариант - решение из этой заметки.
4.
#include <graphics.h>
Вот с этим хуже. Борландовские графические движки устарели и несовместимы с современными. Если переписывать весь графический вывод программы трудоёмко или невозможно, сделайте для неё виртуалку и там запускайте :) "Самопалки" graphics.h
, конечно, тоже есть, законченных решений пока не видел.
Вот здесь ещё можно посмотреть BGI'шки для подключения к Studio программ с Borland-совместимой графикой, инструкция там же.
5.
#include <iostream.h>
Было и такое. Уберите .h
и добавьте
using namespace std;
после инклудов, чтоб не переписывать все
cout << "Hello";
в
std::cout << "Hello";
6.
#include <math.h>
Само по себе не проблема, но кое-что не переехало в современные Math.h
(Builder) или пространство имён Math
(Studio).
Самые частые проблемы такие:
- нет константы пи (
M_PI
) и т.п. Проще всего - возьмите её определение изmath.h
и скопируйте в проект:#define M_PI 3.14159265358979323846
ну или
const double M_PI = 3.14159265358979323846;
- не найдена перегрузка для какой-нибудь математической функции, например, Studio не поймёт
exp(1)
... ну так напишитеexp(1.)
илиexp((double)1)
(от вещественного, а не целого аргумента :)
7.
#include <values.h>
Увы, это тоже Борландовский файл, был в его продуктах и последующих Builder от Embarcadero, у Microsoft такого нет. Но некоторые определения есть в стандартном climits
(для целых типов), а кое-что в сfloat
(для вещественных).
Между прочим, оба файла были и у Борланда.
Например, Borland'овский MAXINT
в Visual C++ превращается в INT_MAX
(limits.h
), а аналогом MAXFLOAT
может служить FLT_MAX
из float.h
(соответственно, вместо MAXDOUBLE
пишется DBL_MAX
).
Выходов по-прежнему два, или скопировать #define
-определение из Борландовского .h
-файла, или заменять названия констант во всём проекте. Вот некоторые определения float.h
из старых борладовских компиляторов:
#define MAXSHORT 0x7FFF #define MAXINT 0x7FFF #define MAXLONG 0x7FFFFFFFL #define DMAXEXP 308 #define FMAXEXP 38 #define DMINEXP -307 #define FMINEXP -37 #define MAXDOUBLE 1.797693E+308 #define MAXFLOAT 3.37E+38 #define MINDOUBLE 2.225074E-308 #define MINFLOAT 8.43E-37
8.
#include <dir.h>
- отстутствует в Studio. Можно попробовать подключить io.h
и использовать методы
_findfirst
и _findnext
для поиска файлов (вместо классических findfirst
, findnext
).
Кроме того, в windows.h
есть структура WIN32_FIND_DATA
для работы с каталогами и файлами. Пример: выводим в консоль оглавление головного каталога.
#include <windows.h> #include <iostream> using namespace std; void main() { WIN32_FIND_DATA FindFileData; HANDLE hf; hf=FindFirstFile((LPCSTR)"c:\\*", &FindFileData); if (hf!=INVALID_HANDLE_VALUE) { do { printf("%s\n", FindFileData.cFileName); } while (FindNextFile(hf,&FindFileData)!=0); FindClose(hf); } system("pause>nul"); }
9.
fflush(stdin);- не работает нормально в актуальных версиях Studio. Для очистки буфера ввода можно сделать
scanf("%*[^\n]");
Директива при этом включена.
Перед fgets можно и rewind. Вот ввод различных типов данных в консоли Visual Studio 2019:
#define _CRT_SECURE_NO_WARNINGS #include <cstdio> int main() { char ch; printf ("\nType one char: "); scanf ("%c",&ch); printf ("Char=%c (%02X)",ch, ch); scanf("%*[^\n]"); //fflush(stdin) не работает в новых версиях Studio char buf[80]; printf("\nType string without spaces: "); scanf("%s", buf); printf("String=%s", buf); scanf("%*[^\n]"); printf("\nType string with spaces: "); buf[0] = '\0'; //буфер снова пуст rewind(stdin); //сброс fgets(buf,80,stdin); fputs(buf, stdout); int d; printf("\nType integer number: "); scanf("%d", &d); printf("Number=%d (dec), %o (oct), %x (hex)", d, d, d); scanf("%*[^\n]"); double f; printf("\nType float number: "); scanf("%lf", &f); printf("Number=%12.4f", f); return 0; }
22.02.2015, 22:18 [14537 просмотров]