Форум программистов, компьютерный форум CyberForum.ru

Ошибка линкера - C++

Восстановить пароль Регистрация
 
Denis_nn
0 / 0 / 0
Регистрация: 15.03.2012
Сообщений: 11
24.07.2012, 11:23     Ошибка линкера #1
Здравствуйте!!! Подскажите пожалуйста почему возникают ошибки линкера?
C++
1
2
3
4
5
6
7
8
9
10
11
12
// main.cpp
 
#include "parser.h"
 
int main()
{
 char prog_buff[PROG_SIZE];
 
  load_program(prog_buff,"E:/projects/vars_test.dci");
 //getch();
 return 0;
}
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
// parser.h
 
#pragma once
 
#include "constants_list.h"
#include "variables_list.h"
 
const int PROG_SIZE = 10000;
 
// The DCI command tokens.
enum DCItokensT { UNKNCOM, PRINT, INPUT, IF, THEN, FOR, NEXT, TO,
                 GOTO, GOSUB, RETURN, EOL, FINISHED, END };
// The DCI token types.
enum typesT { UNDEFTOK, OPERATOR, NUMBER, VARIABLE, COMMAND,
              STRING, QUOTE };
 
/* These are the constants used to call serror() when
   a syntax error occurs.  Add more if you like.
   NOTE: SERROR is a generic error message used when
   nothing else seems appropriate. */
enum errorsT { SERROR, PARENS, NOEXP, DIV_ZERO, EQUAL_EXP,
               NOT_VAR, LAB_TAB_FULL, DUP_LAB, UNDEF_LAB,
               THEN_EXP, TO_EXP, TOO_MNY_FOR, NEXT_WO_FOR,
               TOO_MNY_GOSUB, RET_WO_GOSUB, MISS_QUOTE };
 
// check for double op
enum double_ops { LE, GE, NE };
 
// keyword lookup table
/*
struct commands { 
  char command[20]; // string form 
  DCItokensT tok; // internal representation 
} table[] = { // commands must be entered lowercase 
  "print", PRINT, // in this table. 
  "input", INPUT,
  "if", IF,
  "then", THEN,
  "goto", GOTO,
  "for", FOR,
  "next", NEXT,
  "to", TO,
  "gosub", GOSUB,
  "return", RETURN,
  "end", END,
  "", END  // mark end of table 
};*/
 
char *prog;
typesT tok_type;
DCItokensT tok;
char token[20];
 
class parser
{
    void serror(errorsT);
    DCItokensT look_up(char*); // convert to internal rep 
    typesT get_token();
    
 public:
    parser();
    ~parser();
    
    bool isdelim(char);
    bool is_sp_tab(char);
};
 
