C++ 如何读取内嵌中的指令,然后使用内嵌中的参数将函数形状写入输出文件
所以我只需要一些关于如何修复这个程序的指导,所以我需要阅读一个名为“infle.txt”的文件,文件中是描述应该绘制的形状的说明(一个大写字符,即R,T,D,S,E)然后,它给出形状应填充的字符,然后给出int中的列数和行数。txt文件如下所示:C++ 如何读取内嵌中的指令,然后使用内嵌中的参数将函数形状写入输出文件,c++,file-io,shapes,C++,File Io,Shapes,所以我只需要一些关于如何修复这个程序的指导,所以我需要阅读一个名为“infle.txt”的文件,文件中是描述应该绘制的形状的说明(一个大写字符,即R,T,D,S,E)然后,它给出形状应填充的字符,然后给出int中的列数和行数。txt文件如下所示: T & 4 S @ 6 T x 5 R * 5 7 D $ 7 D + 5 R = 4 3 E 现在,我甚至不确定我是否可以使用switch语句来完成这项工作,因为infle是作为字符串读取的。但是,我对如何从switch语句进行更改感到困惑
T & 4
S @ 6
T x 5
R * 5 7
D $ 7
D + 5
R = 4 3
E
现在,我甚至不确定我是否可以使用switch语句来完成这项工作,因为infle是作为字符串读取的。但是,我对如何从switch语句进行更改感到困惑。无论如何,在读取内嵌后,我必须输出绘制到输出文件的形状。希望这是有意义的,我是超级入门级,几乎不知道我在做什么。这是我的代码:
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
void draw_rect (char out_char, int rows, int columns); // Draws a rectangle shape
void draw_square (char out_char, int rows); //Draws a square shape
void draw_triangle (char out_char, int rows);// Draws a triangle shape
void draw_diamond (char out_char, int rows); // Draws a diamond shape
//void dimension_instructions(char value);
int main()
{
ofstream outfile;
ifstream infile;
int row, col;
bool exit = false;
char value;
char code;
infile.open("infile.txt");
outfile.open("outfile.txt");
if(!infile.good())
{
cout << "failed to open\n";
}else
{
string buffer;
while(!infile.eof())
{
getline(infile, buffer);
cout << buffer << endl;
}
while(!exit)
{
cout << "Enter your shape R for rectangle, T for triangle, D for diamond, S for square, and E to exit" << endl;
cin >> code;
switch(code)
{
case 'R':
dimension_instructions(code);
cin >> value >> row >> col;
draw_rect(value, row, col);
break;
case 'T':
dimension_instructions(code);
cin >> value >> row;
draw_triangle(value, row);
break;
case 'D':
dimension_instructions(code);
cin >> value >> row;
draw_diamond(value, row);
break;
case 'S':
dimension_instructions(code);
cin >> value >> row;
draw_square(value, row);
break;
case 'E':
cout << "Exiting";
exit = true;
break;
default:
cout << "Invalid input, try again" << endl;
}
}
infile.close();
}
outfile.close();
return 0;
}
/*void dimension_instructions(char value)
{
if (value == 'R')
{
cout << "Enter your character rows and columns values." << endl;
}else
{
cout << "Enter your character and row values" << endl;
}
}*/
void draw_diamond (char out_char, int rows)
{
int space = 1;
space = rows - 1;
for (int i = 1; i <= rows; i++)
{
for (int k = 1; k <= space; k++)
{
cout << " ";
}
space--;
for( int k = 1; k <= 2*i-1; k++)
{
cout << out_char;
}
cout << endl;
}
space = 1;
for (int i = 1; i <= rows; i++)
{
for(int k = 1; k <= space; k++)
{
cout << " ";
}
space++;
for(int k = 1; k <= 2*(rows-i)-1; k++)
{
cout << out_char;
}
cout << endl;
}
}
void draw_triangle (char out_char, int rows)
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j <= i; j++)
{
cout << out_char;
}
cout << endl;
}
}
void draw_square (char out_char, int rows)
{
for (int i = 0; i < rows; i++)
{
for (int i = 0; i < rows; i++)
{
cout << out_char;
}
cout << endl;
}
}
void draw_rect (char out_char, int rows, int columns)
{
for (int i = 0; i < rows; i++)
{
for (int i = 0; i < columns; i++)
{
cout << out_char;
}
cout << endl;
}
}
#包括
#包括
#包括
使用名称空间std;
void draw_rect(char out_char,int行,int列);//绘制一个矩形形状
虚线绘制方格(字符输出字符,整数行)//画一个正方形
无效绘制_三角形(char out _char,int行);//画一个三角形
void draw_diamond(char out_char,int行);//绘制菱形
//无效维度_指令(字符值);
int main()
{
出流孔的直径;
河流充填;
int row,col;
bool exit=false;
字符值;
字符码;
infle.open(“infle.txt”);
outfile.open(“outfile.txt”);
如果(!infle.good())
{
cout>行>>列;
绘制直线(值、行、列);
打破
案例“T”:
尺寸说明(代码);
cin>>值>>行;
绘制三角形(值,行);
打破
案例“D”:
尺寸说明(代码);
cin>>值>>行;
绘制菱形(值,行);
打破
案例S:
尺寸说明(代码);
cin>>值>>行;
绘制正方形(值,行);
打破
案例“E”:
cout好的,根据你的评论,我知道你被卡住的地方和原因。(如果你还没有做,你还需要在draw\u square
和draw\u rect
中修复循环变量)
您的主要问题是不理解如何处理每行不同数量的输入。当您遇到此问题时,您已经正确选择了getline
将每行读入缓冲区
,但接下来会发生什么?这就是stringstream
的关键所在
为什么?有两个原因:(1)它允许你用基本的iostream>>
逐字解析缓冲区的内容;(2)当需要时,它允许你循环直到流结束读取尽可能多(或尽可能少)的令牌,当你到达行尾时停止(在文件流本身上使用>
是不可能的,因为>
会占用空白,并且会愉快地跳过每个'\n'
)
这样一来,您的代码实际上只需要一点重构(一个修复混乱逻辑的花哨词)
开始时,不要硬编码文件名或在代码中使用幻数。使用main()
的参数将文件名传递给程序,并在需要时声明常量。还要避免使用char
,因为它不会占用前导空格。cin>>a_char;
阅读'
(空格)同样令人愉快因为它在读别的东西
也可以适当地定义变量的范围。您不需要声明所有变量,以便它们在整个main()
中可见。在适当的范围内声明/定义它们
例如:
...
#include <sstream>
...
int main (int argc, char **argv) { /* don't hardcode filenames */
ifstream infile; /* infile and buffer are the only variables */
string buffer; /* that need to be scoped at main() */
现在您正在阅读每一行,并且您已经从缓冲区创建了一个stringstream
来解析您的字符,除了注意值,code
如何声明为string
,而不是char
——它提供了一种简单的方法来跳过前导空格,只读取非空格字符acters。然后,您只需访问所需的字符,例如,value[0]
验证您对code
if (!(ss >> code)) { /* validate code read into string */
cerr << "error: ss >> code.\n";
break;
}
除了关闭infle
(这将自动发生,但手动显示您对关闭的考虑并不有害)
注意但是使用goto
而不是exit
的标志。虽然goto
没有太多压力,但它还有一个非常宝贵的用途,那就是能够干净地打破嵌套循环和作用域。不要使用它跳出函数(longjmp的longjmp
是技术上的限制),但它可以极大地简化中断嵌套循环和向下跳转几行的逻辑。(在相同的设置中,在错误条件下跳转通常在循环结束时执行的代码也很有用)
因此,请理解它的用途。您可以自由使用标志,但您可以在许多设置中找到goto
cleaner
有了它,您可以将其放在一起(暂时忽略outfile
),类似于:
#include <iostream>
#include <fstream>
#include <sstream>
#include <cstdlib>
using namespace std;
void draw_rect (char out_char, int rows, int columns); // Draws a rectangle shape
void draw_square (char out_char, int rows); //Draws a square shape
void draw_triangle (char out_char, int rows);// Draws a triangle shape
void draw_diamond (char out_char, int rows); // Draws a diamond shape
int main (int argc, char **argv) { /* don't hardcode filenames */
ifstream infile; /* infile and buffer are the only variables */
string buffer; /* that need to be scoped at main() */
if (argc < 2) { /* validate at least 1 argument is provided */
cerr << "error: insufficient input.\n"
"usage: " << argv[0] << " filename.\n";
return 1;
}
infile.open (argv[1]); /* open filename provided as 1st argument */
if(!infile.good()) { /* validate file is open for reading */
cerr << "failed to open infile\n";
return 1;
}
while (getline(infile, buffer)) { /* loop reading each line */
int row, col; /* remaining variables scoped inside */
string value, code; /* your read loop, use strings */
stringstream ss(buffer); /* create stringstream from buffer */
if (!(ss >> code)) { /* validate code read into string */
cerr << "error: ss >> code.\n";
break;
}
switch (code[0]) /* switch on 1st char of code */
{
case 'R':
if ((ss >> value >> row >> col)) /* validate read */
draw_rect (value[0], row, col); /* draw rect */
else /* or handle error */
cerr << "error: 'R' invalid format '" << buffer << "'\n'";
break;
case 'T':
if ((ss >> value >> row)) /* ditto for rest of shapes */
draw_triangle(value[0], row);
else
cerr << "error: 'T' invalid format '" << buffer << "'\n'";
break;
case 'D':
if ((ss >> value >> row))
draw_diamond(value[0], row);
else
cerr << "error: 'D' invalid format '" << buffer << "'\n'";
break;
case 'S':
if ((ss >> value >> row))
draw_square(value[0], row);
else
cerr << "error: 'S' invalid format '" << buffer << "'\n'";
break;
case 'E':
cout << "Exiting\n";
goto exitE; /* goto to break nested loops / scopes */
break;
default:
cout << "Invalid input, try again" << endl;
}
}
exitE:; /* the lowly goto provides a simple exit */
infile.close();
return 0;
}
void draw_diamond (char out_char, int rows)
{
int space = 1;
space = rows - 1;
for (int i = 1; i <= rows; i++)
{
for (int k = 1; k <= space; k++)
{
cout << " ";
}
space--;
for( int k = 1; k <= 2*i-1; k++)
{
cout << out_char;
}
cout << endl;
}
space = 1;
for (int i = 1; i <= rows; i++)
{
for(int k = 1; k <= space; k++)
{
cout << " ";
}
space++;
for(int k = 1; k <= 2*(rows-i)-1; k++)
{
cout << out_char;
}
cout << endl;
}
}
void draw_triangle (char out_char, int rows)
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j <= i; j++)
{
cout << out_char;
}
cout << endl;
}
}
void draw_square (char out_char, int rows)
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < rows; j++)
{
cout << out_char;
}
cout << endl;
}
}
void draw_rect (char out_char, int rows, int columns)
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < columns; j++)
{
cout << out_char;
}
cout << endl;
}
}
如果您还有其他问题,请仔细查看并告诉我。为什么您要在(!infle.eof())
的同时阅读,然后在您的开关()中使用cin>
?另请参阅:您将要查看我最初使用cin进行测试,以确保我的所有功能手动工作,我想我正在尝试“转换”从用户输入到文件输入,我还没有转换所有的代码。好的,谢谢你的大量撰写。我是否可以用一种更简单的方式完成这项工作?我不需要做任何验证,坦率地说,我没有足够的技能来理解你在文章中描述的一半内容。我从来没有
while (getline(infile, buffer)) { /* loop reading each line */
int row, col; /* remaining variables scoped inside */
string value, code; /* your read loop, use strings */
stringstream ss(buffer); /* create stringstream from buffer */
if (!(ss >> code)) { /* validate code read into string */
cerr << "error: ss >> code.\n";
break;
}
switch (code[0]) /* switch on 1st char of code */
{
case 'R':
if ((ss >> value >> row >> col)) /* validate read */
draw_rect (value[0], row, col); /* draw rect */
else /* or handle error */
cerr << "error: 'R' invalid format '" << buffer << "'\n'";
break;
case 'T':
if ((ss >> value >> row)) /* ditto for rest of shapes */
draw_triangle(value[0], row);
else
cerr << "error: 'T' invalid format '" << buffer << "'\n'";
break;
case 'D':
if ((ss >> value >> row))
draw_diamond(value[0], row);
else
cerr << "error: 'D' invalid format '" << buffer << "'\n'";
break;
case 'S':
if ((ss >> value >> row))
draw_square(value[0], row);
else
cerr << "error: 'S' invalid format '" << buffer << "'\n'";
break;
case 'E':
cout << "Exiting\n";
goto exitE; /* goto to break nested loops / scopes */
break;
default:
cout << "Invalid input, try again" << endl;
}
}
exitE:; /* the lowly goto provides a simple exit */
#include <iostream>
#include <fstream>
#include <sstream>
#include <cstdlib>
using namespace std;
void draw_rect (char out_char, int rows, int columns); // Draws a rectangle shape
void draw_square (char out_char, int rows); //Draws a square shape
void draw_triangle (char out_char, int rows);// Draws a triangle shape
void draw_diamond (char out_char, int rows); // Draws a diamond shape
int main (int argc, char **argv) { /* don't hardcode filenames */
ifstream infile; /* infile and buffer are the only variables */
string buffer; /* that need to be scoped at main() */
if (argc < 2) { /* validate at least 1 argument is provided */
cerr << "error: insufficient input.\n"
"usage: " << argv[0] << " filename.\n";
return 1;
}
infile.open (argv[1]); /* open filename provided as 1st argument */
if(!infile.good()) { /* validate file is open for reading */
cerr << "failed to open infile\n";
return 1;
}
while (getline(infile, buffer)) { /* loop reading each line */
int row, col; /* remaining variables scoped inside */
string value, code; /* your read loop, use strings */
stringstream ss(buffer); /* create stringstream from buffer */
if (!(ss >> code)) { /* validate code read into string */
cerr << "error: ss >> code.\n";
break;
}
switch (code[0]) /* switch on 1st char of code */
{
case 'R':
if ((ss >> value >> row >> col)) /* validate read */
draw_rect (value[0], row, col); /* draw rect */
else /* or handle error */
cerr << "error: 'R' invalid format '" << buffer << "'\n'";
break;
case 'T':
if ((ss >> value >> row)) /* ditto for rest of shapes */
draw_triangle(value[0], row);
else
cerr << "error: 'T' invalid format '" << buffer << "'\n'";
break;
case 'D':
if ((ss >> value >> row))
draw_diamond(value[0], row);
else
cerr << "error: 'D' invalid format '" << buffer << "'\n'";
break;
case 'S':
if ((ss >> value >> row))
draw_square(value[0], row);
else
cerr << "error: 'S' invalid format '" << buffer << "'\n'";
break;
case 'E':
cout << "Exiting\n";
goto exitE; /* goto to break nested loops / scopes */
break;
default:
cout << "Invalid input, try again" << endl;
}
}
exitE:; /* the lowly goto provides a simple exit */
infile.close();
return 0;
}
void draw_diamond (char out_char, int rows)
{
int space = 1;
space = rows - 1;
for (int i = 1; i <= rows; i++)
{
for (int k = 1; k <= space; k++)
{
cout << " ";
}
space--;
for( int k = 1; k <= 2*i-1; k++)
{
cout << out_char;
}
cout << endl;
}
space = 1;
for (int i = 1; i <= rows; i++)
{
for(int k = 1; k <= space; k++)
{
cout << " ";
}
space++;
for(int k = 1; k <= 2*(rows-i)-1; k++)
{
cout << out_char;
}
cout << endl;
}
}
void draw_triangle (char out_char, int rows)
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j <= i; j++)
{
cout << out_char;
}
cout << endl;
}
}
void draw_square (char out_char, int rows)
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < rows; j++)
{
cout << out_char;
}
cout << endl;
}
}
void draw_rect (char out_char, int rows, int columns)
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < columns; j++)
{
cout << out_char;
}
cout << endl;
}
}
$ ./bin/drawshapes dat/drawshapes.txt
&
&&
&&&
&&&&
@@@@@@
@@@@@@
@@@@@@
@@@@@@
@@@@@@
@@@@@@
x
xx
xxx
xxxx
xxxxx
*******
*******
*******
*******
*******
$
$$$
$$$$$
$$$$$$$
$$$$$$$$$
$$$$$$$$$$$
$$$$$$$$$$$$$
$$$$$$$$$$$
$$$$$$$$$
$$$$$$$
$$$$$
$$$
$
+
+++
+++++
+++++++
+++++++++
+++++++
+++++
+++
+
===
===
===
===
Exiting