gpt4 book ai didi

c++ - std::istringstream.good() 比预期多返回 true 一次

转载 作者:太空宇宙 更新时间:2023-11-03 10:28:52 25 4
gpt4 key购买 nike

我正在制作一个玩具程序来从字符串创建类(例如,我将它输入“test1 test2”,它会生成 test1.cpp、test1.h、test2.cpp、test2.h)

这个函数中发生的 Action :

bool makeClassesFromString(std::string classNames){

bool returnValue = true;

if (classNames == ""){

returnValue = false;

}
else{

std::istringstream issClassNames (classNames);
std::string sClassName;

while(issClassNames.good()){

issClassNames >> sClassName;
std::string sourceName = sClassName;
sourceName += ".cpp";

std::string headerName = sClassName;
headerName += ".h";

std::ofstream source(sourceName.c_str()), std::ios::app);
std::ofstream header(headerName.c_str()), std::ios::app);

//source << "#include \"" << headerName << "\"";


source.close();
header.close();

}

}

return returnValue;

}

文件以追加模式打开,以确保不会意外覆盖任何已经存在的类。

我最近回到这个程序来包含一些额外的东西——特别是,旧版本只创建了两个空文件,我想修改它来创建具有必要定义和包含的文件,这样我就不必手动去并每次添加它们。这揭示了意想不到的行为——最后一个类将任何文本添加两次。

在上面的代码示例中,我已经注释掉了我开始处理它的行,但是当我不注释掉它时,我会得到这样的行为:

input:
classmaker.exe test1 test2

output:
test1.h
test2.h
test1.cpp //(Which contains: #include "test1.h")
test2.cpp //(Which contains: #include "test2.h"#include "test2.h"

我的猜测是我的 while(issClassNames.good()) 返回最后一个类名的额外时间(因此再次将字符串附加到源文件)但我不确定是什么行为插入这一点。

目前提出的解决方案:

  1. 在以 ofstream 模式打开之前,测试文件是否已存在并尝试以 ifstream 模式打开。 (问题:没有解决运行 while once 模式的问题)
  2. 移除追加模式。 (问题:覆盖已有类的风险,仍然没有解决 while-loop 问题)
  3. 在 while 循环中使用条件测试,不要在上次运行时打开文件,例如将当前类名与最后一个类名进行比较,如果相等则中止。问题:不知道如何检查这是否是最后一次运行,除了笨拙的“这是与上次相同的类名吗?”如果输入字符串是“test1 test1 test2”,测试也可能会过早中止

编辑

我已经意识到:istringstream.good() 返回 true 的次数并不比预期多,而是它的计算结果如下:

input: "test1 test2"

evaluation:
good = true; extract next to string //(succeeds, overwrites empty string with "test1")
good = true; extract next to string //(succeeds, overwrites "test1" with "test2")
good = true; extract next to string //(fails, Doesn't overwrite "test2")
good = false; break loop.

编辑 2 + 3

好吧,这很容易解决。谢谢大家。不幸的是,我只能将一个答案标记为已接受,所以我选择了第一个发布的答案,但我感谢您的帮助。

完整的最终程序:

#include <iostream>
#include <fstream>
#include <string>
#include <sstream>

void makeClassesFromStdInput();
void makeClassesFromParameter(int argc, const char** argv);
bool makeClassesFromString(std::string classNames);

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

switch (argc) {

case 0: //This shouldn’t happen

break;

case 1:

//This will keep making classes from the CLI until
//the user breaks the process.
makeClassesFromStdInput();
break;

default:

//This will make classes from the parameters passed
//to the program except the first parameter which is
//assumed to be the program name.

makeClassesFromParameter(argc, argv);
break;

}

return 0;

}

void makeClassesFromStdInput(){

std::cout << "Input class name and press enter.\nWhitespace delimits class names.\nA blank line ends the process.\n>";
bool running = true;
std::string classNames;

while(running){

std::getline(std::cin, classNames);
running = makeClassesFromString(classNames);

}

}

void makeClassesFromParameter(int argc, const char** argv){

std::string classNames = "";

for(int i = 1; i<argc; i++){

classNames += argv[i];
classNames += " ";

}

makeClassesFromString(classNames);

}

bool makeClassesFromString(std::string classNames){

bool returnValue = true;

if (classNames == ""){

returnValue = false;

}
else{

std::istringstream issClassNames (classNames);
std::string sClassName;

while(issClassNames >> sClassName){

std::string sourceName = sClassName;
sourceName += ".cpp";

std::string headerName = sClassName;
headerName += ".h";

std::ofstream source(sourceName.c_str(), std::ios::app);
std::ofstream header(headerName.c_str(), std::ios::app);

source << "#include \"" << headerName << "\"";

//Header is slightly more involved because we want all capital letters
for (std::string::size_type i=0; i<headerName.length(); ++i){

if(headerName[i] == '.'){

headerName[i] = '_';
}
else{

headerName[i] = toupper(headerName[i]);
}
}

header << "#ifndef __" << headerName << "\n"
<< "#define __" << headerName << "\n"
<< "\n"
<< "\n"
<< "#endif";

source.close();
header.close();

}

}

return returnValue;

}

最佳答案

流无法知道您将要阅读的内容。如果您的读取尝试成功,您总是需要在尝试读取后检查:

while(issClassNames >> sClassName) {
// do whatever processing of sClassName you want to do
}

关于c++ - std::istringstream.good() 比预期多返回 true 一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23864966/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com