C 如何将其分解为两个以上的函数?
如何将这两个函数划分为两个以上的函数 函数逐行读取文件 一条指令将出现在文件中的一行中(每条指令的末尾将有一个换行符) 字符)。在运行开始时,程序将逐行读取指令。那么它会的 解码所需的操作和参数,并调用相应的 参数 我试图将foor循环、数组、C 如何将其分解为两个以上的函数?,c,function,C,Function,如何将这两个函数划分为两个以上的函数 函数逐行读取文件 一条指令将出现在文件中的一行中(每条指令的末尾将有一个换行符) 字符)。在运行开始时,程序将逐行读取指令。那么它会的 解码所需的操作和参数,并调用相应的 参数 我试图将foor循环、数组、getc()放到另一个函数中,但它不起作用 void read_line(FILE *fp, char *orders, char *book_name, char *book_name_2, int *num) { int i = 0;
getc()
放到另一个函数中,但它不起作用
void read_line(FILE *fp, char *orders, char *book_name, char *book_name_2, int *num)
{
int i = 0;
char c ;
*num = 0;
c = getc(fp);
while ((c != '\n') && (!feof(fp))) {
for (i = 0; (c != '$') && (c != '\n') && (!feof(fp)); i++) {
orders[i] = c;
c = getc(fp);
}
orders[i] = '\0';
if (c != '\n' && (!feof(fp))) {
fseek(fp, 3, 1);
c = getc(fp);
}
else break;
for (i = 0; (c != '$') && (c != '\n'); i++) {
book_name[i] = c;
c = getc(fp);
}
book_name[i] = '\0';
if (c != '\n' && (!feof(fp))) {
fseek(fp, 3, 1);
c = getc(fp);
}
else break;
if (strcmp(orders, "Rename ") != 0) {
for (i = 0; c != '\n'; i++) {
*num = (*num) * 10 + (c - '0');
c = getc(fp);
}
}
else {
for (i = 0; c != '\n'; i++) {
book_name_2[i] = c;
c = getc(fp);
}
book_name_2[i] = ' ';
book_name_2[i + 1] = '\0';
}
return;
}
}
提取代码块的最简化的方法基本上就是将代码块复制到函数中,然后对在代码块外声明的变量使用指针。让我们以for循环为例:
for (i = 0; (c != '$') && (c != '\n'); i++) {
book_name[i] = c;
c = getc(fp);
}
book_name[i] = '\0';
因此,我们需要访问i
、c
、book\u name
和fp
。最简单的(但不是最好的)是:
然后将for循环替换为:
foo(&i, &c, book_name, fp);
这是一个简单的程序。但它给了你很多提示。实际上,这个方法本身并没有什么问题。但是您可以通过考虑在哪个范围内声明变量来消除其中的一些变量。例如,您可以在For头中声明变量,,除非您想保留最后一个值,否则您应该这样做。如果您这样做了,就可以删除一个参数并获得
void foo(char *c, char *book_name, FILE *fp)
{
for (int i = 0; (*c != '$') && (*c != '\n'); i++) {
book_name[i] = *c;
*c = getc(fp);
}
book_name[i] = '\0';
}
请注意,我必须向前看,直到下次使用ifI
,才能确定这是安全的。您的代码的编写方式不适合块提取
您还应该尝试将c
变量设置为局部变量。说到这里,它应该是int
,而不是char
。阅读getc
的文档了解原因
在这里使用for
循环本身并没有错,但它不是惯用的。For循环通常在知道循环开始前应执行多少次时使用。当您想循环直到某件事情发生时,while
更合适。但是这里更好的方法是边做边做。因为,在读取文件时,您希望尝试读取,然后检查是否成功。从技术上讲,您正在这样做,但使此代码难以提取的是,每个块都以读取下一个循环应该处理的字符结束
要纠正这一点,我们需要从头开始。首先将第一个实例删除到getc
。另外,从循环头中删除条件
while (1) {
i=0;
// Each block takes care of 100% of their input
while((c = getc(fp)) != '$' && c != '\n' && c != EOF) {
orders[i] = c;
i++;
}
orders[i] = '\0';
// Negated your condition to make a cleaner if and get rid of else
if (!(c != '\n' && (!feof(fp)))) break;
fseek(fp, 3, 1);
...
我在这里纠正的主要问题是,每个代码块都是从头开始的。它不在乎以前发生了什么。在代码中,您总是从检查前面块中的值开始。此更改使提取代码变得更容易。在大多数情况下,当人们询问如何提取代码时,他们真正应该问的问题是如何更改代码,使提取变得微不足道
同时,阅读什么是fseek(fp,3,1)代码>?不要使用幻数。两条注释:1)charc=0代码>-->int c=0代码>2)不要使用feof()
@wildplasser我如何在不使用feof()的情况下将代码更改为code你能帮助我吗?feof
是为了找出你不得不停止后停止的原因,而不是为了弄清楚你是否应该现在停止。请参阅Jas06-非常糟糕的表单,在有几个人试图在评论和回答中提供帮助之后。一记耳光。
void foo(char *c, char *book_name, FILE *fp)
{
for (int i = 0; (*c != '$') && (*c != '\n'); i++) {
book_name[i] = *c;
*c = getc(fp);
}
book_name[i] = '\0';
}
while (1) {
i=0;
// Each block takes care of 100% of their input
while((c = getc(fp)) != '$' && c != '\n' && c != EOF) {
orders[i] = c;
i++;
}
orders[i] = '\0';
// Negated your condition to make a cleaner if and get rid of else
if (!(c != '\n' && (!feof(fp)))) break;
fseek(fp, 3, 1);
...