[英]Stack Overflow with tail recursion function c++
該代碼的作用:
下面的代碼應該通過限制每行代碼中的字符數而不丟失任何代碼來格式化打印機的.cpp文件。 該代碼應該逐個通過char文件。 通過打開ifstream
然后使用get
方法來獲取每個字符,直到找到EOF
為止。 抓取每個字符時,將其推入一個std::string
( vector
),然后增加行字符數。 如果在行字符計數大於最大大小之前找到了新的行字符,它將被重置並在下一行繼續。 如果在找到'\\n'
n'char之前,行的char計數比最大char計數少2,則將\\
, \\n
, ' '
'的(x制表符計數)追加到要寫入的string
的末尾。 然后,將行的其余部分附加到string
。 但是,如果添加到string
的最后一個字符不是' '
char,則該string
會刪除其末尾和最接近左側' '
之間的所有字符' '
char並放置在新行的開頭,即5 ' '
在新行字符。 最后一點是我認為錯誤所在的位置。
示例行:(假裝大於最大字符數)
LongLong123 longLineOfCode;\n;
樣本輸出:
壞:
LongLong123 longLineOfCo\\n
de;\n
好:
LongLong123\\n
longLineOfCode;\n
錯誤:
SubmitFormater.exe中0x55CC1949(ucrtbased.dll)的未處理異常:0xC00000FD:堆棧溢出(參數:0x00000000,0x00F02000)。 發生了
示例命令行:
110 5 "C:/Users/holycatcrusher/Documents/OC 2018 Fall/222/Labs/COSC_222_Data_Structures_Cpp/SubmitFormater.cpp"
110是可以在一行中的字符數,5是制表符的字符數(5個空格),長字符串是要格式化的文件的地址(將文件復制為出錯時,輸入的文件將被銷毀)。 我正在使用構成該項目的代碼作為示例輸入(它的副本)。
編碼:
/* SubmitFormater.cpp
This file was created by Bradley Honeyman
Oct 25, 2018
This file is used to format submit files for COSC 222 asignments
*/
#include "pch.h"
#include <iostream>
#include <fstream>
#include <string>
#include <stdbool.h>
#include <stddef.h>
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
std::string *processFile(std::ifstream *input, int maxCharCount, int tabSpaceSize, char delimiter, std::string *code, int lineCharCount);
int toInt(char *input);
int main(int argc, char **argv) {
std::cout << "Running 222 formatter" << std::endl << "by: Bradley Honeyman" << std::endl;
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
//make sure there is the min number of commands
if (argc < 3) {
std::cout << "Ensure there is a specified max line length and at least one file to modify!" << std::endl;
return 0;
}
for (int i = 3; i < argc; i++) {
//open file and make sure it opens
std::ifstream input;
input.open(argv[i]);
if (!input.is_open()) {
std::cout << "Could not open the input file: " << argv[i] << std::endl;
return EXIT_FAILURE;
}
//process code
std::string *code = new std::string();
processFile(&input, toInt(argv[1]), toInt(argv[2]), ' ', code, 0);
//check for error
if (code == NULL) {
return EXIT_FAILURE;
}
//output
input.close();
std::ofstream out(argv[i]);
if (!out.is_open()) {
std::cout << "could not write to output file" << std::endl;
return EXIT_FAILURE;
}
//print to file
std::cout << code->c_str() << std::endl;
out << code->c_str();
//close out delete code pointer
out.close();
delete code;
}
return 0;
}
/*
formats a file by placing \\\n the custom tab whereever the length of a line is bigger than the max
also a delimiter is used, so words aren't cut in half
*/
#define FORMAT_CHAR_COUNT 2
std::string *processFile(std::ifstream *input, int maxCharCount, int tabSpaceSize, char delimiter, std::string *code, int lineCharCount) {
//std::cout << "Processing" << std::endl;
//get char and check if is end of file
char current = input->get();
//std::cout << "\'" << current << "\'" << std::endl;
if (input->eof()) {
return code;
}
//incerment char count then check if are at furthest possible position
lineCharCount++;
//std::cout << lineCharCount << std::endl;
if (current == '\n') {
lineCharCount = 0;
//check if are at max char count, split code and put to new line
} else if (lineCharCount >= maxCharCount && current != '\\') {
//if not at the end of the line go back to the closest delimiter to break
std::string *pre = new std::string("");
bool fail = false;
if (current != '\n' && code->at(code->size() - 1)) {
code->push_back(current);
int i = code->size() - 1;
int back = 0;
for (i; i >= 0; i--) {
pre->push_back(code->at(i));
back++;
if (back > maxCharCount - tabSpaceSize - FORMAT_CHAR_COUNT) {
std::cout << "Can not format file because there isn't a place close enough to break at a delimiter!" << std::endl;
fail = true;
break;
}
}
//check for fail
if (!fail) {
//add delimiter if it needs to be
if (pre->size() > 0 && pre->at(pre->size() - 1) != delimiter) {
pre->push_back(delimiter);
}
//reverse prepending string, and remove code that is to be prepended
std::reverse(pre->begin(), pre->end());
code->assign(code->substr(0, code->size() - back - 1));
}
}
//insert \ then new line then tab then set char count to tab size + pre size + 1 for char to be added
code->push_back('\\');
code->push_back('\n');
for (int i = 0; i < tabSpaceSize; i++) { code->push_back(' '); } //create tab
code->append(pre->c_str());
lineCharCount = tabSpaceSize + 1 + pre->size();
pre->clear();
delete pre;
}
//add char to code and run again
code->push_back(current);
return processFile(input, maxCharCount, tabSpaceSize, delimiter, code, lineCharCount);
}
/*
converts string to an int
*/
int toInt(char *input) {
int i = 0;
int out = 0;
while (input[i] != '\0') {
out = (out * 10) + (input[i] - '0');
i++;
}
return out;
}
另外,您可以將上面的代碼用作示例.cpp文件。 不過請記住要使用副本,因為程序會修改文件!
調用堆棧的第1部分和第2部分 (單擊圖像即可讀取它們)
注意:
問題的原因已包含在對話中。
經過這篇文章的大量討論之后,我認為值得發布最終成為我解決方案的東西。 還有一些關於我得出的結論的注釋。
碼:
/* SubmitFormater.cpp
This file was created by Bradley Honeyman
Oct 25, 2018
This file is used to format submit files for COSC 222 asignments
*/
#include "pch.h"
#include <iostream>
#include <fstream>
#include <string>
#include <stdbool.h>
#include <stddef.h>
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
std::string *processFile(std::ifstream *input, int maxCharCount, int tabSpaceSize, char delimiter, std::string *code, int lineCharCount);
int toInt(char *input);
int main(int argc, char **argv) {
std::cout << "Running 222 formatter" << std::endl << "by: Bradley Honeyman" << std::endl;
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
//make sure there is the min number of commands
if (argc < 3) {
std::cout << "Ensure there is a specified max line length and at least one file to modify!" << std::endl;
return 0;
}
for (int i = 3; i < argc; i++) {
//open file and make sure it opens
std::ifstream input;
input.open(argv[i]);
if (!input.is_open()) {
std::cout << "Could not open the input file: " << argv[i] << std::endl;
return EXIT_FAILURE;
}
//process code
std::string *code = new std::string();
processFile(&input, toInt(argv[1]), toInt(argv[2]), ' ', code, 0);
//check for error
if (code == NULL) {
return EXIT_FAILURE;
}
//output
input.close();
std::ofstream out(argv[i]);
if (!out.is_open()) {
std::cout << "could not write to output file" << std::endl;
return EXIT_FAILURE;
}
//print to file
out << code->c_str();
//close out delete code pointer
out.close();
delete code;
}
return 0;
}
/*
formats a file by placing \\\n the custom tab whereever the length of a line is bigger than the max
also a delimiter is used, so words aren't cut in half
*/
#define FORMAT_CHAR_COUNT 2
std::string *processFile(std::ifstream *input, int maxCharCount, int tabSpaceSize, char delimiter, std::string *code, int lineCharCount) {
//get char and check if is end of file
char current = input->get();
if (input->eof()) {
return code;
}
//incerment char count then check if are at furthest possible position
lineCharCount++;
//std::cout << lineCharCount << std::endl;
if (current == '\n') {
lineCharCount = 0;
//check if are at max char count, split code and put to new line
} else if (lineCharCount >= maxCharCount && current != '\\') {
//if not at delimiter push everything to the right of the nearest delimiter to the left to pre
int back = 0;
std::string pre("");
if (current != delimiter) {
for (int i = code->size() - 1; i >= 0; i--) {
back++;
if (code->at(i) == delimiter) {
pre.push_back(code->at(i));
break;
} else {
pre.push_back(code->at(i));
}
}
//remove what was added to pre from code
std::reverse(pre.begin(), pre.end());
code->assign(code->substr(0, code->size() - back));
}
//insert \ then new line then tab then set char count to tab size + pre size + 1 for char to be added
code->push_back('\\');
code->push_back('\n');
for (int i = 0; i < tabSpaceSize; i++) { code->push_back(' '); } //create tab
code->append(pre);
lineCharCount = tabSpaceSize + 1 + pre.size();
}
//add char to code and run again
code->push_back(current);
return processFile(input, maxCharCount, tabSpaceSize, delimiter, code, lineCharCount);
}
/*
converts string to an int
*/
int toInt(char *input) {
int i = 0;
int out = 0;
while (input[i] != '\0') {
out = (out * 10) + (input[i] - '0');
i++;
}
return out;
}
筆記:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.