Ошибка графической инициализации C++ (синтаксис или ошибка отсутствующего файла?)

[Решено]

Я использую CodeBlocks (C++) на Win10. Я попытался создать простую графическую программу - я скачал определенный графический пакет (graphics.h и два других файла, связанных с BGI - я добавил библиотеку в настройках и т. Д.). Я пробовал эту программу, но, кажется, проблема в строке, отмеченной. Я перенес это из Паскаля (поскольку мой учитель - да, речь идет о колледже - только показывает нам программы на Паскале) правильным образом, по крайней мере, частично. Проблема, безусловно, с указателями (РЕДАКТИРОВАТЬ ПОСЛЕ РЕШЕНИЯ: это не так!, Проверьте мой ответ). Я дам более подробную информацию, если это необходимо.

Вопрос: Где я допустил ошибки и как их исправить (что написать, что добавить, что удалить), чтобы оно работало нормально? Если в коде нет ошибок, но мне НУЖНЫ некоторые файлы для работы графики на моем компиляторе, какие файлы, где их взять и где их разместить?

ОШИБКА (не совсем, теперь "предупреждение"):

deprecated conversion from string constant to 'char*' [-Wwrite-strings]

(см. код чуть ниже)

Пожалуйста, прочитайте: Я был бы ОЧЕНЬ благодарен за исправленную версию моей программы. Ссылки бесполезны, поэтому, если вы ДЕЙСТВИТЕЛЬНО не хотите мне помочь (спасибо!), Покиньте эту страницу. Моя единственная связанная способность состоит в том, чтобы сравнить две версии программы, которые предназначены сделать то же самое, но одна имеет ошибку (или больше).

КОД (обновлено!):

#include<iostream>
#include<graphics.h>
#include<conio.h>
using namespace std;
int main(){
int gr,xmax,ymax,r;
int gm,gd;
gd=DETECT;
gm=0;
initgraph(&gd, gm, "C:\\TC\\BGI"); /*edit(solved): followed the tutorial linked in my answer; not a directory in my PC.*/
gr=graphresult();
if(gr!=grOk) cout<<"Error!";
    else    {xmax=getmaxx();
            ymax=getmaxy();
            cout<<"Resol.: "<<xmax+1<<"x"<<ymax+1;}
setcolor(7);rectangle(0,0,xmax,ymax);setcolor(5);line(0,0,xmax,ymax);line(0,ymax,xmax,0);setcolor(3);
for(r=(ymax+1)/2;r>=0;r--) circle((xmax+1)/2,(ymax+1)/2,r);
getch();
closegraph();
return 0;
}

graphics.h источник и руководство: http://www.codewithc.com/how-to-include-graphics-h-in-codeblocks/

5 ответов

Решение

Решено! Понизил CB (v16 до v13, я думаю, не уверен, если это было необходимо) и заменил некоторые файлы. Я следовал этому руководству: https://m.youtube.com/watch?v=FxCdMM9H66I Это было почти то же самое, что и ссылка в вопросе, но, вероятно, (один или несколько) из этих файлов (graphics.h, winbgim.h, libbgi.a) из предыдущей ссылки были ошибками, имели некоторые неочевидные ошибки или около того, или были несовместимы и т. д.), в то время как файлы, предоставленные создателем видео, которые я предоставил в этом ответе, были исправлены. Я не (очень хочу) знать. Теперь, предупреждение все еще появляется, НО программа работает отлично! Я заменил r=0 на r>=0, это была небольшая ошибка. (Я обновлю вопрос, если смогу)

Спасибо за вашу помощь! (Не могу сказать "ничего", я бы имел в виду):)

РЕДАКТИРОВАТЬ:

Некоторая "более чистая" версия, которая показывает круг (только что понял, что вариант в вопросе не отображает заполненный круг):

