简体   繁体   中英

C program writing random strings to file

The following C program takes "BasicTest.vm" as an input file and produces "BasicTest.asm" as an output file.

// This is the VM Translator that shall covert
// Stack based VM program to HACK Mnemonics
// This will translate the the Arithmetic/Logical and
// Memory access VM Instructions

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAXCHARPERLINE 80

//This function opens the input VM file given in the command line

FILE* initializeParser(char *filename) {

    return(fopen(filename,"r"));

} //End initializeParser

//This function opens the file into which mnemonic output is written into
// It takes the input file Xxxxxx.vm and create Xxxxxx.asm as the
//Output filename

FILE* initializeOutput(char *filename) {

    int i = 0;

    while(filename[i] != '.') i++;

    filename[i+1] = 'a';
    filename[i+2] = 's';
    filename[i+3] = 'm';
    filename[i+4] = '\0';

    return(fopen(filename,"w"));
}

void fileNameforLabel(char *filename,char *outfileName) {

    int i = 0;
    while(filename[i] != '.') {
        if ((filename[i] != '/') && (filename[i] == '\\'))
            outfileName[i] = filename[i];
        i++;
    }
    outfileName[i] = '.';
    outfileName[i+1] = '\0';
}

void generateCode(FILE* outputFile, char *symbol2, char *symbol3, char *filename){
    
    fprintf(outputFile,"@%s\n",symbol2);
    fprintf(outputFile,"@%s\n",symbol3);
    fprintf(outputFile,"@%s\n",filename);
}


//The main() function takes the name of input VM file as command line

void main(int argc, char **argv) {

    FILE *inputFile;
    FILE *outputFile;

    int i,j,k; //Temporary variables

    int ALabelNum = 0; // Label Number for Arithmetic Instructions
    int lineNumber = 0; //This keeps the count of number of lines read

    //The nextCommand string will store the command to be processed
    // This is called a buffer
    char nextCommand[MAXCHARPERLINE];

    //This paraedCommand string is nextCommand without whitespaces
    char parsedCommand[MAXCHARPERLINE];

    // Temporary strings for holding symbols
    char symbol1[MAXCHARPERLINE];
    char symbol2[MAXCHARPERLINE];
    char symbol3[MAXCHARPERLINE];
    char symbol4[MAXCHARPERLINE];


    //Opening the input and files
    inputFile = initializeParser(argv[1]);
    outputFile = initializeOutput(argv[1]);

    fileNameforLabel(argv[1],symbol4);
    //Reading the input file line after line till End of file
    //fgets() is used for reading.

    while(fgets(nextCommand,MAXCHARPERLINE,inputFile) != NULL) {

        //Inside this loop we parse the command got through nextCommand

        i = 0;
        j = 0;
        parsedCommand[0] = '\0'; //Initializing parsed command


        //Go till the first non whitespace character
        while ((nextCommand[i] == ' ') || (nextCommand[i] == '\t'))
            i++;

        // Check and remove comment at any part of line

        while (nextCommand[i] != '\n') {
            if ((nextCommand[i] == '/') && (nextCommand[i+1] == '/')) {
                break;
            }
            else
            {
                parsedCommand[i] = nextCommand[i];
            }
            i++;
        }
        parsedCommand[i] = '\n';
        parsedCommand[i+1] = '\0';

        //Extracting Symbols
        i = 0;
        symbol1[0] = '\0';
        symbol2[0] = '\0';
        symbol3[0] = '\0';

        //Extract first symbol
        while ((parsedCommand[i] != ' ') && (parsedCommand[i] != '\t') && (parsedCommand[i] != '\n')) {
            symbol1[i] = parsedCommand[i];
            i++;
        }
        symbol1[i] = '\0';

        //Goto Second symbol
        while ((parsedCommand[i] == ' ') || (parsedCommand[i] == '\t'))
            i++;

        // Check if end of line
        if (parsedCommand[i] != '\n')
        {
            //Extract Symbol 2
            j = 0;
            while ((parsedCommand[i] != ' ') && (parsedCommand[i] == '\t') && (parsedCommand[i] != '\n'))
                symbol2[j++] = parsedCommand[i++];
            symbol2[j] = '\0';
            //Goto Symbol 3
            while ((parsedCommand[i] == ' ') || (parsedCommand[i] == '\t'))
                i++;
            // Check if end of line
            if (parsedCommand[i] != '\n')
            {
                //Extract Symbol 3
                j = 0;
                while ((parsedCommand[i] != ' ') && (parsedCommand[i] == '\t') && (parsedCommand[i] != '\n'))
                    symbol3[j++] = parsedCommand[i++];
                symbol3[j] = '\0';
            }
        }
        fprintf(outputFile,"// %s",parsedCommand);
        if (symbol1[0] != '\0')
            generateCode(outputFile, symbol2, symbol3, symbol4);

    }

    fclose(inputFile);
    fclose(outputFile);
}

Here is the BasicTest.vm file

// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/07/MemoryAccess/BasicTest/BasicTest.vm

// Executes pop and push commands using the virtual memory segments.
push constant 10
pop local 0
push constant 21
push constant 22
pop argument 2
pop argument 1
push constant 36
pop this 6
push constant 42
push constant 45
pop that 5
pop that 2
push constant 510
pop temp 6
push local 0
push that 5
add
push argument 1
sub
push this 6
push this 6
add
sub
push temp 6
add

The problem is that the program is printing some random characters in the "BasicTest.asm" file.

Here is the BasicTest.asm file

// 
// 
// 
// 
// 
// 
// push constant 10
@
@
@úÿÿ
// pop local 0
@
@
@úÿÿ
// push constant 21
@
@
@úÿÿ
// push constant 22
@
@
@úÿÿ
// pop argument 2
@
@
@úÿÿ
// pop argument 1
@
@
@úÿÿ
// push constant 36
@
@
@úÿÿ
// pop this 6
@
@
@úÿÿ
// push constant 42
@
@
@úÿÿ
// push constant 45
@
@
@úÿÿ
// pop that 5
@
@
@úÿÿ
// pop that 2
@
@
@úÿÿ
// push constant 510
@
@
@úÿÿ
// pop temp 6
@
@
@úÿÿ
// push local 0
@
@
@úÿÿ
// push that 5
@
@
@úÿÿ
// add
@
@
@úÿÿ
// push argument 1
@
@
@úÿÿ
// sub
@
@
@úÿÿ
// push this 6
@
@
@úÿÿ
// push this 6
@
@
@úÿÿ
// add
@
@
@úÿÿ
// sub
@
@
@úÿÿ
// push temp 6
@
@
@úÿÿ
// add
@
@
@úÿÿ

According to what I have understood the problem is in the generateCode function. Basically it takes outputFile, symbol2, symbol3, symbol4 as arguments and writes them in the file but instead of printing those values it is printing either nothing or some random characters.

I don't understand why?

try to use %s instead of @%s in generateCode function

This function goes beyond the last character of the file name: initializeOutput. asm will overwrite v, m \n. Where will the new \n go?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM