从c中的文件中读取字符串

时间:2017-07-10 22:57:37

标签: c string

我正在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)时,我得到了我的字符串,但还有一个带垃圾的附加行?

有什么想法吗?

1 个答案:

答案 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

就像我说的那样,你可以采取许多不同的方法,这些只是基于你的条件和一种方法的想法。