我正在C
中的文件中读取字符串。字符串应该具有特定长度并以thisisnumbr
开头。如果满足这两个要求,那么应该发生其他事情。此外,我想防止文件中的任何意外情况可能导致崩溃。
我的代码:
#define MYSTRING "thisisnumb-"
void read_mystring()
{
int c, i = 0, len =0 ;
char input[sizeof( MYSTRING)+2] ;
char check[] = MYSTRING ;
FILE *file ;
file = fopen("/pathto/myfile", "r") ;
if (file) {
while ((c = getc(file)) != EOF)
{
input[i] = c ;
i++ ;
if (i > sizeof(input))
{
len = 1 ;
break ;
}
}
fclose(file) ;
}
if(strncmp(input,check,sizeof(check)-1) == 0 && len == 0)
{
//do something
}
}
因此input
的大小为MYSTRING
加上2个字符(应该是2位数。
在while
循环中,我正在阅读myfile
并将其存储在input
中。随着
if (i > sizeof(input))
{
len = 1 ;
break ;
}
如果文件中的字符串看起来比预期的长,我确保字符串读取停止。
然后我将字符串的开头与strncmp
进行比较,并检查len==0
是否确保字符串以MYSTRING
开头并且长度正确。
如果是这样,就会发生其他事情。
这有效,这意味着如果没有文件,文件中的字符串太长,或者文件中的字符串不以MYSTRING
开头,我就不会收到分段错误。
我想知道,如果还有其他事情可能会破坏我的计划?
而且,当我在函数结束时执行printf("input=%s\n",input)
时,我得到了我的字符串,但还有一个带垃圾的附加行?
有什么想法吗?
答案 0 :(得分:4)
您需要注意很多事情。最重要的echo json_encode($data, JSON_PRETTY_PRINT);
包括 nul-byte 所需的存储大小。它是sizeof MYSTRING
。您必须非常小心地混合strlen + 1
(在char数组上)和字符串长度。
接下来,如果您在整个代码中多次调用此函数,最好sizeof string
调用方中的文件并将fopen
参数传递给您的函数。 (这取决于你)我会这样做:
FILE*
接下来,有很多方法可以处理您的功能。正如评论中所提到的,通过提供足够大的缓冲区来处理文件中的长字符串(甚至那时你需要验证完整的行读取),你可以更好地服务。阅读/* open file in caller to prevent repeatedly opening and closing file */
FILE *fp = fopen (fname, "r");
if (!fp) { /* validate file open for reading */
fprintf (stderr, "error: file open failed '%s'.\n", fname);
exit (EXIT_FAILURE);
}
fgets
被读取并包含在结果缓冲区中,因此您需要通过用 nul-byte 覆盖来删除尾随'\n'
,例如
'\n'
验证线路读取后,您只需根据您的要求检查长度,然后检查最后两个字符是位数,例如
char buf[BUFSZ] = "";
while (fgets (buf, BUFSZ, fp)) {
size_t len = strlen (buf);
if (len > 0 && buf[len - 1] == '\n')
buf[--len] = 0;
else {
/* handle more chars remain in line than buf can hold */
}
完全放弃,并添加一个 if (len != sizeof MYSTRING + 1) {
/* not right length - handle error */
}
if (strncmp (buf, MYSTRING, sizeof MYSTRING - 1) == 0 &&
isdigit (buf[sizeof MYSTRING - 1]) &&
isdigit (buf[sizeof MYSTRING]))
{
/* string matches criteria -- do something */
}
else {
/* doesn't meet conditon -- handle error */
}
标记,直到长行结束时,如果超过moretoread
,则会有类似于以下内容:
BUFSZ
void read_mystring (FILE *fp)
{
char buf[BUFSZ] = "";
int moretoread = 0;
while (fgets (buf, BUFSZ, fp)) {
size_t len = strlen (buf);
if (len > 0 && buf[len - 1] == '\n') { /* check for newline */
buf[--len] = 0; /* overwrite with nul-byte */
moretoread = 0; /* reset moretoread flag */
}
else {
/* handle more chars remain in line than buf can hold */
moretoread = 1;
}
if (moretoread) /* you are way over your wanted length */
continue; /* just read until newline encountered */
if (len != sizeof MYSTRING + 1) {
/* not right length - handle error */
}
/* check prefix followed by two digits */
if (strncmp (buf, MYSTRING, sizeof MYSTRING - 1) == 0 &&
isdigit (buf[sizeof MYSTRING - 1]) &&
isdigit (buf[sizeof MYSTRING]))
{
/* string matches criteria -- do something */
}
else {
/* doesn't meet conditon -- handle error */
}
}
}
包括ctype.h
。
就像我说的那样,你可以采取许多不同的方法,这些只是基于你的条件和一种方法的想法。