C / C ++读取和写入文件的长字符串

时间:2013-08-22 13:40:36

标签: c++ c file

我有一个我正在格式化的城市列表:

{town, ...}, 
{...},
...

阅读并建立每个城镇并创建town1,town2,.... 问题是当我输出它时,第1行工作{town,...},但第二行崩溃。 知道为什么吗?

我有[地区] [城镇](excel表)。

所以每个地区都会重复多少个城镇。 每个文件每行有1个地区/城镇。

judete包含重复1次的每个区域。

AB
SD
PC
....

orase包含城镇列表。

town1
town2
....

orase-index包含每个城镇的区域

AB
AB
AB
AB
SD
SD
SD
PC
PC
...

我想要一个像这样的输出{“town1”,“town2”,...},每行(第5行)包含属于同一行judete区域的城镇(第5行)。

这是我的代码:

#include<stdio.h>
#include<string.h>

char judet[100][100];
char orase[50][900000];
char oras[100], ceva[100];

void main ()
{

    int i=0, nr;
    FILE *judete, *index, *ORASE, *output;
    judete = fopen("judete.txt", "rt");
    index = fopen("orase-index.txt", "rt");
    ORASE = fopen("orase.txt", "rt");   
    output = fopen("output.txt", "wt");

    while( !feof(judete) )
    {
        fgets(judet[i], 100, judete);
        i++;
    }

    nr = i;
    char tmp[100];
    int where=0;

    for(i=0;i<nr;i++)
        strcpy(orase[i],"");

    while( !feof(index) )
    {
        fgets(tmp, 100, index);
        for(i=0;i<nr;i++)
        {
            if( strstr(judet[i], tmp) )
            {
                fgets(oras, 100, ORASE);
                strcat(ceva, "\"");
                oras[strlen(oras)-1]='\0';
                strcat(ceva, oras);
                strcat(ceva, "\", ");
                strcat(orase[i], ceva);
                break;
            }

        }
    }


    char out[900000];

    for(i=0;i<nr;i++)
    {
        strcpy(out, "");
        strcat(out, "{");
        strcat(out, orase[i]); //fails here
        fprintf(output, "%s},\n", out);
    }

}

运行代码得到的结果是:

  

orase-judete.exe中0x00D4F7A9(msvcr110d.dll)的未处理异常:0xC0000005:访问冲突写入位置0x00A90000。

3 个答案:

答案 0 :(得分:4)

你没有清除orase数组,因为你的循环

for(i-0;i<nr;i++)
    strcpy(orase[i],"");

错误(' - '而不是'=')执行0次。

答案 1 :(得分:3)

我认为无论你是在写C还是C ++,你都需要先决定。你用两者标记了这一点,但代码看起来像是纯粹的C.虽然C ++编译器会接受大多数C,但结果并不是大多数人认为理想的C ++。

由于您已将其标记为C ++,因此我假设您实际上想要(或可以使用)C ++代码。编写良好的C ++代码将与您当前的C代码完全不同,它可能比重新尝试逐行重写代码或类似的代码更容易重新开始。

然而,我所看到的直接问题是你没有真正指定你想要的输出。目前我假设您希望每行输出都是这样的:"{" <town> "," <town> "}"

如果是这种情况,我首先要注意输出似乎根本不依赖于您的judete文件。 oraseorase-index似乎完全足够了。为此,我们的代码看起来像这样:

#include <iostream>
#include <string>
#include <iterator>
#include <fstream>
#include <vector>

// a class that overloads `operator>>` to read a line at a time:
class line { 
    std::string data;
public:
    friend std::istream &operator>>(std::istream &is, line &l) { 
        return std::getline(is, l.data);
    }
    operator std::string() const { return data; }
};

int main() {
    // open the input files:
    std::ifstream town_input("orase.txt");
    std::ifstream region_input("orase-index.txt");

    // create istream_iterator's to read from the input files. Note
    // that these iterate over `line`s, (i.e., objects of the type
    // above, so they use its `operator>>` to read each data item).
    //
    std::istream_iterator<line> regions(region_input), 
                                towns(town_input), 
                                end;

    // read in the lists of towns and regions:
    std::vector<std::string> town_list {towns, end};
    std::vector<std::string> region_list {regions, end};

    // write out the file of town-name, region-name:
    std::ofstream result("output.txt");
    for (int i=0; i<town_list.size(); i++) 
        result << "{" << town_list[i] << "," << region_list[i] << "}\n";
}

Noe,由于这是C ++,您通常需要将源保存为something.cpp而不是something.c,以便编译器正确识别它。

编辑:根据你在评论中提出的新要求,你显然想要更接近这一点:

#include <iostream>
#include <string>
#include <iterator>
#include <fstream>
#include <vector>
#include <map>

// a class that overloads `operator>>` to read a line at a time:
class line { 
    std::string data;
public:
    friend std::istream &operator>>(std::istream &is, line &l) { 
        return std::getline(is, l.data);
    }
    operator std::string() const { return data; }
};

int main() {
    // open the input files:
    std::ifstream town_input("orase.txt");
    std::ifstream region_input("orase-index.txt");

    // create istream_iterator's to read from the input files. Note
    // that these iterate over `line`s, (i.e., objects of the type
    // above, so they use its `operator>>` to read each data item).
    //
    std::istream_iterator<line> regions(region_input), 
                                towns(town_input), 
                                end;

    // read in the lists of towns and regions:
    std::vector<std::string> town_list (towns, end);
    std::vector<std::string> region_list (regions, end);

    // consolidate towns per region:
    std::map<std::string, std::vector<std::string> > consolidated;
    for (int i = 0; i < town_list.size(); i++)
        consolidated[region_list[i]].push_back(town_list[i]);

    // write out towns by region
    std::ofstream output("output.txt");
    for (auto pos = consolidated.begin(); pos != consolidated.end(); ++pos) {
        std::cout << pos->first << ": ";
        std::copy(pos->second.begin(), pos->second.end(),
            std::ostream_iterator<std::string>(output, "\t"));
        std::cout << "\n";
    }       
}

答案 2 :(得分:1)

请注意ceva永远不会被初始化。

我建议使用静态初始化,而不是使用strcpy来初始化字符串:

char ceva[100]="";
相关问题