typesT parser::get_token()
{
 register char *temp;
 
 tok_type = UNDEFTOK;
 temp = token;
 *temp = '\0';
 
 if(*prog=='\0') { // end of file 
    *token = '\0';
    tok = FINISHED;
    return(tok_type=OPERATOR);
  }
 
 if(*prog=='\r') 
  { // crlf 
      ++prog; ++prog;
      return(tok_type = OPERATOR);
  }
  while(is_sp_tab(*prog)) ++prog; // skip over white space
 
  if(strchr("+-%*/^=()", *prog)){ 
    tok_type = OPERATOR;
    // advance to next char
    *temp++ = *prog++;
  }
 
  if(strchr("<>", *prog)) { // check for double op
    switch(*prog) {
      case '<':
        if(*(prog+1)=='>') {
          prog++; prog++;
          *temp = NE;
        }
        else if(*(prog+1)=='=') {
          prog++; prog++;
          *temp = LE;
        }
        else {
          prog++;
          *temp = '<';
        }
        temp++;
        *temp = '\0';
        break;
      case '>':
        if(*(prog+1)=='=') {
          prog++; prog++;
          *temp = GE;
        }
        else {
          prog++;
          *temp = '>';
        }
        temp++;
        *temp = '\0';
        break;
    }
    return(tok_type = OPERATOR);
  }
  if(strchr("+-*^/=;(),", *prog)){ // operator
    *temp = *prog;
    prog++; // advance to next position 
    temp++;
    *temp = '\0'; 
    return (tok_type=OPERATOR);
  }
    
  if(*prog=='"') { // quoted string 
    prog++;
    while(*prog!='"'&& *prog!='\r') *temp++ = *prog++;
    if(*prog=='\r') serror(MISS_QUOTE);
    prog++; *temp = '\0';
    return(tok_type=QUOTE);
  }
  
  if(isdigit(*prog)) { // number 
    while(!isdelim(*prog)) *temp++ = *prog++;
    *temp = '\0';
    return(tok_type = NUMBER);
  }
 
  if(isalpha(*prog)) { // var or command 
    while(!isdelim(*prog)) *temp++ = *prog++;
    tok_type = STRING;
  }
  
  *temp = '\0';
 
  // see if a string is a command or a variable 
  if(tok_type==STRING) {
    tok = look_up(token); // convert to internal rep 
    if(!tok) tok_type = VARIABLE;
    else tok_type = COMMAND; // is a command 
  }
  return tok_type;
}
/*
  
  
 
  
 
  /*
  if(isalpha(*prog) && strstr(prog,"const")) {
    while(*prog != 't') *prog++;*prog++;
    while(is_sp_tab(*prog))*prog++;
    *temp++ = *prog++;
    tok_type = CONSTANT;
  }
   else if(isalpha(*prog)) {
    while(!isdelim(*prog)) *temp++ = *prog++;
    return(tok_type = VARIABLE);
  } 
   else if(isdigit(*prog)) {
    while(!isdelim(*prog)) *temp++ = *prog++;
    return(tok_type = NUMBER);
  }
 
  *temp = '\0';
}*/
 
// Return true if c is a delimiter. 
bool parser::isdelim(char c)
{
  if(strchr(" ;,+-<>/*%^=()", c) || c==9 || c=='\r' || c==0) 
    return true;  
  return false; 
}
 
// Return true if c is space or tab. 
bool parser::is_sp_tab(char c)
{
  if(c==' ' || c=='\t') return true;
  else return false;
}
 
// Load a program.
bool load_program(char *p, char *fname)
{
  ifstream in(fname, ios::in | ios::binary);
  int i=0;
  prog = p;
  if(!in) {
    cout << "File not found ";
    cout << "-- be sure to specify .BAS extension.\n";
    return false;
  }
  
  i = 0;
  do {
    *p = in.get();
    p++; i++;
  } while(!in.eof() && i<PROG_SIZE);
 
  // null terminate the program
  if(*(p-2)==0x1a) *(p-2) = '\0'; // discard eof marker
  else *(p-1) = '\0';
 
  in.close();
  return true;
}
/* Look up a token's internal representation in the
   token table.
 
 
DCItokensT look_up(char *s)
{
  register int i;
  char *p;
 
  // convert to lowercase 
  p = s;
  while(*p){ 
    *p = tolower(*p);
    p++;
  }
 
  // see if token is in table 
  for(i=0; *table[i].command; i++)
    if(!strcmp(table[i].command, s))
      return table[i].tok;
  return UNKNCOM; // unknown command
}*/
// CONSTANTS
/*
if(isalpha(*prog) && strstr(prog,"const")) {
    while(*prog != 't') *prog++;*prog++;
    while(is_sp_tab(*prog))*prog++;
    *temp++ = *prog++;
    tok_type = CONSTANT;
  }
  */
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
//variables_list.h
 
#pragma once
 
#include "header.h"
 
const int SIZE_OF_NAME_C = 20;
 
class vars_list
{
 class node
 {
  
    friend class vars_list;
 
    char name[SIZE_OF_NAME_C];
    double value;
    node *next;
    node *prev;
 
 public:
     node(){value = 0;}
     node(double vl):value(vl)
     { }
     ~node(){}  
 };
 
 public:
 
    node *head;
    node *tayl;
 
    vars_list(){}
    ~vars_list(){}
 
