读文件内容到char **,每个一级指针指向一行

来源:互联网 发布:fc2破解版安卓域名设置 编辑:程序博客网 时间:2024/06/07 12:35

如题,用三种方式实现,源码如下:

/* * ===================================================================================== * *       Filename:  linefor2dchar.cpp * *    Description:  读文件到char **,每个指针指向一行 * *        Version:  1.0 *        Created:  2012年11月28日 16时16分10秒 *       Revision:  none *       Compiler:  gcc * *         Author:  Xingwang Su (http://blog.csdn.net/njzhiyuan),  *   Organization:   * * ===================================================================================== */#ifdef __cplusplusextern "C" {#endif#ifndef _GNU_SOURCE#define _GNU_SOURCE#endif#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <string.h>#ifdef __cplusplus}#endif#include <iostream>#include <fstream>#include <string>#include <vector>#define FREE(ptr) {free(ptr); (ptr)=NULL;}using namespace std;int linefor2dchar1(const char *filename, char ***context, size_t *linenum) {FILE *fp = NULL;char *line = NULL;size_t linecount = 0;size_t linelen = 0;size_t arraysize = 0;const int step = 100;size_t index = 0;if (NULL == filename) {goto fail;}arraysize = step;if ((*context = (char **) calloc(arraysize, sizeof(char *))) == NULL) {goto fail;}if ((fp = fopen(filename, "r")) == NULL) {goto fail;}while (getline(&line, &linelen, fp) != EOF) {if (linecount >= arraysize) {if ((*context = (char **) realloc(*context, sizeof(char *) * (arraysize + step))) == NULL) {goto fail; }arraysize += step;}(*context)[linecount] = line;line = NULL;++linecount;}(*context)[linecount] = NULL;*linenum = linecount;fclose(fp);return 0;fail:if (fp)fclose(fp);if (line) {free(line);line = NULL;}if (*context) {for(index = 0; index < linecount; ++index) {FREE((*context)[index]);}FREE(*context);}return -1;}void test1(const char *filename) {char **context = NULL;size_t linenum = 0;size_t index = 0;if (linefor2dchar1(filename, &context, &linenum) != 0) {fputs("", stderr);return ;}for(index = 0; index < linenum; ++index) {fprintf(stdout, "%s", context[index]);}for(index = 0; index < linenum; ++index) {FREE(context[index]);}FREE(context);}int linefor2dchar2(const char *filename, char ***context, size_t *linenum) {FILE *fp = NULL;char *linebuf = NULL;char *line = NULL;size_t linecount = 0;size_t arraysize = 0;const int step = 100;struct stat stbuf;if (NULL == filename) {goto fail;}if (stat(filename, &stbuf) != 0) {goto fail;}if ((linebuf = (char *) calloc(stbuf.st_size + 1, sizeof(char))) == NULL) {goto fail;}if ((fp = fopen(filename, "r")) == NULL) {goto fail;}fread(linebuf, stbuf.st_size, 1, fp);if (ferror(fp)) {goto fail;}arraysize = step;if ((*context = (char **) calloc(arraysize, sizeof(char *))) == NULL) {goto fail;}line = linebuf;(*context)[linecount++] = line;while (*line) {if ('\n' == *line) {*line = '\0';++line;} else if ('\r' == *line) {*line = '\0';++line;if ('\n' == *line) {*line = '\0';++line;}} else {++line;continue;}if (linecount >= arraysize) {if ((*context = (char **) realloc(*context, sizeof(char *) * (arraysize + step))) == NULL) {goto fail; }arraysize += step;}(*context)[linecount] = line;++linecount;}(*context)[linecount] = NULL;*linenum = linecount;fclose(fp);return 0;fail:if (fp)fclose(fp);if (linebuf) {free(linebuf);linebuf = NULL;}if (*context) {FREE(*context);}return -1;}void test2(const char *filename) {char **context = NULL;size_t linenum = 0;size_t index = 0;if (linefor2dchar2(filename, &context, &linenum) != 0) {fputs("", stderr);return ;}for(index = 0; index < linenum; ++index) {fprintf(stdout, "%s\n", context[index]);}FREE(context[0]);FREE(context);}int linefor2dchar3(const char *filename, char ***context, size_t *linenum) {ifstream infile;string line;vector<string> lines;vector<string>::size_type linecount = 0;if (NULL == filename) {goto fail;}infile.open(filename);if (!infile) {goto fail;}//infile.setstate(ifstream::badbit|ifstream::failbit);while (getline(infile, line)) {lines.push_back(line);}/*if (infile.fail() || infile.bad()) {goto fail;}*/*context = new char *[lines.size() + 1];*linenum = lines.size();for(vector<string>::const_iterator iter = lines.begin(); iter != lines.end(); ++iter) {if ( ( (*context)[linecount] = strdup((*iter).c_str() ) ) == NULL ) {goto fail;}++linecount;}(*context)[lines.size()] = NULL;infile.close();return 0;fail:if (infile)infile.close();if (*context) {free((*context)[index]);(*context)[index] = NULL;}delete[] *context;*context = NULL;}return -1;}void test3(const char *filename) {char **context = NULL;size_t linenum = 0;size_t index = 0;if (linefor2dchar3(filename, &context, &linenum) != 0) {cerr << "error" << endl;return ;}for(index = 0; index < linenum; ++index) {cout <<  context[index] << endl;}for (index = 0; index < linenum; ++index) {FREE(context[index]);}delete[] context;context = NULL;}int main(int argc, char * argv[]) {int index = 0;if( argc < 3) {fputs("less argument\n", stderr);return 1;}switch(atoi(argv[1])) {case 1:for (index = 2; index < argc; ++index)test1(argv[index]);break;case 2:for (index = 2; index < argc; ++index)test2(argv[index]);break;case 3:for (index = 2; index < argc; ++index)test3(argv[index]);break;default:fputs ("Unknow option\n", stderr);break;}return 0;}





原创粉丝点击