#include<iostream>
#include<graphics.h>
#include<dos.h>
using namespace std;
main(){
int gm,gd,gr,xmax,ymax,r;
gd=DETECT;
gm=0;
initgraph(&gd,&gm,"C:\\TC\\BGI");
gr=graphresult();
if(gr!=grOk) cout<<"Error!";
    else    {xmax=getmaxx();
            ymax=getmaxy();
            cout<<"Res.: "<<xmax+1<<"x"<<ymax+1;}
setcolor(7);
rectangle(0,0,xmax,ymax);
setcolor(5);
line(0,0,xmax,ymax);
line(0,ymax,xmax,0);
setcolor(3);
for(r=(ymax+1)/2;r>=0;r--) circle((xmax+1)/2,(ymax+1)/2,r);
getch();
closegraph();
}

РЕДАКТИРОВАТЬ 2: Понижение не требуется ПОДТВЕРЖДЕНО!:D

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

Символьные литералы как ' ' в основном переводятся компилятором в целые числа, и вы не ожидаете, например, &32 ( ASCII-код для пространства) работать, не так ли?

Если вы должны передать строку, используйте двойные кавычки и не используйте оператор адреса, как в " ",

Предупреждение должно исчезнуть, если вы замените литерал массивом, который можно преобразовать в char*:

char driver[] = "";
initgraph(&gd, &gm, driver);

Я исправил очевидные синтаксические ошибки и пометил места комментарием `/* <- ИСПРАВЛЕНО * /:

#include<iostream>
#include<graphics.h>
#include<conio.h>
using namespace std;
int main()
{
  int gr,xmax,ymax,r;
  int gm,gd; /* <-- FIXED */
  gd=DETECT;
  gm=0;
  initgraph(&gd, &gm, "C:/Users/MyName/Desktop/WORKFOLDER/"); /* <-- FIXED */
  gr=graphresult();
  if(gr!=grOk) cout<<"Error!";
  else {
    xmax=getmaxx();
    ymax=getmaxy();
    cout<<"Resol.: "<<xmax+1<<"x"<<ymax+1;
  }
setcolor(7);rectangle(0,0,xmax,ymax);setcolor(5);line(0,0,xmax,ymax);line(0,ymax,xmax,0);setcolor(3);
  for(r=(ymax+1)/2;r=0;r--) circle((xmax+1)/2,(ymax+1)/2,r);
  getch();
  closegraph();
  return 0;
}

К сожалению, я не могу скомпилировать и протестировать его. (У меня нет библиотек BGI и я не хочу его устанавливать.)

Просто прочитайте ваш отредактированный вопрос и хотите упомянуть о LValue:

"LValue" означает то, что имеет адрес, т.е. вы можете применить адрес оператора &, LValue, потому что он может появиться на левой стороне назначения.

Переменная имеет адрес и, следовательно, является LValue.

Символьная константа (например, 'A') имеет на самом деле тип int и не является LValue.

Строковая константа (например, "Hello") имеет тип const char[] (совместимо с const char*) является (может быть удивительным) значением LValue, потому что компилятор должен где-то выделить для него хранилище данных.

Таким образом, даже следующее будет "работать":

#include <stdio.h>
int main()
{
  char *sz = "Hello";
  printf("address of \"%s\": %p\n", sz, sz);
  printf("address of sz: %p\n", &sz);
  sz[0] = 'h';
  printf(sz);
  return 0;
}

Я скомпилировал и протестировал с gcc и cygwin (в Windows 10 - 64 bit):

$ gcc -o test-cstringlvalue test-cstringlvalue.c 

$ ./test-cstringlvalue.exe
address of "Hello": 0x403060
address of sz: 0x61cc6c
Segmentation fault (core dumped)

Итак, вы видите две важные вещи:

  1. Компилируется нормально. (Изменение значения LVal не подозревается компилятором.)

  2. Это терпит крах, потому что постоянная строка была изменена.

(Вероятно, он не будет падать ни на одной платформе.)

Тем не менее, я рекомендую не изменять строковые константы, но это демонстрирует то, что я пытался объяснить о LValues.

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

Редактировать:

Прочитав свой собственный текст снова, я почувствовал себя немного неуверенно, если правильно сказал: "Таким образом, я снова погуглил и нашел эту ссылку: SO: Почему строковые литералы имеют l-значение, а все остальные литералы - r-значение?,

Другие вопросы по тегам