Simple, custom analysis using C ++

I have been reading SO for some time now, but I really can't find any help for my problem.

I have C ++ - an assignment for creating an IAS simulator.

Here is a sample code ...

0 1 a 1 2 b 2 c 3 1 10 begin 11 . load a, subtract b and offset by -1 for jump+ 11 load M(0) 12 sub M(1) 13 sub M(3) 14 halt 

Using C ++, I need to be able to read these lines and store them in the "memory register" class that I already created ...

For example, the first line would have to store "1 a" in the register note.

How can I parse the number at the beginning of a line and then save the rest as a string?

I have an installation repository using a class that is called using mem.set(int, string); . int is the memory location at the beginning of the line, and string is the stored instruction.

Edit: some clarification:

+4
source share
6 answers

Separating the leading number and the rest of the line is not a difficult task. Use something like getline to read one line at a time from your input file and save the line in char cur_line[] . For each line, try something like this:

  • Declare a char* pString and an integer int line_num
  • Use strstr to find the first space character and assign the result to pString .
  • Move pString forward one character at a time until it points to a character without spaces. This is the beginning of a line containing "the rest of the line".
  • Use atoi in cur_line to convert the first record in a string to an integer and store the results in line_num
  • Now you can name your function, for example mem.set(line_num, pString)

Interpretation of these lines will be much more difficult, however ...

Edit: As Mike De Simon mentions, you can combine the strstr and atoi steps above if you use one of strto* instead of atoi .

0
source

I would advise <ifstream> look at the <ifstream> library.

+2
source
 #include <iostream> // #include <fstream> for file objects as others suggest #include <string> #include <map> using namespace std; map<int, string> my_program; int line_num; string line_text; while ( cin >> line_num ) { // or any input stream such as a file getline( cin, line_text ); // standard function defined in <string> my_program[ line_num ] = line_text; // store line for next phase } 

This will read the lines of the file until the end is met, or the line that starts with something other than a number. Use cin.eof() to make sure the entire file has been read if you are interested.

Of course, since map sorts its contents, the lines will be in the following order for the next step.

+1
source

If the first part of the string is always a number, look at the strtoul function. On the man page:

strtoul - convert string to unsigned integer

LIBRARY

C Standard Library (libc, -lc)

SYNTAX

  #include <stdlib.h> unsigned long strtoul(const char *restrict str, char **restrict endptr, int base); 

DESCRIPTION

The strtoul () function converts a string to str into an unsigned long value. The conversion is performed in accordance with this base, which must be from 2 to 36 inclusive or be a special value of 0.

A line can begin with an arbitrary number of spaces (as defined by isspace(3) ), followed by one optional + or - sign. If base is zero or 16, the string may include the 0x prefix, and the number will be read in base 16; otherwise, the zero base is taken as 10 (decimal), unless the next character is 0 , in which case it is taken as 8 (octal).

The rest of the string is converted to an unsigned long value in an obvious way, stopping at the end of the string or on the first character, which does not give a valid digit in this database. (In the bases above 10, the letter A in upper or lower case represents 10, B represents 11, etc., with Z representing 35.)

If endptr not NULL , strtoul() stores the address of the first invalid character in *endptr . However, if there were no digits, strtoul() saves the original str value in *endptr . (Thus, if *str not \0 but **endptr is \0 by return, the entire string is valid.)

RETURN VALUES

The strtoul () function returns either the conversion result, or, if there was a major minus sign, the negation of the conversion result, if only the original (non-denied) value is overflowed; in the latter case strtoul() returns ULONG_MAX . In all cases, errno set to ERANGE . If the conversion cannot be performed, 0 is returned and the global variable errno is set to EINVAL .


The key here is the endptr parameter. It sets a pointer to where you need to continue parsing. If endptr == str , then you know that the string did not start with a number.

I like the strto___ family of functions much more than the ato__ functions, because you can set base (including the context-sensitive "base 0"), and since endptr tells me where to continue. (And for embedded applications, strto___ much smaller than __scanf functions.)

EDIT: Sorry to miss your comment. To use endptr , write code like this:

 char* restOfLine = NULL; unsigned long result = strtoul(lineBuffer, 10, &restOfLine); if(restOfLine == NULL || restOfLine == lineBuffer) { /* Handle error. */ } else { // Use result, and do further parsing starting at restOfLine. } 

Usually, the "handle error" clause returns or breaks or throws an exception or does something else to free itself from further processing, so you do not need an explicit else clause.

+1
source

Something like this might be useful to use the Boost.Spirit library. This is a C ++ EBNF parser generator, such as flex and yacc, without additional compilation steps.

0
source

Here's the easy part:

 std::string text_to_parse; unsigned int register_number; void Parse_Line(std::istream& data_file) { // Read in the register number. if(data_file >> register_number) { // Read the remaining line as a string {variable} getline(data_file, text_to_parse); // Now do something with the text... } return; } 

The problem with your data file is that it does not follow simple grammar or syntax. For example, you have two text lines starting with 11. Line 10 is not a line "memory register", but a line of commands. In addition, lines 2 and 3 do not correspond to the same grammar as 0 and 1.

For more help, send grammar rules (preferably in BNF syntax or in ASCII).

0
source

Source: https://habr.com/ru/post/1307817/


All Articles