-1

I am very new to both C & C++, my task is to convert a program from C to C++ (Without using any C libraries!). I have done so to the best of my knowledge, but there is one issue. The issue is how would I complete the task without using cstrings (string.h) ? This is probably something simple, but I was unable to it figure out, Thank you!

Part of the program that's using it:

#include <iostream> // Include the I/O library that comes with C++.
//#include <string>
#include <string.h>

#include "scan.h" // Include the local header file.

using namespace std; // State the namespace std, this is used to make the code cleaner and simpler.

char token_image[100];

token scan() {
    static int c = ' '; // next available char; extra (int) width accommodates EOF
    int i = 0; // index into token_image

    /* skip white space */
    while (isspace(c)) {
        c = getchar();
    }
    if (c == EOF)
        return t_eof;
    if (isalpha(c)) {
        do {
            token_image[i++] = c;
            c = getchar();
        } while (isalpha(c) || isdigit(c) || c == '_');
        token_image[i] = '\0';
        if (!strcmp(token_image, "read")) return t_read;
        else if (!strcmp(token_image, "write")) return t_write;
        else return t_id;
    }
    else if (isdigit(c)) {
        do {
            token_image[i++] = c;
            c = getchar();
        } while (isdigit(c));
        token_image[i] = '\0';
        return t_literal;
    } else switch (c) {
        case ':':
            if ((c = getchar()) != '=') {
                cout << stderr << "error\n";
                exit(1);
            } else {
                c = getchar();
                return t_gets;
            }
            break;
        case '+': c = getchar(); return t_add;
        case '-': c = getchar(); return t_sub;
        case '*': c = getchar(); return t_mul;
        case '/': c = getchar(); return t_div;
        case '(': c = getchar(); return t_lparen;
        case ')': c = getchar(); return t_rparen;
        default:
            cout << "error\n";
            exit(1);
    }
}

The header file that is defined is this (if needed):

typedef enum {t_read, t_write, t_id, t_literal, t_gets,
                t_add, t_sub, t_mul, t_div, t_lparen, t_rparen, t_eof} token;

// Define an array and a function that are extern (Visible to the whole program). These are essential to the program.
extern char token_image[100];

extern token scan();
Clifford
  • 88,407
  • 13
  • 85
  • 165
Vrej
  • 70
  • 1
  • 8
  • 1
    There’s nothing wrong with using `cstring` functions in C++ if you don’t need to support extended character sets (Unicode …). Don’t use `string.h`, it doesn’t properly namespace its functions. But you’re also currently using the C function `getchar`, which you can/should replace with `std::cin.get()` or other C++ stream input functions. – Konrad Rudolph Feb 10 '20 at 17:41
  • 1
    Worth noting that `using namespace std`, in contrast to making "the code cleaner and simpler," is considered a bad practice. https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice – Travis Gockel Feb 10 '20 at 17:43
  • 5
    You should use `std::string` instead of C strings. – Barmar Feb 10 '20 at 17:43
  • At that level, C++ can be taken as a superset of C. There are exceptions, but generally most valid C code is C++ code. After that however, you have to abandon C-style practises like malloc etc. – Michael Chourdakis Feb 10 '20 at 17:45
  • You can't convert from one language to the other. – Jesper Juhl Feb 10 '20 at 17:46
  • 2
    Basic steps to translating a program from one language to another: 1) understand the behaviour of the program in the source language. 2) Implement the behaviour of the source program in the new language adhering to the new language's best practices and taking advantage of its idioms. 3) Test the new program against the source program to ensure the behaviour is identical. In the case of C to C++, often the best answer is to do nothing. If the C code works, use it. – user4581301 Feb 10 '20 at 17:53
  • "my task is to convert a program from C to C++" - That is not doable in general. – Jesper Juhl Feb 10 '20 at 18:01
  • 1
    @JesperJuhl he's not being asked to automate it or do it in general, it's just an exercise to learn what the C++ analogues are to C features. – Barmar Feb 10 '20 at 18:02
  • @user4581301 This is an academic exercise. The conditions specifically say that they're not allowed to use the C functions, they're supposed to convert to the equivalent C++ mechanisms, like `std::string`. – Barmar Feb 10 '20 at 18:04
  • @Bramar: Perhaps "_alternative_ C++ mechanisms" rather then "equivalent" - if I were being pedantic (which I am). A simple (and probably unacceptable) solution is to insert `std::` in front to all the C function names - then they are no longer C functions. ;-) – Clifford Feb 10 '20 at 18:22
  • Haven't you answered your own question - you included `` but inexplicably commented it out. You have a long way to go and appear to have done little to translate this code to something less C-like - more than just string handling. I suggest that you don' use `using namespace std;` or include C headers - that way any use of a C library function will cause an error - so you won't miss any. And besides it does not make the code _"cleaner and simpler"_. – Clifford Feb 10 '20 at 18:29
  • Note that there is no C++ specific replacement for functions such as `isdigit()`. You need to include `` and use `std::isdigit()`, which ultimately is the same function, but it is no longer C - or write an explicit character test yourself. The constraints are somewhat unclear. When moved to the `std::` namespace the entire C library is an intrinsic part of the standard C++ library, so strictly there is no need to change anything to meet the constraint. – Clifford Feb 10 '20 at 18:33
  • @clifford Thank you for the recommendations, as for the include statements and the namespace, I did test by removing both of them, the only error I received was that strcomp wasn't found, but rest of the functions seemed to run fine without even including anything. I am using g++ on a terminal to test the program. – Vrej Feb 10 '20 at 18:37
  • @Vrej : Does your "scan.h" have a `using namespace std:` directive in it perhaps? Or a nested standard include of the `` rather then `` form? What compiler version are you using, and what compiler / preprocessor options? – Clifford Feb 10 '20 at 18:47
  • I have the scan.h file posted at the bottom of the question, it's rather a very small and simple file. As for the compiler it's g++ with only the -o option to give a specific name, and it's using C++ 2011 to compile the program. – Vrej Feb 10 '20 at 18:56
  • @Vrej : I just tried it with your code, and you are right. It seems to be a g++ thing - (some) other compilers will object: https://stackoverflow.com/questions/45087872/is-there-a-gcc-warning-for-using-symbols-from-the-c-library-not-through-namespac. They are included indirectly through `` and are placed in both the global and `std::` namespace at the same time - other compilers may _move_ them to `std::`. I say that, but I tried it in clang and VC++ and neither object. Oh well. – Clifford Feb 10 '20 at 18:58
  • @Vrej : Yes I assumed the scan.h was a fragment since it lacks necessary include guards. – Clifford Feb 10 '20 at 18:59

1 Answers1

3

Some simple mechanistic changes to kick-start you:

Include <string>, remove <string.h>

Change:

char token_image[100]; 

to:

std::string token_image ;

Change:

token_image[i++] = c;

to:

 token_image += c ;

Delete:

token_image[i] = '\0';

Change

if (!strcmp(token_image, "read")) return t_read;

to:

if( token_image != "read" ) return t_read ;

Similarly for the rest of the code the above covers all the string operations used in this code.

user4581301
  • 33,082
  • 7
  • 33
  • 54
Clifford
  • 88,407
  • 13
  • 85
  • 165