用c语言从文件中读取字符串

用c语言从文件中读取字符串,c,string,C,String,我正在从C中的文件中读取字符串。字符串应该有一个特定的长度,并以thisisnumbr开头。如果这两个要求都得到满足,那么就会发生其他事情。此外,我希望防止文件中任何意外的内容可能导致崩溃 我的代码: #define MYSTRING "thisisnumb-" void read_mystring() { int c, i = 0, len =0 ; char input[sizeof( MYSTRING)+2] ; char check[] = MYSTRING ; FI

我正在从
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)
时,我得到了字符串,但还有一行垃圾


有什么想法吗?

你需要看很多东西。最重要的
sizeof MYSTRING
包括nul字节所需的存储大小。它是
strlen+1
。你必须非常小心地混合
sizeof string
(在字符数组上)和字符串长度

接下来,如果您在整个代码中多次调用此函数,则最好打开调用者中的文件,并将
文件*
参数传递给您的函数。(由您决定)我将执行以下操作:

/* 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字节来删除尾随的
'\n'
,例如

验证行读取后,只需根据需要检查长度,然后检查最后两个字符是否为数字,例如:

总而言之,如果超过
BUFSZ
,则添加一个
moretoread
标志以读取到一个长行的末尾,您将得到类似于以下内容的结果:

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


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

你最好使用像
fgets
这样的面向行的函数来读取每一行,然后使用
strncmp
来比较你的前缀和行的内容……使用足够的cient缓冲区大小,以容纳甚至长的行或继续读取和丢弃字符,直到达到
'\n'
为止。1)
字符输入[sizeof(MYSTRING)+2]-->
char输入[sizeof(MYSTRING)+2]=“”
2)
i>sizeof(input)
-->
i>=sizeof(input)-1。。谢谢工作起来很有魅力!谢谢,谢谢你的详细解释!第8行,if子句,应该有
==
对吗?当然(我会带着尖头帽转身面对拐角10分钟
:)
谢谢@Tom——修正了。
        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 */
        }
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 */
        }
    }
}