    void create();              // create empty list
    void add_var(char*,double); // add variable
    bool exist(char*);          // if exist
 
};
 
 
///////////////////////////////////////////////////
bool vars_list::exist(char *name)
{
 
 node *pHead = head;
 
 while(pHead != tayl)
     if(strstr(name,pHead->name))
         return true;
     else
         pHead = pHead->next;
 return false;
}
///////////////////////////////////////////////////
void vars_list::create()
{
 head = tayl = new node;
 
 head->next = tayl;
 tayl->next = 0;
 tayl->prev = 0;
 
}
///////////////////////////////////////////////////
void vars_list::add_var(char *name,double var)
{
 node *pnode = new node(var);
 pnode->next = head;
 pnode->prev = 0;
 head->prev = pnode;
 head = pnode;
 
 int i = 0;
 while(isalpha(*name))
 {
  head->name[i] = *name;
  i++; *name++;
 }
 head->name[i] = '\0';
}
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
//constants_list.h
 
#pragma once
 
#include "header.h"
 
const int SIZE_OF_NAME_V = 20;
 
class const_list
{
 class node
 {
  
    friend class const_list;
 
    char name[SIZE_OF_NAME_V];
    double value;
    node *next;
    node *prev;
 
 public:
     node(){value = 0;}
     node(double vl):value(vl)
     { }
     ~node(){}  
 };
 
 public:
 
    node *head;
    node *tayl;
 
    const_list(){}
    ~const_list(){}
 
    void create();              // create empty list
    void add_var(char*,double); // add variable
    bool exist(char*);          // if exist
 
};
 
 
///////////////////////////////////////////////////
bool const_list::exist(char *name)
{
 
 node *pHead = head;
 
 while(pHead != tayl)
     if(strstr(name,pHead->name))
         return true;
     else
         pHead = pHead->next;
 return false;
}
///////////////////////////////////////////////////
void const_list::create()
{
 head = tayl = new node;
 
 head->next = tayl;
 tayl->next = 0;
 tayl->prev = 0;
 
}
///////////////////////////////////////////////////
void const_list::add_var(char *name,double var)
{
 node *pnode = new node(var);
 pnode->next = head;
 pnode->prev = 0;
 head->prev = pnode;
 head = pnode;
 
 int i = 0;
 while(isalpha(*name))
 {
  head->name[i] = *name;
  i++; *name++;
 }
 head->name[i] = '\0';
}
C++
1
2
3
4
5
6
7
8
9
// header.h
 
#pragma once
 
#include <iostream>
#include <fstream>
#include <conio.h>
 
using namespace std;
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
24.07.2012, 11:37     Ошибка линкера #2
Я, наверное, не прав, но разве :
C++
1
load_program(prog_buff,"E:/projects/vars_test.dci");
а не :
C++
1
load_program(prog_buff,"E:\\projects\\vars_test.dci");
Denis_nn
0 / 0 / 0
Регистрация: 15.03.2012
Сообщений: 11
24.07.2012, 11:55  [ТС]     Ошибка линкера #3
Цитата Сообщение от nexen Посмотреть сообщение
Я, наверное, не прав, но разве :
C++
1
load_program(prog_buff,"E:/projects/vars_test.dci");
а не :
C++
1
load_program(prog_buff,"E:\\projects\\vars_test.dci");
Код из файла грузится нормально!

Добавлено через 36 секунд
Он и так и так почему-то грузится)))

Добавлено через 9 минут
Ну ребят! Ну хоть кто-нибудь подскажите!!!!
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
24.07.2012, 12:09     Ошибка линкера #4
Denis_nn, можешь хотя бы написать, что за ошибка?
defer
秘密
 Аватар для defer
555 / 235 / 3
Регистрация: 29.11.2010
Сообщений: 783
24.07.2012, 12:23     Ошибка линкера #5
две функции объявлены
C++
1
2
void serror(errorsT);
DCItokensT look_up(char*);
но нет реализации, вот такая ошибка
Denis_nn
0 / 0 / 0
Регистрация: 15.03.2012
Сообщений: 11
24.07.2012, 12:33  [ТС]     Ошибка линкера #6
Цитата Сообщение от defer Посмотреть сообщение
две функции объявлены
C++
1
2
void serror(errorsT);
DCItokensT look_up(char*);
но нет реализации, вот такая ошибка

Вот новый parser.h, в катором все объявлено, но тоже самое!(((

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
#pragma once
 
#include "constants_list.h"
#include "variables_list.h"
 
const int PROG_SIZE = 10000;
 
// The DCI command tokens.
enum DCItokensT { UNKNCOM, PRINT, INPUT, IF, THEN, FOR, NEXT, TO,
                 GOTO, GOSUB, RETURN, EOL, FINISHED, END };
// The DCI token types.
enum typesT { UNDEFTOK, OPERATOR, NUMBER, VARIABLE, COMMAND,
              STRING, QUOTE };
 
/* These are the constants used to call serror() when
   a syntax error occurs.  Add more if you like.
   NOTE: SERROR is a generic error message used when
   nothing else seems appropriate. */
enum errorsT { SERROR, PARENS, NOEXP, DIV_ZERO, EQUAL_EXP,
               NOT_VAR, LAB_TAB_FULL, DUP_LAB, UNDEF_LAB,
               THEN_EXP, TO_EXP, TOO_MNY_FOR, NEXT_WO_FOR,
               TOO_MNY_GOSUB, RET_WO_GOSUB, MISS_QUOTE };
 
// check for double op
enum double_ops { LE, GE, NE };
 
// keyword lookup table
 
struct commands { 
  char command[20]; // string form 
  DCItokensT tok; // internal representation 
} table[] = { // commands must be entered lowercase 
  "print", PRINT, // in this table. 
  "input", INPUT,
  "if", IF,
  "then", THEN,
  "goto", GOTO,
  "for", FOR,
  "next", NEXT,
  "to", TO,
  "gosub", GOSUB,
  "return", RETURN,
  "end", END,
  "", END  // mark end of table 
};
 
char *prog;
char *p_buf; // points to start of program
typesT tok_type;
DCItokensT tok;
char token[20];
 
class parser
{
    void serror(errorsT);
    DCItokensT look_up(char*); // convert to internal rep 
    typesT get_token();
    
 public:
    parser();
    ~parser();
    
    bool isdelim(char);
    bool is_sp_tab(char);
};
 
typesT parser::get_token()
{
 register char *temp;
 
 tok_type = UNDEFTOK;
 temp = token;
 *temp = '\0';
 
 if(*prog=='\0') { // end of file 
    *token = '\0';
    tok = FINISHED;
    return(tok_type=OPERATOR);
  }
 
 if(*prog=='\r') 
  { // crlf 
      ++prog; ++prog;
      return(tok_type = OPERATOR);
  }
  while(is_sp_tab(*prog)) ++prog; // skip over white space
 
  if(strchr("+-%*/^=()", *prog)){ 
    tok_type = OPERATOR;
    // advance to next char
    *temp++ = *prog++;
  }
 
  if(strchr("<>", *prog)) { // check for double op
    switch(*prog) {
      case '<':
        if(*(prog+1)=='>') {
          prog++; prog++;
          *temp = NE;
        }
        else if(*(prog+1)=='=') {
          prog++; prog++;
          *temp = LE;
        }
        else {
          prog++;
          *temp = '<';
        }
        temp++;
        *temp = '\0';
        break;
      case '>':
        if(*(prog+1)=='=') {
          prog++; prog++;
          *temp = GE;
        }
        else {
          prog++;
          *temp = '>';
        }
        temp++;
        *temp = '\0';
        break;
    }
    return(tok_type = OPERATOR);
  }
  if(strchr("+-*^/=;(),", *prog)){ // operator
    *temp = *prog;
    prog++; // advance to next position 
    temp++;
    *temp = '\0'; 
    return (tok_type=OPERATOR);
  }
    
  if(*prog=='"') { // quoted string 
    prog++;
    while(*prog!='"'&& *prog!='\r') *temp++ = *prog++;
    if(*prog=='\r') serror(MISS_QUOTE);
    prog++; *temp = '\0';
    return(tok_type=QUOTE);
  }
  
  if(isdigit(*prog)) { // number 
    while(!isdelim(*prog)) *temp++ = *prog++;
    *temp = '\0';
    return(tok_type = NUMBER);
  }
 
  if(isalpha(*prog)) { // var or command 
    while(!isdelim(*prog)) *temp++ = *prog++;
    tok_type = STRING;
  }
  
  *temp = '\0';
 
  // see if a string is a command or a variable 
  if(tok_type==STRING) {
    tok = look_up(token); // convert to internal rep 
    if(!tok) tok_type = VARIABLE;
    else tok_type = COMMAND; // is a command 
  }
  return tok_type;
}
/*
  
  
 
  
 
  /*
  if(isalpha(*prog) && strstr(prog,"const")) {
    while(*prog != 't') *prog++;*prog++;
    while(is_sp_tab(*prog))*prog++;
    *temp++ = *prog++;
    tok_type = CONSTANT;
  }
   else if(isalpha(*prog)) {
    while(!isdelim(*prog)) *temp++ = *prog++;
    return(tok_type = VARIABLE);
  } 
   else if(isdigit(*prog)) {
    while(!isdelim(*prog)) *temp++ = *prog++;
    return(tok_type = NUMBER);
  }
 
  *temp = '\0';
}*/
 
// Return true if c is a delimiter. 
bool parser::isdelim(char c)
{
  if(strchr(" ;,+-<>/*%^=()", c) || c==9 || c=='\r' || c==0) 
    return true;  
  return false; 
}
 
// Return true if c is space or tab. 
bool parser::is_sp_tab(char c)
{
  if(c==' ' || c=='\t') return true;
  else return false;
}
 
// Load a program.
bool load_program(char *p, char *fname)
{
  ifstream in(fname, ios::in | ios::binary);
  int i=0;
  prog = p;
  if(!in) {
    cout << "File not found ";
    cout << "-- be sure to specify .BAS extension.\n";
    return false;
  }
  
  i = 0;
  do {
    *p = in.get();
    p++; i++;
  } while(!in.eof() && i<PROG_SIZE);
 
  // null terminate the program
  if(*(p-2)==0x1a) *(p-2) = '\0'; // discard eof marker
  else *(p-1) = '\0';
 
  in.close();
  return true;
}
/* Look up a token's internal representation in the
   token table.
*/ 
 
DCItokensT look_up(char *s)
{
  register int i;
  char *p;
 
  // convert to lowercase 
  p = s;
  while(*p){ 
    *p = tolower(*p);
    p++;
  }
 
  // see if token is in table 
  for(i=0; *table[i].command; i++)
    if(!strcmp(table[i].command, s))
      return table[i].tok;
  return UNKNCOM; // unknown command
}
 
// Display an error message.
void serror(errorsT error)
{
  char *p, *temp;
  int linecount = 0;
  register int i;
 
  static char *e[]= {   
    "Syntax error", 
    "Unbalanced parentheses", 
    "No expression present",
    "Division by zero",
    "Equal sign expected",
    "Not a variable",
    "Label table full",
    "Duplicate label",
    "Undefined label",
    "THEN expected",
    "TO expected",
    "Too many nested FOR loops",
    "NEXT without FOR",
    "Too many nested GOSUBs",
    "RETURN without GOSUB",
    "Double qoutes needed"
  }; 
  cout << e[error]; 
 
  p = p_buf;
  while(p != prog) {  // find line number of error 
    p++;
    if(*p == '\r') {
      linecount++;
    }
  }
  cout << " in line " << linecount << ".\n";
 
  temp = p;  // display line with error
  for(i=0; i<20 && p>p_buf && *p!='\n'; i++, p--);
  for(; p<=temp; p++) cout << *p;
    
  throw(1); // throw an exception
}
// CONSTANTS
/*
if(isalpha(*prog) && strstr(prog,"const")) {
    while(*prog != 't') *prog++;*prog++;
    while(is_sp_tab(*prog))*prog++;
    *temp++ = *prog++;
    tok_type = CONSTANT;
  }
  */
Добавлено через 51 секунду
Ага,извиняюсь!!! Я забыл объявить их методами класса!))) Вроде все пока работает, спасибо за помощь!
Yandex
Объявления
24.07.2012, 12:33     Ошибка линкера
Ответ Создать тему
Опции темы

Текущее время: 00:46. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru