C 如何将其分解为两个以上的函数?

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;

如何将这两个函数划分为两个以上的函数

函数逐行读取文件

一条指令将出现在文件中的一行中(每条指令的末尾将有一个换行符) 字符)。在运行开始时,程序将逐行读取指令。那么它会的 解码所需的操作和参数,并调用相应的 参数

我试图将foor循环、数组、
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';
}
请注意,我必须向前看,直到下次使用if
I
,才能确定这是安全的。您的代码的编写方式不适合块提取

您还应该尝试将
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=02)不要使用
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);

    ...