【问题标题】:Create an array of pointer and convert each line to a string?创建一个指针数组并将每一行转换为字符串?
【发布时间】:2015-03-01 20:18:17
【问题描述】:

所以我得到了一个 .lst 文件,我需要读取它并将内容存储到缓冲区中,然后将信息存储在带有行号的 .txt 中。但是,我需要使用指向 cbuf 指针的指针并使用函数 get_lines 和 read_file。我有一个总线错误,我认为它在 get_lines 但我不确定。 代码:

#include <stdlib.h>
#include <stdio.h>

int readfile(FILE *fp, char **cbuf); //mallocs a char buffer and reads a file into it, returns count of chars
char **get_lines(char *cbuf, int bufsize); //mallocs an array of pointers to lines in cbuf, returns array's address

int main(int argc, char *argv[])           //reads a list-file into a buffer, generates a pointer array to lines/strings
{
  int i,bufsize;
  char *cbuf;
  char **lines;
  FILE *fp;

  if( (fp=fopen(argv[1],"r")) == NULL)
    {
      perror("ERROR: bad/no filename");
      exit(0);
    }
  bufsize= readfile(fp,&cbuf);       //create a buffer for the file, read the file into the buffer
   lines= get_lines(cbuf, bufsize) ;  //create an array of pointers to lines in the file, convert each line to a string
  i=0;
  while( lines[i] != NULL) {         //last entry in lines[] holds a NULL to mark end of data
printf("%i\t%s\n",i,lines[i]); //display line/strings pointed to by entries in lines

i++;
}
  return 0;
}

int readfile(FILE *fp,char**cbuf)
{
  int i;
  char c;

  fseek(fp, 0L, SEEK_END);
  int bufsize = ftell(fp);
  fseek(fp, 0L, SEEK_SET);

  *cbuf = (char *)malloc(sizeof(char) * bufsize);

  for (i = 0; i < bufsize; i++)
    {
      c = fgetc(fp);
      (*cbuf)[i] = c;
    }
  return bufsize;
}

char **get_lines(char *cbuf, int bufsize)
{
  char **lines;
  int i,j;

  lines[0] = &(cbuf[0]);

  j = 0;
  for (i = 0; i < bufsize; i++)
    {
      if (cbuf[i] == '\n')
        {
          cbuf[i] = '\0';
          lines[j++] = &cbuf[i] + j;
        }
      lines[bufsize] = NULL;
    }
  return lines;
}

【问题讨论】:

  • 您忘记为行指针数组分配内存。
  • char **lines; 然后lines[0] = &amp;(cbuf[0]); 之类的东西将不起作用。您通过取消引用不确定的指针来调用未定义的行为。以及关于即将发生的事情的说明。这:lines[bufsize] 将是一场灾难。 bufsize 是输入缓冲区大小,与您的 line 计数无关。此外,您应该考虑如果文件的最后一行 not 以换行符结尾会发生什么。考虑一下您计划在哪里种植上述线路的终结器。
  • 你要么需要解析数据两次——首先是找出多少行——然后分配指针数组,或者分配一个小数组,然后每次用完时分配一个小数组realloc()元素。
  • 即使您确实分配了lines 数组,也要仔细考虑lines[j++] = &amp;cbuf[i] + j;,我认为它不会像您认为的那样。

标签: c arrays pointers buffer


【解决方案1】:

你真的必须在输出之前将整个文件存储在内存中吗?这可以通过读取每个字符并写入输出的循环非常简单地完成。最终它将写入一个文本文件。

#include <stdlib.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
    int linenum = 1, c, pending = 1;
    FILE *fp;
    FILE *fo = stdout;

    if (argc < 2)                           // check argc
        {
        perror("ERROR: no argument");
        exit(0);
        }
    if ((fp=fopen(argv[1],"rt")) == NULL)   // added text mode
        {
        perror("ERROR: bad filename");
        exit(0);
        }
    while ((c = fgetc(fp)) != EOF) {
        if (pending) {                      // start a new line
            fprintf (fo,"%04d\t", linenum++);
            pending = 0;
        }
        putc(c, fo);
        if (c == '\n')                      // check end of line
            pending = 1;
    }
    fclose(fp);
    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-29
    • 2012-06-26
    • 1970-01-01
    • 2013-08-03
    • 2013-03-06
    相关资源
    最近更新 更多