繁体   English   中英

从c中的文件读取字符串

[英]reading strings from a file in c

我正在从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开头,则不会出现MYSTRING

我在想,是否还有其他事情可能会破坏我的程序?

而且,当我在printf("input=%s\\n",input)末尾执行printf("input=%s\\n",input)时,我得到了我的字符串,而且还有一行带有垃圾的内容?

有任何想法吗?

您需要看很多东西。 sizeof MYSTRING最主要sizeof MYSTRING包括nul-byte所需的存储大小。 它是strlen + 1 您必须非常小心地将sizeof string (在char数组上)和string length混合使用

接下来,如果您在整个代码中多次调用此函数,则最好在调用程序中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读取并读入'\\n'结果缓冲区,因此您需要通过用nul-byte覆盖来删除结尾的'\\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 */
        }

放在BUFSZ ,如果超过BUFSZ ,则添加一个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 */
        }
    }
}

isdigit()包括ctype.h

就像我说的,您可以采用许多不同的方法,这些只是基于您的条件和一种实现方式的想法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM