inc*_*ent 0 c linux string file
我正在尝试在文件中查找字符串。我通过修改的手册页中存在的代码段编写了以下内容getline。
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
FILE * fp;
char * line = NULL;
char *fixed_str = "testline4";
size_t len = 0;
ssize_t read;
fp = fopen("test.txt", "r");
if (fp == NULL)
exit(EXIT_FAILURE);
while ((read = getline(&line, &len, fp)) != -1) {
printf("Retrieved line of length %zu:\n", read);
printf("%s", line);
if (strcmp(fixed_str,line)==0)
printf("the match is found\n");
}
//printf("the len of string is %zu\n", strlen(fixed_str));
fclose(fp);
if (line)
free(line);
exit(EXIT_SUCCESS);
}
Run Code Online (Sandbox Code Playgroud)
问题是,尽管getline成功且正确地遍历了文件中的所有行,但strcmp的结果始终为false。由于换行符(AM I RIGHT?),fixed_str的长度为9,文件中相等字符串的长度为10。但是在9个字符的帮助下比较strncmp仍然会产生错误的结果。我还排除了上限和空格的可能性,所以我认为我做错了什么
test.txt如下
test line1
test line2
test line3
testline4
string1
string2
string3
first name
Run Code Online (Sandbox Code Playgroud)
我尝试了所有条目,但没有成功
注意:在我的实际程序中,我必须fixed_str从另一个文件中读取
从getline()手册页(我的重点是):
getline()从流中读取整行,并将包含文本的缓冲区地址存储到* lineptr中。缓冲区以null终止,并包含换行符(如果已找到)。
您fixed_str没有换行符。
因此,剥离任何换行符(例如):
char* nl = strrchr( line, '\n' ) ;
if(nl != NULL) *nl = `\0` ;
Run Code Online (Sandbox Code Playgroud)
或更有效,因为getline()返回行长(read在您的情况下):
if(line[read - 1] == '\n' ) line[read - 1] = `\0` ;
Run Code Online (Sandbox Code Playgroud)
添加一个'\n'to fixed_str可能看起来更简单,但这不是一个好主意,因为文件中的最后一行(或仅有一行)没有一行,但是可能是匹配项。
strncmp()如您的问题所述使用应该可以,但是没有看到尝试就很难发表评论,但是在任何情况下它都是有缺陷的解决方案,因为它可以满足以下所有条件:
testline4
testline4 and some more
testline4 12345.
Run Code Online (Sandbox Code Playgroud)
其中fixed_str从控制台或文件输入,而不是恒定的拍摄,将输入方法和数据源可能会引起问题,如可替换的线端约定的可能性。为了使其更强大,您可以执行以下操作:
// Strip any LF or CR+LF line end from fixed_str
char* line_end = strpbrk( fixed_str, "\r\n" ) ;
if( line_end != NULL ) *line_end = '\0' ;
// Strip any LF or CR+LF line end from line
line_end = strpbrk( line, "\r\n" ) ;
if( line_end != NULL ) *line_end = '\0' ;
Run Code Online (Sandbox Code Playgroud)
或@AndrewHenle指出的更简单(即更好)的解决方案:
// Strip any LF or CR+LF line end from fixed_str
fixed_str[strcspn(line, "\r\n")] = '\0';
// Strip any LF or CR+LF line end from line
line[strcspn(line, "\r\n")] = '\0';
Run Code Online (Sandbox Code Playgroud)
这样一来,无论输入的末尾是CR还是CR + LF,都可以比较任一输入,并且两个输入之间的行尾甚至可能有所不同。