我如何更改此代码以在没有strstr函数的情况下工作?

时间:2019-01-31 23:24:59

标签: c pointers

我正在尝试查找文本文件中具有特定内容的每一行,并在不使用strstr或getline的情况下对它们进行计数。如何更改我的代码使其不起作用?

#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char * argv[]){

FILE * fp;
char * s = argv[1];
int lines = 0, i;
fp = fopen("mytext.txt", "r");
if(fp == NULL){
    printf("error\n %d", fp);
    exit(1);
}
size_t lookfor;
char * lines = NULL;
size_t len = 0;
while ((lookfor = getline(&lines, &len, fp)) != -1) {
    if(strstr(lines, s) != NULL) {
        lines+= 1;
    }
}
fclose(fp);
printf("the number of lines that include the word 'great' are%d\n", lines);
return 0;
}

1 个答案:

答案 0 :(得分:2)

由于包含了<stdio.h>,因此隐式允许自己使用standard IO functions(即使禁止这样做,程序中的输入或输出也会如何发生?)。

请务必查看有关C reference函数的一些C standard library阅读每个功能的文档。稍后,还要检查C11标准n1570

在Linux上,getline<stdio.h>中声明了man getline,但不是标准的IO功能。它在POSIX中。 getline(3)手册页(通过fopen命令获得)中对此进行了说明。

因此,您可以并且可能应该使用fgetcfgetschar mylinebuf[128]; 之类的函数。在Linux上,另请参见其手册页,例如fgets(3),它提醒您它已在C99中标准化。

一种简单的方法是为您的行声明一些缓冲区,例如

char* res = fgets(mylinebuf, sizeof(mylinebuf), fp);

发送给文档,您仅接受小于128字节的行,并使用

fopen

不要忘记测试标准IO功能是否失败。特别是,fgets could失败了,getline也可能失败了。

更聪明的方法可能是仅使用fgetc(3)来模仿mygetline所做的事情(因此也许编写自己的strstr函数)。

如果您被禁止使用mystrstr,则可以编写自己的mystrstr函数来做同样的事情(如果允许使用strchr,否则可以自己编码) 。这是基本的指针内容。

strchr写在mystrchr上方,留给读者练习。并使用基本的指针操作编写gcc -Wall -Wextra -g

如果在Linux上使用GCC,请始终启用所有警告和调试信息,因此编译with printf("error\n %d", fp);

另请参阅How to debug small programs。因此,在Linux上学习use the gdb debuggervalgrind。避免使用undefined behavior -UB-(并且您的程序有多个,例如,在没有其他参数的情况下调用)。例如

gcc -Wall -Wextra -g

是错误的,并且UB(而且编译器会用strstr来警告您)。

您需要改进代码来避免UB,这不仅仅是为了避免mystrstr而更改代码。

顺便说一句,在2019年,UTF-8 is used everywhere(实际上)会增加程序的复杂性(如果您想认真一点的话(如果允许的话,您可能要使用libunistring,否则,请写您的{{1}}来了解UTF-8,并检查输入文件的内容(或程序参数)是否是有效的UTF-8;可能不是这样。)