Hello I have been given the task of reading file input of 3 digit month abbreviations and a day and I must calculate the Julian date for each (sum of days since jan 1)
No matter what I do when I add two INTEGERS I get error 201 (incompatible data types). I have tried making a new program and gotten it to work but once I implement it into my existing code it doesn’t work anymore. This is very frustrating, please help. I’m sick of this stupid class making me take this language where I can’t find shit online to help.
Here is the code:
program prg6_150;
const
MONABV:array[1..12] of string[03] = ('JAN','FEB','MAR','APR','MAY','JUN',
'JUL','AUG','SEP','OCT','NOV','DEC');
MONDAYS:array[1..12] of integer = (31,28,31,30,31,30,31,31,30,31,30,31);
var
more_rec:Boolean; { EOF flag }
DAY:integer; { input day }
MONTH:string[03]; { input month abbreviation }
JULIAN:integer; { computed Julian day }
ch:char; { spacer character for input }
FileIn:Text;
FileOut:Text;
{ your module, to be called "JULIAN_DAY" inserted here }
procedure JULIAN_DAY;
var
j,sum_days:integer;
begin
j := 0;
sum_days := 0;
if MONTH = 'JAN' then j := 1 else
if MONTH = 'FEB' then j := 2 else
if MONTH = 'MAR' then j := 3 else
if MONTH = 'APR' then j := 4 else
if MONTH = 'MAY' then j := 5 else
if MONTH = 'JUN' then j := 6 else
if MONTH = 'JUL' then j := 7 else
if MONTH = 'AUG' then j := 8 else
if MONTH = 'SEP' then j := 9 else
if MONTH = 'OCT' then j := 10 else
if MONTH = 'NOV' then j := 11 else
if MONTH = 'DEC' then j := 12;
for J:= 2 to 12 do
repeat
sum_days := MONDAYS[1] + sum_days;
j := j - 1
until j = 1;
Julian := DAY + sum_days;
end;
procedure read_rec;
begin
if Eof(FileIn) then
more_rec := False
else
readln(FileIn,day,ch,month)
end; { read_rec }
procedure initialize;
begin
more_rec := True;
Assign(FileIn,'JULIAN.DAT');
Reset(FileIn);
Assign(FileOut,'JULIAN.OUT');
Rewrite(FileOut);
read_rec
end; { initialize }
procedure process;
begin
Julian_Day;
writeln(FileOut,day:2,' ',month,' ',julian:3);
read_rec
end; { process }
procedure wrapup;
begin
Close(FileOut);
Close(FileIn)
end; { wrapup }
begin { main }
initialize;
while more_rec do
process;
wrapup
end.
Command Prompt Error
My program has following code:
function FooBar(const s: string): string;
var
sa: AnsiString;
begin
// ..........................
sa := AnsiString(s);
sa := AnsiString(StringReplace(string(sa), '*', '=', [rfReplaceAll]));
sa := AnsiString(StringReplace(string(sa), ' ', '+', [rfReplaceAll]));
result := string(sa);
// ..........................
end;
I noticed that the program did crash «somewhere» and FastMM4 said that I had written to a freed object. As soon as I have commented out «const», the program did work.
I have read the Delphi documentation about const arguments, but I can’t figure out why the const argument crashes the program. I would love to understand it.
UPDATE: The program does only crash in Delphi 6 and only if optimization is ON. If the optimization is OFF, the program will work normally. Might it be a Delphi bug?
asked Apr 29, 2014 at 10:39
Daniel MarschallDaniel Marschall
3,7402 gold badges27 silver badges67 bronze badges
8
There are a few peculiar gotchas when it comes to const string parameters.
Many years ago I helped a colleague resolve a similar peculiar problem (D3 iirc). The following simplified example doesn’t look like your specific issue, but it may give you some ideas:
type
TMyClass
FString: string;
procedure AppendString(const S: string);
end;
procedure TMyClass.AppendString;
begin
FString := FString + S;
end;
Now if you have an instance of TMyClass
and try to call AppendString(FString);
to double up the string, you may get an access violation. (There are a few other factors that can affect if you do.) The reason is as follows:
- The const prevents refcounting the string on the method call.
- So
FString
may haverefCount = 1
when its value is changed. - In which case Copy-on-Write doesn’t apply and the string is reallocated. (Most likely at a different address.)
- So when the method returns, S is referring to an invalid address, and triggers an AV.
answered Apr 29, 2014 at 14:24
DisillusionedDisillusioned
14.6k3 gold badges43 silver badges77 bronze badges
1
For this case:
sa := s;
automatic reference counting (ARC) works. This is idiomatic way, compiler know how to work with these string — if sa will change, it creates new copy and so on.
For case of hard typecasting (though type is the same)
sa := AnsiString(s);
you tell compiler that you want to get only pointer to string, and you know how to work with this string reference. Compiler will not interfere and annoy you, but you are responsible for correct operations
P.S. I can not reproduce the problem with Delphi XE5 — both simple assigning and typecasting causes LStrLAsg (internal function) call with ARC. (Of course, compiler magic could be changed a bit)
answered Apr 29, 2014 at 13:53
4
We debugged a crash today that was a Delphi 5 compiler code-gen bug:
procedure TForm1.Button1Click(Sender: TObject);
var
s: string;
begin
s := 'Hello, world! '+IntToStr(7);
DoSomething(s);
//String s now has a reference count of zero, and has already been freed
ShowMessage(s);
end;
procedure TForm1.DoSomething(const Title: string);
var
s: AnsiString;
begin
s := AnsiString(Title);
if Now = 7 then
OutputDebugString('This is a string that is irrelevant');
end;
The Delphi 5 compiler mistakenly tries to decrement the reference counts of both
Title
s
and causes the const
string’s reference count to go to zero. This causes it to be freed. So when DoSomething
returns, you are using a freed string.
An access violation waiting to happen.
Or, in the case of customers: happening.
answered Oct 19, 2016 at 19:54
Ian BoydIan Boyd
245k252 gold badges865 silver badges1206 bronze badges
That becouse AnsiString is a pointer. So, you could’n operate it as a usual strings (which mean a array of chars). Crash is random, so you can gain the crash as result of stackoverflow or access violations at any time, not depend on optimization.
Than you function FooBar return the result, sa variable are already free from mamory.
Try to use the PChar or PAnsiChar and allocate the memory for this variables as your needs.
answered Apr 29, 2014 at 11:17
Y.NY.N
4,9397 gold badges33 silver badges61 bronze badges
2
Since it doesn’t make sense to convert to AnsiString and back here, I would rewrite this as
function FooBar(const s:string):string;
begin
Result:=
StringReplace(
StringReplace(
s
,'*','=',[rfReplaceAll])
,' ','+',[rfReplaceAll]);
end;
answered Apr 29, 2014 at 12:06
Stijn SandersStijn Sanders
35.9k11 gold badges45 silver badges67 bronze badges
3
Есть такое понятие в программировании — безопасный код.
Помимо всего прочего (про exceptionы и потокобезопасность здесь речь не пойдет) оно включает в себя стиль написания программы, который не допускает работу с указателями в явной форме — получение, разыменование, арифметика на ним, также не приветствуются операции приведения типов.
Вместо указателей настоятельно рекомендуется использовать ссылки, а типы преобразовывать в явном виде — через операции присваивания, встроенные функции и т.п.
Т.е. нужно как можно больше работы сбрасывать на компилятор — статический контроль типов, управление памятью и прочую рутину. Он умеет это лучше чем человек.
Теперь по поводу совместимости и эквивалентности.
Совместимость типов — это такое отношение между двумя типами, которое доступно компилятору на этапе синтаксического анализа исходника. Т.е. компилятор ЗНАЕТ как перевести тип А в тип Б.
Например real совместим с integer (переменной типа real можно присвоить значение переменной типа integer), но не наоборот.
Эквивалентность типов — имеется в виду двоичная эквивалентность, это отношение между типами, выстроенное на основе размера памяти в байтах, который занимает переменная того или иного типа.
Например у нас есть запись вида:
Код
TMyDWord = packed record
HiWord: Word;
LoWord: Word;
end;
Если мы имеем переменную типа Dword то мы вполне можем привести её к типу TMyDWord. Это приведение допустимо потому что размер занимаемый TMyDword равен размеру DWord. Обратное приведение также возможно.
Эквивалентность типов может зависеть от настроек компилятора. Если мы поставим выравнивание полей записи по 4 байтам (это сильно ускорит их обработку) приведенный выше пример не будет работать, так как размеры перестанут совпадать и отношение двоичной эквивалентности между типами пропадет.
Операция приведения типа оперирует с понятием эквивалентности типов. Мы можем привести тип А к типу Б в том случае, когда size(А) >= size(Б). Это ограничение не позволит обратиться к, возможно, невыделенной области памяти, что приведет к AV-исключению.
При передаче параметров в подпрограммы или методы, для компилятора очень важен ТИП подставляемх фактических параметров, именно на основе их типов, он будет вызывать нужную перегруженную версию (если они есть) сабрутины. Отсюда правило — нужно ЗНАТЬ что ты хочешь сделать, чтобы небыло недопонимания с компилером.
Цитата
Мне кажется, что оба действия — и Type1(Type2Variable) и Type1((@Type2Variable)^) — выполняются на этапе
компиляции. Но почему в первом случае создаётся локальная копия(для VAR-параметров), по какому синтаксическому правилу?
Я уже объяснял….. Первый вариант приводит к копированию данных во временную переменную. Второй вариант компилятор рассматривает как некое переобъявление переменной. Разыменованный указатель — это переменная, операция приведения типа выступает в качестве декларирования типа переменной. Именно поэтому такая запись пригодна для передачи параметра по ссылке.
Добавлено через 6 мин.
Ваял предыдущий креатив…..
Цитата(Neznaika @ 11.08.2007 18:41)
А можно ли вообще использовать в качестве фактических параметров процедур для VAR-параметров ВЫРАЖЕНИЯ? Для W типа Word конструкция Byte(W) — это выражение.
В принципе — можно. Если выражение своим результатом возвращает указатель, то используя технику дзен
Код
Type1((PType1PointerExpression)^)
Мы можем передавать данные по ссылке.
Другое дело, что нам потребуется написать выражение, результатом которого будет некий указаталь (с точки зрения безопасного кода подобные действия никуда не годятся).
Program_LABA9.pas(100,43) Error: Incompatible type for arg no. 2: Got «Constant String», expected «LongInt» — Free Pascal
Формулировка задачи:
Помогите решить проблему Program_LABA9.pas(100,43) Error: Incompatible type for arg no. 2: Got «Constant String», expected «LongInt»
Код к задаче: «Program_LABA9.pas(100,43) Error: Incompatible type for arg no. 2: Got «Constant String», expected «LongInt»»
textual
Листинг программы
Полезно ли:
12 голосов , оценка 3.917 из 5
Похожие ответы
- Ввести x с клавиатуры и определить, сколько чисел в промежутке от 1 до 100 делятся без остатка на x, x-1 или x
- Выдать все четные числа от 0 до 10000, если х = 0; иначе выдать x^5
- Разбросать по экрану 1000 звездочек в случайном месте случайным цветом с небольшой задержкой
- Ошибка: syntax error identifier expected
- Ошибка fatal: syntax error identifier expected
- Ошибка при компиляции «Syntax error «Begin» expected but «;» found»
- Ошибка «Syntax Error, «:» expected but «;» found
- Вычислить 100!+2^100
- Найти сумму первых 100 элементов упорядоченной последовательности
- При выполнении программы пропускается цикл for
- Как наиболее рационально обратиться к элементам динамического массива через цикл For
Ниже мой код, а затем ниже, это сообщение об ошибке. Буду признателен за любую помощь. Спасибо. Назначение:
« Измените предоставленный класс
String
чтобы внутренне хранить строки Pascal, которые представляют собой массивы символов, которые начинаются с нескольких символов в строке, за которыми следуют эти символы, без конечного нулевого символа. То есть:
str
должна содержать строку Pascal.- Должен быть включен конструктор, созданный в вашей строковой лаборатории Pascal. Также должен быть включен нормальный конструктор C-строк и должен преобразовать его в строку Pascal.
- Функция
c_str
должна преобразовать обратно в строку C, чтобы предоставить пользователю строку C. В этой функции можно выделить память для строки.- Все остальные функции должны выполняться правильно, учитывая изменение во внутреннем формате строки.
- Вы не можете хранить строку C внутри себя вместе с строкой Pascal.
Pascal.cpp
// Pascal Main cpp
#include <iostream>
#include <algorithm>
#include "Pascal.h"
#include <exception>
using namespace std;
// Default constructor
String::String() {
arr = new char[1];
arr[0] = '';
len = 0;
}
// Constructor. Converts a C-string to a String object
String::String(const char *s) {
len = strlen(s);
arr = new char[len + 1];
std::copy(s, s + len + 1, arr);
}
// Copy constructor.
String::String(const String &obj) {
len = obj.len;
arr = new char[len + 1];
std::copy(obj.arr, obj.arr + len + 1, arr);
}
// Move constructor.
String::String(String &&obj) {
len = obj.len;
arr = obj.arr;
obj.arr = nullptr;
}
String::String(const char *str, bool pascal) {
judge = pascal;
if (judge) {
len = strlen(str) - 1;
const char *temp = str;
arr = new char[len + 1];
arr[0] = len + '0';
for (int i = 1; i <= len; i++) {
arr[i] = temp[i];
}
}
else {
len = strlen(str);
arr = new char[len + 1];
std::copy(str, str + len + 1, arr);
}
}
// Destructor
String::~String() {
if (arr != nullptr)
delete[] arr;
}
// Assignment operator
String &String::operator=(const String &rhs) {
delete[] arr;
len = rhs.len;
arr = new char[len + 1];
std::copy(rhs.arr, rhs.arr + len + 1, arr);
return *this;
}
// Move assignment operator
String &String::operator=(String &&rhs) {
delete[] arr;
len = rhs.len;
arr = rhs.arr;
rhs.arr = nullptr;
return *this;
}
// Mutator operator[]
char &String::operator[](int index) {
// check whether the index is within bounds
if (index > len || index < 0)
throw std::out_of_range("Index out of range");
return arr[index];
}
// Accessor operator[]
char String::operator[](int index) const {
// check whether the index is within bounds
if (index > len || index < 0)
throw std::out_of_range("Index out of range");
return arr[index];
}
// Get the length (number of characters) of a String object
int String::length() const {
return len;
}
bool operator==(const String &lhs, const String &rhs) {
if (lhs.judge != rhs.judge) {
cout << "can't compare";
}
return strcmp(lhs.arr, rhs.arr) == 0;
}
bool operator<(const String &lhs, const String &rhs) {
if (lhs.judge != rhs.judge) {
cout << "can't compare";
}
return strcmp(lhs.arr, rhs.arr) < 0;
}
// Friend functions for > comparison
bool operator>(const String &lhs, const String &rhs) {
if (lhs.judge != rhs.judge) {
cout << "can't compare";
}
return rhs < lhs;
}
// Friend functions for <= comparison
bool operator<=(const String &lhs, const String &rhs) {
if (lhs.judge != rhs.judge) {
cout << "can't compare";
}
return !(rhs < lhs);
}
// Friend functions for >= comparison
bool operator>=(const String &lhs, const String &rhs) {
if (lhs.judge != rhs.judge) {
cout << "can't compare";
}
return !(lhs < rhs);
}
// Friend functions for != comparison
bool operator!=(const String &lhs, const String &rhs) {
if (lhs.judge != rhs.judge) {
cout << "can't compare";
}
return !(lhs == rhs);
}
// Friend function for string concatination
String operator+(const String &lhs, const String &rhs) {
if (lhs.judge == rhs.judge && lhs.judge == false) {
int strLength = lhs.len + rhs.len + 1;
char *tmpStr = new char[strLength];
for (auto i = 0; i < lhs.len; ++i)
tmpStr[i] = lhs.arr[i];
for (auto i = 0; i <= rhs.len; ++i)
tmpStr[lhs.len + i] = rhs.arr[i];
String retStr(tmpStr);
delete[] tmpStr;
return retStr;
}
else if (lhs.judge == rhs.judge && lhs.judge == true) {
int strLength = lhs.len + rhs.len + 1;
char *tmp = new char[strLength];
for (auto i = 1; i <= lhs.len; ++i)
tmp[i] = lhs.arr[i];
for (auto i = 1; i <= rhs.len; ++i)
tmp[lhs.len + i] = rhs.arr[i];
tmp[0] = (lhs.len + rhs.len) + '0';
String retStr(tmp);
delete[] tmp;
return retStr;
}
else {
return String("can't do that");
}
}
// Return C style character string
const char* String::c_str() const {
return arr;
}
// Friend function for output
std::ostream& operator<<(std::ostream &out, const String &obj) {
return out << obj.c_str();
}
Pascal.h
// Pascal Header File
#pragma once
#ifndef __MYSTRING_H__
#define __MYSTRING_H__
#include <iostream>
class String {
public:
// Usage: String aStringObj; or String aStringObj();
String();
// Constructor. Converts a char* object to a String object
// Usage: String aStringObj("hello"); or String aStringObj = "hello";
String(const char *s);
// Copy and move constructors.
// Usage: String aStringObject(anotherStringObj); or
// String aStringObject = anotherStringObj;
String(const String &s);
String(const char *str, bool pascal);
String(String&& obj);
// Destructor
~String();
// Assignment operator
// Usage: aStringObject = anotherStringObj; or
// aStringObject.operator=(anotherStringObj);
String &operator=(const String &rhsObject);
String& operator=(String&& rhs);
// Mutator operator[]
// Usage: aStringObject[1] = M;
char &operator[] (int index);
// Accessor operator[]
// Usage: char ch = aStringObject[1];
char operator[] (int index) const;
// Get the length (number of characters) of a String object
// Usage: int len = aStringObject.Length();
int length() const;
// Friend functions for == comparison
// Usage: if (aStringObject == anotherStringObj) {...} or
// if (aStringObject == "hello") {...} or
// if ("hello" == aStringObj) {...} or
friend bool operator==(const String &lhsObject, const String &rhsObject);
// The other five comparison operators
// !=, <, >, <=, >= are similarly handled as in line 13.
friend bool operator<(const String &lhsObject, const String &rhsObject);
friend bool operator>(const String &lhsObject, const String &rhsObject);
friend bool operator<=(const String &lhsObject, const String &rhsObject);
friend bool operator>=(const String &lhsObject, const String &rhsObject);
friend bool operator!=(const String &lhsObject, const String &rhsObject);
// Friend function for string concatenation
// Usage: StringOne = StringTwo + StringThree or
// StringOne = "hello" + StringTwo or
// StringOne = StringTwo + "hello"
friend String operator+(const String &lhs, const String &rhs);
// Return C style character string
// Usage: const char *str = aStringObj.C_str();
const char *c_str() const;
// Friend function for output
// Usage: cout << aStringObj;
friend std::ostream &operator<<(std::ostream &out, const String &obj);
private:
// arr implements the String object as a dynamic array
char *arr;
// len keeps track of the length
int len;
// judge weather the String is a c_string or a pascal_string
bool judge;
};
#endif
При компиляции я получаю эти предупреждения и ошибки:
Severity Code Description Project File Line Suppression State Warning C4996 'std::_Copy_impl': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators' Pascal Assignment c:program files (x86)microsoft visual studio 14.0vcincludexutility 2229 Severity Code Description Project File Line Suppression State Error LNK1120 1 unresolved externals Pascal Assignment C:UsersDanielleDocumentsVisual Studio 2015ProjectsPascal AssignmentDebugPascal Assignment.exe 1 Severity Code Description Project File Line Suppression State Error LNK2019 unresolved external symbol _main referenced in function "int __cdecl invoke_main(void)" (?invoke_main@@YAHXZ) Pascal Assignment C:UsersDanielleDocumentsVisual Studio 2015ProjectsPascal AssignmentMSVCRTD.lib(exe_main.obj) 1