1

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

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

读取和构建每个城镇并创建 town1, town2,.... 工作问题是当我输出它时,第一行工作 {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 行)包含属于同一行(第 5 行)的 judete 区域的城镇。

这是我的代码:

#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。

4

3 回答 3

4

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

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

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

于 2013-08-22T13:50:02.673 回答
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";
}

不,因为这是 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";
    }       
}
于 2013-08-22T14:45:55.210 回答
1

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

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

char ceva[100]="";
于 2013-08-22T14:57:33.543 回答