我正在尝试查找文本文件中具有特定内容的每一行,并在不使用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;
}
答案 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
命令获得)中对此进行了说明。
因此,您可以并且可能应该使用fgetc
和fgets
和char 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
debugger和valgrind。避免使用undefined behavior -UB-(并且您的程序有多个,例如,在没有其他参数的情况下调用)。例如
gcc -Wall -Wextra -g
是错误的,并且UB(而且编译器会用strstr
来警告您)。
您需要改进代码来避免UB,这不仅仅是为了避免mystrstr
而更改代码。
顺便说一句,在2019年,UTF-8 is used everywhere(实际上)会增加程序的复杂性(如果您想认真一点的话(如果允许的话,您可能要使用libunistring,否则,请写您的{{1}}来了解UTF-8,并检查输入文件的内容(或程序参数)是否是有效的UTF-8;可能不是这样。)